How it works
The API auth flow has five conceptual steps:- Find a credential on the request.
- Verify that credential with the system that owns it.
- Normalize the verified caller into a principal.
- Attach the principal to the request session.
- Check the principal’s permissions before data access or mutation.
- Which workspace is this request scoped to?
- Who or what appears as the actor in audit logs?
- Which permissions can this caller use?
Request lifecycle
Protected API routes authenticate in middleware before the handler runs. The middleware resolves the credential, stores the resulting principal on the session, and applies workspace-level API rate limiting with the principal’s workspace scope. Handlers do not authenticate requests. A handler reads the principal from the session and fails closed if the protected route was registered without the auth middleware. After it has a principal, the handler checks the permission required for the operation and uses the principal’s workspace ID for reads, writes, cache keys, and audit logs. The session does not store a separate workspace ID. Request metadata that needs the workspace, such as error logs or request metrics, reads it from the stored principal. If a request has no principal, the workspace value is empty.Credential sources
Credential sources differ in how they prove identity, how long they live, and who they represent. After verification, they all produce the same principal concept. Root keys represent machine-to-machine access. They are long-lived credentials owned by a workspace and are suitable for public API clients. Portal sessions represent an end user acting through the customer portal. They are browser-oriented credentials and grant the permissions attached to that session. JWTs represent short-lived bearer authentication from trusted Unkey-owned callers. The dashboard proxy uses this source to call the API without exposing a root key to browser code. The important design constraint is that adding a credential source does not change how handlers authorize or audit requests.Dashboard proxy
The dashboard proxy is an internal bridge between browser-authenticated dashboard sessions and the API’s bearer authentication model. Browser code calls the dashboard, not the API directly. The dashboard verifies the user’s dashboard session, maps the organization to a workspace, mints a short-lived JWT, and forwards the API request with that JWT as the bearer credential. The proxy exists so the dashboard can use the same API surface that external clients use while keeping browser credentials scoped to the dashboard. The browser never receives the API signing secret or a root key. The API still owns authorization because it verifies the JWT, builds the principal, applies the workspace rate limit, and checks the handler’s required permission. The dashboard signs with one active secret. The API verifies with an ordered list of secrets so deployments can rotate signing keys safely. Add the new secret to the API verification list before the dashboard starts signing with it, then remove the old secret after every token signed with the old secret has expired. The proxy rejects caller-supplied authorization headers. It builds the upstream request headers itself so browser cookies and dashboard session headers do not cross the service boundary.Principal model
A principal is not the raw credential. It is the normalized identity that the API trusts after verification. A principal contains:- A workspace scope for reads, writes, and limits.
- A subject for audit logs.
- A credential source type for debugging and policy decisions.
- A permission set for authorization.

