Skip to main content

Token, Session, and Transaction Lifetimes

O2ID mints and stores several kinds of short-lived state during authentication and token issuance. Each has a lifetime — how long it's valid before it expires and can no longer be used:

StoreBuilt-in default
Access tokens1 hour
Refresh tokens30 days
Authorization codes10 minutes
Sessions12 hours
Login transactions10 minutes
Consent transactions10 minutes

These are an auth/policy concern, not a storage-driver one — they apply identically regardless of which storage driver is configured.

note

Reading or updating tenant settings requires a role with the tenant:settings:read/tenant:settings:update scopes; per-application overrides use the same applications:update scope as any other application field — see Using o2idctl and Managing Roles.

Overriding a lifetime

Every lifetime above can be overridden at two levels:

  • Per tenant — a default for every application in that tenant.
  • Per application — takes precedence over the tenant's own setting, for one specific application.

Resolution order is application override → tenant override → built-in default: the first one that's actually set wins.

Setting a tenant default

o2idctl tenant-settings get
o2idctl tenant-settings update --access-token-lifetime 30m --session-lifetime 8h

This changes the default for every application in the current tenant that doesn't set its own override.

Setting a per-application override

The same lifetime flags are accepted by applications create and applications update:

o2idctl applications create --name "My App" \
--callback-url https://myapp.example.com/callback \
--access-token-lifetime 5m --refresh-token-lifetime 720h

o2idctl applications update <id> --session-lifetime 2h

An application's own override always wins over the tenant default, for that application only — every other application in the tenant is unaffected.

Clearing an override

Pass 0 or inherit as the value to remove an override and fall back to the next level up (the tenant's own setting, then the built-in default):

o2idctl applications update <id> --access-token-lifetime inherit

A real 0-second lifetime is meaningless, so 0 is safe to use as the "clear this override" signal rather than a genuine value.

Available flags

FlagAffects
--access-token-lifetimeAccess tokens
--refresh-token-lifetimeRefresh tokens
--authorization-code-lifetimeAuthorization codes
--session-lifetimeSessions
--login-transaction-lifetimeLogin transactions
--consent-transaction-lifetimeConsent transactions

Each accepts a Go-style duration string (30m, 2h, 720h), or 0/inherit to clear.

Which application a session or login transaction "belongs to"

Access tokens, refresh tokens, authorization codes, and consent transactions are always issued for a specific, already-authenticated application, so their override is unambiguous.

Sessions and login transactions are a little different: a login transaction is created by /oauth2/authorize as soon as client_id is seen in the request, before the user has even authenticated, and a session created at login time is picked up from whichever login transaction (if any) the user arrived through. In both cases, if a client_id was present, its application's override is used; otherwise (e.g. a user landing directly on /login with no in-flight authorization request) only the tenant override and built-in default apply.

API reference

Tenant settings can also be read and updated directly, e.g. from a script:

GET /tenant/settings
PATCH /tenant/settings

PATCH accepts a partial lifetimes object; omitted fields are left unchanged, and an explicit 0 clears that field's override. See the API Reference for the full request/response shape, and Managing Applications for the equivalent per-application fields on /applications.