Authentication
Bearer tokens, token abilities, the device authorization flow, and how the API answers a suspended account.
Bearer tokens
curl -H "Authorization: Bearer $SHORTSPAN_TOKEN" \
-H "Accept: application/json" \
https://shortspan.dev/api/v1/auth/meTokens are issued by the device flow, by shortspan token create, or in the console under API tokens. They are shown once; only a hash is stored.
GET /api/v1/auth/me returns the authenticated user and the current token's abilities. It is the cheapest way to check that a token is live and correctly scoped.
Abilities
Each token carries abilities that narrow what it may do. They never widen it - the role check runs regardless, so a token with secrets:reveal held by a viewer reveals nothing.
curl -X POST https://shortspan.dev/api/v1/tokens \
-H "Authorization: Bearer $SHORTSPAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-deploy",
"abilities": ["secrets:read", "ssh:use"]
}'Omitting abilities grants the standard interactive set: secrets:read, ssh:use, db:use, aws:inject, k8s:use, runbooks:execute, access:request. Note that secrets:reveal is not among them.
The full list is in API tokens and devices.
The device authorization flow
For clients that cannot receive a redirect - a CLI, a TV, a headless tool. Two endpoints, both unauthenticated.
1. Request a code
curl -X POST https://shortspan.dev/api/v1/auth/device-code{
"data": {
"device_code": "…",
"user_code": "WDJB-MJHT",
"verification_uri": "https://shortspan.dev/device",
"expires_in": 600,
"interval": 5
}
}2. Show the user code, and poll
Display user_code and verification_uri. The person opens the URL in a browser where they are signed in, checks that the code matches, and approves. Meanwhile, poll:
curl -X POST https://shortspan.dev/api/v1/auth/device-token \
-H "Content-Type: application/json" \
-d '{"device_code": "…"}'| Response | Meaning |
|---|---|
| Not approved yet. Keep polling at |
| The ten-minute window closed. Start over. |
| The user refused. Do not retry. |
| Approved. Store it and stop polling. |
Codes live for ten minutes. Both the code and the poll are rate limited, per code and per IP, so a single honest login has its own budget while enumeration across many codes is bounded.
Authentication failures
| Status and code | Cause | Correct client behaviour |
|---|---|---|
| Missing, malformed, expired, or revoked token. | Re-authenticate. |
| The account or workspace is suspended. | Do not re-authenticate. Surface the message; a new token will fail identically. |
| Role or ability insufficient. | Do not retry. The credential is fine; the permission is not. |
| This client version has been withdrawn. | Tell the user to upgrade. |
| The account has no workspace yet. | Send them to the URL in the body. |
| The request was not TLS. | Fix the client. Do not retry over plaintext. |
Revoking
# Revoke the token making the request
curl -X DELETE https://shortspan.dev/api/v1/auth/token \
-H "Authorization: Bearer $SHORTSPAN_TOKEN"
# Revoke another one you own
curl -X DELETE https://shortspan.dev/api/v1/tokens/{tokenId} \
-H "Authorization: Bearer $SHORTSPAN_TOKEN"Self-revocation remains available to suspended accounts. Losing access must never mean losing the ability to hand a credential back.
Something here wrong or missing? Tell us.