Tokens, refresh and concurrency
Encrypted per-user storage and safe rotation across workers.
Lifetime and rotation
Access token: fifteen minutes. Refresh token: thirty days. Each refresh replaces access and refresh tokens; save the new pair before continuing. Reusing an already rotated refresh token revokes its token family.
TokenStore
Implement get and set on a record bound to the local user, app and verified Pura identity. Encrypt tokens at rest using a key held in your secret store. Only the backend managing that session should access the record; a deleted connection returns null/None.
import type {TokenStore, StoredTokens} from '@pura-ai/sdk';
// DB reads/writes must use the lock's transaction context.
const store: TokenStore = {
get: async (): Promise<StoredTokens | null> => loadEncryptedGrant(),
set: async tokens => saveEncryptedGrant(tokens),
withRefreshLock: operation => withGrantDatabaseLock(operation),
};Multiple processes and workers
An SDK instance coordinates its own concurrent refreshes. For multiple instances implement withRefreshLock(operation) in TypeScript or with_refresh_lock() in Python using a shared lock for the same grant. Reading, refreshing and saving must happen within the same transaction context.
Under the lock the SDK rereads tokens: if another worker has already rotated them it uses the new pair. Release the lock even if the function fails. A global lock across users creates bottlenecks and does not replace correct session binding.
Revocation and inconsistent identity
invalid_grant or a changed pura_user_id during refresh ends the connection. The SDK does not save tokens for another identity. Request fresh authorization and remove invalid tokens; do not refresh in a loop.