ROUTING & HANDLERS FEATURE
Public Payload
Anonymous access is never accidental: without #[PublicEndpoint], Semitexa treats the route as protected.
Feature Guide
A quick orientation block that answers the essential questions: what this feature does, how it works, why it matters, and the key concepts behind it.
What this does
Semitexa is closed by default: every payload requires authentication unless you explicitly opt it into anonymous access with #[PublicEndpoint].
How it works
The access policy resolver inspects payload attributes at boot. If #[PublicEndpoint] is present, the route is marked public; otherwise the authorizer treats guest access as AuthenticationRequired and the pipeline returns 401 before the handler runs.
Why it matters
This flips the usual risk profile. Teams do not have to remember to secure every endpoint one by one. The safe default is built in, and public exposure becomes a deliberate code review event.
Key concepts
- #[PublicEndpoint]
- Marks a payload as explicitly reachable without authentication.
- default private
- The absence of #[PublicEndpoint] means the endpoint is treated as protected for guests.
- 401 Unauthorized
- The framework response returned when a guest hits a protected endpoint.
- Authorizer
- Core service that decides whether the current subject may access the resolved payload.
Security Default
Private unless you say otherwise
The absence of #[PublicEndpoint] is what keeps routes closed to guests. Public access must be deliberate and visible in code.
// Protected by default
#[AsPayload(path: '/dashboard', methods: ['GET'])]
class DashboardPayload {}
// Explicitly public
#[PublicEndpoint]
#[AsPayload(path: '/catalog', methods: ['GET'])]
class CatalogPayload {}
| Route declaration | Guest request result |
|---|---|
| No auth attribute at all | 401 Unauthorized |
#[PublicEndpoint]
|
200 OK |
#[PublicEndpoint] + #[RequiresPermission]
|
Boot-time exception |
| Authenticated user on default-private route | 200 OK |
Verified against Semitexa Ultimate 2026.09.19.1020
Public Payload
Semitexa is closed by default. Every payload picks one of three access attributes — #[AsPublicPayload], #[AsProtectedPayload], or #[AsServicePayload] — and the framework refuses to discover a payload that declares none. Anonymous access is the explicit #[AsPublicPayload] opt-in, never an implicit fallback.
How it works
The access policy resolver inspects the payload's access attribute at boot. #[AsPublicPayload] marks the route as anonymous-allowed. #[AsProtectedPayload] requires a User-domain principal and returns 401 to guest requests before the handler runs. #[AsServicePayload] requires a Service-domain principal (a verified webhook signature, machine token, or partner credential) and similarly returns 401 on missing or wrong-domain credentials.
Why this matters
The three attributes are mutually exclusive and explicit. Public exposure becomes a deliberate code-review event because the keyword AsPublicPayload appears at the type. There is no "default protected" fallback that someone could remove; there is no shared base attribute that could accidentally drop a route into the wrong access class. A payload that declares none of the three never reaches the route registry, so a missing attribute is a build-time discovery failure rather than a silently exposed endpoint.
See also
- Protected Route —
#[RequiresPermission]and#[RequiresCapability]on protected payloads. - Post-Hardening Migration Guide — migrating from the legacy access model.
How it works
The access policy resolver inspects payload attributes at boot. If #[PublicEndpoint] is present, the route is marked public; otherwise the authorizer treats guest access as AuthenticationRequired and the pipeline returns 401 before the handler runs.
Why it matters
This flips the usual risk profile. Teams do not have to remember to secure every endpoint one by one. The safe default is built in, and public exposure becomes a deliberate code review event.
Key concepts
- #[PublicEndpoint]
- Marks a payload as explicitly reachable without authentication.
- default private
- The absence of #[PublicEndpoint] means the endpoint is treated as protected for guests.
- 401 Unauthorized
- The framework response returned when a guest hits a protected endpoint.
- Authorizer
- Core service that decides whether the current subject may access the resolved payload.