Tokens
The JWT model — short-lived access tokens, audiences per product, the refresh flow, and JWKS.
Every Norcube API accepts Bearer JWTs. The dashboard and the CLI manage the whole lifecycle for you; this page is for anyone integrating directly.
The model
Two token kinds, both RS256-signed JWTs:
| Token | Lifetime | Where it lives |
|---|---|---|
| Access token | ~5 minutes | Sent as Authorization: Bearer <jwt> on every request. Claims include the user (sub), the organization_id, the aud list, and token_type: "access". |
| Refresh token | 7 days | The session. For the web app: an HTTP-only jds_refresh_token cookie. For the CLI: stored in the OS keyring. Used only to mint new access tokens. |
Access tokens are deliberately short — clients should treat
401 INVALID_TOKEN as "refresh once and retry", not as an error.
Audiences
Each product validates tokens against its own audience; a token minted for one product won't authenticate against another:
| Audience | Service |
|---|---|
auth | The auth service itself (user profile, organizations, IAM). |
langsync-api | LangSync |
snapdb-api | Backup |
domainradar | DomainRadar |
billing | Billing |
prompthub | PromptHub |
Convenience: tokens minted for a product audience also include auth,
so the same token can fetch your profile and org list alongside product
calls.
Minting an org-scoped access token
The auth service exposes an OAuth2-style endpoint. The refresh token
travels as the jds_refresh_token cookie (not a form field):
curl -X POST "https://auth.api.norcube.com/oauth/token" \
-H "Cookie: jds_refresh_token=<your-refresh-token>" \
-d grant_type=refresh_token \
-d audience=langsync-api \
-d organization_id=<org-uuid>The response carries a fresh access token (and possibly a rotated refresh token — always persist the returned one). Cache the access token until shortly before expiry, then refresh.
Two things the endpoint does not do:
- No
client_credentialsgrant. There is no machine-to-machine client flow; the refresh token always originates from a human sign-in. - No long-lived personal access tokens yet. For unattended API access the options today are a product API key (LangSync) or a service-account user whose refresh token your integration stores and refreshes — re-login at least weekly, since refresh tokens live 7 days.
Verifying tokens (JWKS)
The signing keys are public:
GET https://auth.api.norcube.com/.well-known/jwks.jsonIf you're building something that receives Norcube tokens, verify
RS256 signatures against this JWKS and check the aud and
token_type claims — exactly what every Norcube service does.
Behaviour and edge cases
- Wrong audience →
401. Mint a token with the audience of the API you're calling. - Refresh tokens can rotate. When
/oauth/tokenreturns a new refresh token, the old one is dead — store the replacement immediately (the CLI does this for you). - Sessions are independent. Web login and CLI login hold separate refresh tokens; signing out of one doesn't invalidate the other. There's no session list / remote revocation yet — sessions die by expiring (7 days without refresh).
- Lost refresh token = re-login. They can't be re-issued.