Authentication
One credential, one header, one workspace.
The header
Authorization: Bearer shr_pat_...
That is the only credential the API accepts from a script. There is no OAuth flow to complete, no client to register, and no session to keep alive.
The shr_pat_ prefix earns its eight characters twice. It lets the server recognise what it is
holding without trying to parse a JWT first, and it gives secret scanners a pattern to match,
which is the difference between a leaked token that gets revoked when you push and one that does
not.
One token, one workspace
A token names its workspace when you mint it. Requests carry no x-workspace-id header, and a
client that sends one anyway does not get to choose: the token decides.
If you belong to three workspaces you hold three tokens. That is more objects to manage, and it is also the honest answer to what should happen when you leave one of them.
Shown once
The token is 32 random bytes behind the prefix. We store a SHA-256 hash of it, so after the screen that shows it we genuinely cannot tell you what it was.
Copy it when it appears. If you lose it, revoke that token and mint another. Nothing is lost except the name you gave it.
Expiry and revocation
Expiry is optional and there is no default. A credential that dies quietly inside a CI job at 3am is worse than one somebody has to remember to revoke, so a token you do not give a date lives until you take it back.
Revocation is immediate. The token row is updated and the next request fails, with no window where an already-issued credential keeps working.
Each token records when it was last presented, written at most once an hour. It is not a request log, and it is enough to answer the only question anyone asks of a token list months later, which is which of these can I delete.
What a 401 means
Three causes, one status: the credential is unknown, revoked, or expired. The response does not distinguish them, because telling an unauthenticated caller which of the three applies is telling them whether a token they hold used to be real.
A 403 is a different failure and worth reading carefully: either the token lacks the scope, or
its owner lacks the permission. The two are checked separately and either can refuse.
Errors covers both.
What a token can never do
Its authority is the smaller of two things: what you may do, and what you scoped it to. Ticking
workspace:admin on a token does not make you an admin, and a token minted by a guest reaches
exactly what that guest reaches. See Permissions.