API tokens: calling /api statelessly

Tiger's /api speaks two auth modes, auto-detected, and you never choose between them — the request does:

The request carries… Mode For
a session cookie stateful your first-party UI (the browser is a logged-in client)
an Authorization: Bearer token stateless a mobile app, a public API client, a server-to-server call

A token wins if both are present, and — critically — the token path never touches the session: no session row, no Set-Cookie, nothing to store. Same ACL, same services, same response envelope as a cookie request; only the front door differs.

Mint a token

A personal access token is just another credential factor on the user (user_credential, type personal_access_token) — hashed at rest, revocable, scoped to that user. Mint one from a normal (logged-in) session via Tiger_Service_Token:

POST /api   module=tiger service=token method=create
→ { "result": 1, "data": { "token": "tgr_1a2b3c…", "prefix": "1a2b3c…" } }

The plaintext is shown once — copy it now; only its hash is stored. method=all lists your tokens (prefix + timestamps, never the secret); method=revoke (with a credential_id) revokes one.

Use it

Send it as a Bearer token; drop the cookie entirely:

curl https://your-app/api \
  -H "Authorization: Bearer tgr_1a2b3c…" \
  -d "module=billing&service=invoice&method=create&amount=4200"

The gateway resolves the token to your identity + role and runs the same authorization it would for a session — a token grants exactly what your role grants, nothing more.

What changes in token mode

  • No session. The identity lives only for the request; nothing is written to storage.
  • CSRF is skipped. CSRF is a cookie-mode defense — a token request carries no cookie, so it's immune by construction and the form CSRF check is bypassed automatically.
  • An invalid token stays guest. A bad/expired token doesn't fall back to a session; it's simply unauthenticated, and deny-by-default takes it from there.

See also