Skip to content

Sessions & Tokens ​

How Flowsta issues, scopes, and ends sessions - what your app holds, for how long, and what ends it.

The Three-Token Model ​

Flowsta uses three types of tokens with different lifetimes:

TokenLifetimePurpose
Access token24 hoursAuthorizes API requests from OAuth apps
SSO session cookie (flowsta_session)7 daysKeeps the user signed in across Flowsta's own sites and the consent screen
Refresh token30 daysSilently obtains new access tokens

How they work together:

  • When a user signs in with their Vault, Flowsta sets the SSO session cookie - a 7-day JWT scoped to .flowsta.com. While it's valid, Flowsta sites and "Sign in with Flowsta" consent screens recognize the user.
  • When an OAuth app completes the flow, it receives an access token (24 hours) and a refresh token (30 days).
  • When the access token expires, the app exchanges the refresh token for a new access token. The refresh token itself is not rotated - it keeps its original 30-day expiration from the time of issue.
  • After the refresh token expires, the app sends the user through the sign-in flow again.

All three are stateless JWTs signed by Flowsta: the server keeps no session list, so a token is valid until it expires or, for refresh tokens, until it is revoked through POST /oauth/revoke.

How sign-in works ​

Signing in is a cryptographic challenge the user's Vault answers:

  1. Flowsta Vault requests a one-time challenge (POST /auth/vault/challenge)
  2. The Vault signs it with the identity key - derived from the user's 24-word recovery phrase, never sent anywhere - and, from 1.6.0, this device's own key beside it
  3. The signed challenge is exchanged for a session (POST /auth/vault/token), which returns a JWT and sets the flowsta_session cookie

The user approves the sign-in in their Vault, or a site they chose to remember is approved without a prompt. See Zero-Knowledge Architecture for the full picture.

What a session is bound to ​

  • A web session belongs to the identity that signed in. The JWT carries that identity's user id, agent public key and DID. Switching to another identity in the Vault does not end the session and does not move it: the browser stays signed in as the identity that answered the challenge until the user signs out or the token expires.
  • Sign-out is per site. POST /auth/logout (with the session's bearer token) clears the flowsta_session cookie for that browser. It does not touch other browsers or devices, and it does not revoke OAuth tokens your app holds - end those with POST /oauth/revoke.
  • Devices are independent. A user can be signed in on several devices at once; each holds its own JWT with its own expiry. There is no server-side list of sessions and no way to end them all at once.

For Developers ​

If you're building an app that uses Flowsta authentication:

  1. Handle expired sessions gracefully

    • Detect 401 responses
    • Show a "Session expired" message
    • Redirect to sign-in with a return URL
  2. Implement token refresh

    • Check token expiration before requests
    • Refresh proactively (before expiration)
    • Handle refresh failures gracefully - after 30 days the refresh token itself expires and the user must sign in again
  3. Store tokens securely

    • Use HTTP-only cookies for server-rendered apps (best)
    • The @flowsta/auth SDK uses localStorage for SPA convenience (acceptable for PKCE flows without client secrets)
    • Sensitive PKCE data is stored in sessionStorage and cleared after use
  4. Key your records to the identity, not the browser. Use sub (or the DID) from /oauth/userinfo. Because a session stays with the identity that signed in, a user who switches identities in their Vault and then signs in to your app again arrives as a different sub.

See the SDK Documentation for implementation details.

Technical Details ​

JWT Structure ​

A session JWT for a device-hosted identity:

json
{
  "id": "user_abc123",
  "userId": "user_abc123",
  "email": null,
  "agentPubKey": "uhCAk...",
  "did": "did:flowsta:uhCAk...",
  "hostingModel": "device-hosted",
  "iat": 1698765432,
  "exp": 1699370232,
  "iss": "flowsta-auth",
  "aud": "flowsta-sites"
}

Token Claims ​

ClaimDescription
id / userIdUnique user identifier
emailnull for device-hosted identities - the server holds only an email hash
agentPubKeyHolochain identity (public key)
didW3C Decentralized Identifier, did:flowsta:<agent key>
hostingModeldevice-hosted for Vault identities; custodial for legacy web accounts
iatIssued at (timestamp)
expExpires at (timestamp, +7 days)
issIssuer (flowsta-auth)
audAudience (flowsta-sites)

The session holds no password, no private data, and no browsing history. Whoever holds a session token can do what that session is authorized to do until it expires; they cannot reach the recovery phrase, the device keys, or the sealed private records, none of which leave the user's device.

http
Set-Cookie: flowsta_session=eyJhbGc...;
  HttpOnly;
  Secure;
  SameSite=Lax;
  Max-Age=604800;
  Domain=.flowsta.com

See the API Reference for complete technical documentation.

Need Help? ​

Documentation licensed under CC BY-SA 4.0.