La documentación para desarrolladores está disponible en inglés.
Tokens and lifetimes
Formats and lifetimes of codes, access, refresh and ID tokens, refresh rotation and why access can end early.
Every provider token except the ID token is opaque: 32 random bytes in base64url behind a type prefix. Calab stores only their SHA-256 hashes, so a token can never be recovered or shown again.
At a glance
| What | Format | Lifetime | Notes |
|---|---|---|---|
client_id | calab_client_ + 43 characters | Until the client is deleted | A public identifier, not a secret |
| Client secret | calab_os_ + 43 characters | No expiry; after a rotation the old one stays valid for 10 minutes | Shown once |
| Sign-in request | — | 10 minutes | The consent screen must finish within it |
| Authorization code | calab_oc_ + 43 characters | 60 seconds, single use | Bound to the client, redirect_uri and PKCE |
| Access token | calab_oa_ + 43 characters | up to 5 minutes (expires_in) | For /userinfo only |
| Refresh token | calab_or_ + 43 characters | 8 hours at most, 30 minutes idle | Rotated on every exchange |
| ID token | JWT, RS256 | Same as the access token | Verified with jwks_uri |
Access token
An access token opens /userinfo and nothing else. It does not work with the Calab REST API, the gateway or voice; conversely, Calab app tokens and bot tokens are refused by /userinfo. There is no introspection: to check a token, call /userinfo — 401 invalid_token means it is no longer valid.
Refresh tokens and rotation
A refresh token is issued only when the client has “Allow continued access” turned on and the person kept that box ticked on the consent screen.
- Every exchange (
grant_type=refresh_token) returns a new refresh token, a new access token and a new ID token (withoutnonce). The old refresh token becomes used immediately. - Presenting an already used refresh token again from the same client is treated as a leak: Calab revokes the whole chain (the grant) and the person must sign in again. There is no grace window — if a response is lost on the network, a new sign-in is required.
- Each exchange extends the idle deadline to 30 minutes, but never past the absolute 8-hour limit from sign-in.
- An exchange can narrow scopes (the
scopeparameter); the narrowing applies to the whole chain. Scopes can never be widened that way (invalid_scope).
ID token
A JWT with alg: RS256 and a kid header. Claims: iss, sub, aud (= your client_id), iat, exp, auth_time, nonce (code exchange only), plus name with the profile scope and email + email_verified: true with the email scope and a verified address. An unverified email never appears in the ID token or in /userinfo.
Signing keys are configured by the installation's operator; new keys are published in jwks_uri ahead of use and old ones stay there during the transition. Cache the JWKS (the server sends Cache-Control: max-age=60) and reload it once when you meet an unknown kid.
Subject (sub)
- A random identifier (32 bytes, base64url) created for the “workspace + member” pair.
- Stable: it does not change when the name or email changes or the client is recreated.
- The same for every client of one workspace and different across workspaces (their issuers differ too).
- It never reveals the internal account UUID.
Use the (iss, sub) pair as the account key in your application.
When access ends early
Calab re-checks everything on every code exchange, refresh and /userinfo call. Access (the whole grant chain) ends when:
- the person revokes it in “OAuth apps” or signs out of the Calab session they signed in from;
- the member is removed or banned from the workspace, or the directory (AD) closes their access;
- an admin changes the client's redirect URIs, origins, scopes or refresh setting, rotates its secret or deletes it;
- the workspace's SSO policy changes or the corporate sign-in proof expires;
- the Business / Enterprise plan ends or the workspace is suspended;
- the client presents a used code or refresh token again.
At /token this shows up as 400 invalid_grant, at /userinfo as 401 invalid_token. The right reaction is the same: start a new sign-in.