Status: Accepted Date: 2026-02-06 Deciders: Reflections Maintainers
Context
The API serves both browser sessions (user identity) and internal service calls. Authorization must use server-derived reflection membership and role checks, not client-provided claims.Decision
Adopt dual authentication modes in API runtime:AUTH_MODE=jwtfor Clerk session token verification.AUTH_MODE=bearerfor shared service token authentication.
- Resolve caller role from
reflection_membershipsserver-side. - Enforce minimum required role via
requireReflectionRole/requireResourceRole.
Alternatives considered
Alternative 1: JWT-only for every caller (including services)
Pros:- Single authentication mode.
- Operational friction for non-user services.
- Coupling internal workers/agents to user auth provider semantics.
Alternative 2: Bearer-only for all clients
Pros:- Simple token handling.
- No per-user identity guarantees.
- Weak auditability and least-privilege enforcement for user-facing endpoints.
Alternative 3: Client-supplied role claims trusted at API boundary
Pros:- Lower DB lookup overhead.
- Security risk from forged role claims.
- Violates server-derived authorization requirement.
Consequences
Benefits:- Flexible auth strategy for mixed caller types.
- Stronger authorization integrity through server-side role lookup.
- Environment validation catches misconfiguration early.
- More configuration branches and environment constraints.
- Bearer mode has wider trust boundary and must be tightly scoped operationally.
Implementation notes
- Auth mode constraints and production guardrails are defined in the shared environment configuration.
- Token verification and auth context setup are centralized in the API auth middleware.
- Reflection role checks are centralized in the API authorization module.

