Authentication & KeysOAuth Client Credentials

OAuth Client Credentials

The short-lived-token alternative to API keys — RFC 6749 client-credentials grant minting 15-minute ed25519 JWTs, verifiable offline via JWKS.

When to use this instead of API keys

OAuth client credentials fit organizations whose security policy forbids long-lived bearer secrets in running systems. Instead of a tk_live_ key that works until revoked, your system holds a client id + secret and exchanges them for 15-minute access tokens as needed. Everything else — scopes, rate limits, quotas, billing — works identically to API keys.

OAuth clients are provisioned by our team: contact support with the scopes you need. You receive a client_id (oc_...) and a client_secret (ocs_...), shown once, hash-at-rest like API keys.

Minting a token

POST /v1/oauth/token with the client_credentials grant — the only supported grant type. Authenticate with HTTP Basic (preferred) or form-body credentials:

curl -sS -X POST https://api.transmute.403fin.io/v1/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials \
  -d 'scope=convert validate'
# {"access_token":"eyJ...","token_type":"Bearer","expires_in":900,"scope":"convert validate"}
  • expires_in is always 900 — the 15-minute TTL is fixed, not configurable.
  • The optional scope parameter narrows the client's stored scopes; it can never widen them. Requesting a scope the client doesn't hold yields invalid_scope.
  • Use the token exactly like a key: Authorization: Bearer eyJ....

Off-the-shelf OAuth2 client libraries work as-is: protocol errors follow RFC 6749 §5.2 ({"error":"invalid_client"} JSON bodies, not problem+json), and all client-auth failures are deliberately indistinguishable.

Offline verification (JWKS)

Tokens are ed25519-signed JWTs. If you proxy transmute behind your own gateway, you can verify tokens offline against our published keys:

GET https://api.transmute.403fin.io/.well-known/jwks.json

Operational notes

  • The token endpoint is rate-limited per client IP at 1 request/second (burst 5). A well-behaved client caches its token and mints ~4 per hour — don't request a fresh token per API call.
  • Revoking a client stops new tokens immediately; outstanding tokens live out their remaining ≤15 minutes. That bounded tail is the trade for offline-verifiable tokens.
  • Token minting is never metered or billed.