Skip to main content
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=jwt for Clerk session token verification.
  • AUTH_MODE=bearer for shared service token authentication.
Apply reflection-scoped RBAC after authentication:
  • Resolve caller role from reflection_memberships server-side.
  • Enforce minimum required role via requireReflectionRole / requireResourceRole.

Alternatives considered

Alternative 1: JWT-only for every caller (including services)

Pros:
  • Single authentication mode.
Cons:
  • 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.
Cons:
  • 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.
Cons:
  • 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.
Costs:
  • 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.