Auth & tokens.
PAMbase has two kinds of credentials: connection tokens that apps use to call the API on a user's behalf, and session cookies that authenticate people in the hub and dev portal. This page is the focused reference on both, their lifetimes, and how to recover when one expires.
Token types & TTLs
| Credential | TTL | Who holds it | Purpose |
|---|---|---|---|
connection_token | ~365 days | Your app (server-side) | Bearer credential for all app API calls |
authorization code | 10 minutes | Transient (callback) | Single-use; exchanged once for a connection token |
| hub / dev session | 7 days | The user (cookie) | Logged-in session in the hub & dev portal UIs |
| 2FA challenge | 5 minutes | The user (transient) | Window to complete a two-factor step |
How apps authenticate
Every API call sends the connection token as a bearer credential. The SDK does this for you when you construct the client; with raw HTTP, set the header yourself.
import { PAMbaseApp } from "@pambase/sdk";const pambase = new PAMbaseApp({baseUrl: process.env.PAMBASE_API_URL!,connectionToken: user.pambaseToken, // from your encrypted secret store});
curl http://localhost:4000/v1/identity/brief \-H "Authorization: Bearer <connection_token>"
How the hub & dev portal authenticate
Humans signing in to the hub (where users manage connections) and the dev portal (where you manage apps and webhooks) get a session cookie valid ~7 days. This is unrelated to your app's connection token — it authenticates a person in a browser, not an app calling the API. Sensitive actions may require a 2FA challenge, valid for 5 minutes.
The 401 → re-connect recovery
When a connection token is expired or revoked, the API returns 401 unauthorized (SDK: UnauthorizedError). The recovery is always the same: discard the token and re-run the connect flow.
import { UnauthorizedError } from "@pambase/sdk";try {return await pambase.getContext({ intent: "app.daily" });} catch (err) {if (err instanceof UnauthorizedError) {await secrets.delete(user.id); // drop the dead tokenreturn redirect("/connect"); // re-run the OAuth connect flow}throw err;}
{ error: { code: "unauthorized", message } } with HTTP 401. Scope problems are forbidden / scope_denied (403) — those mean re-consent, not re-connect-from-scratch. See Errors.Related
- Connect an app — the full OAuth-style flow.
- Security — storing and protecting the token.
- Troubleshooting — diagnosing 401s and 403s.
- Errors and Limits.