Skip to main content
Not yet released. The packages on this page are not published to npm yet, so the install commands below will not resolve. The documented interface is stable and the code exists; only publication is outstanding. To use KeyStone from a frontend today, call the REST API or the TypeScript SDK, which is published. Contact us if you need early access.

Session Tokens

KeyStone Elements uses session tokens for browser-safe API access. These are short-lived, scoped JWTs issued by the KeyStone API, separate from the M2M credentials your backend uses.

Why Not Use M2M Credentials Directly?

M2M credentials (client_id + client_secret) have full API access for your environment. Exposing them in browser code would let anyone with DevTools access your entire settlement data and create/modify settlements on your behalf. Session tokens solve this by being:
  • Short-lived - 1 hour default (configurable 1 min to 24 hours)
  • Scoped - Limited to specific permissions (e.g., only settlements:read)
  • Revocable - Can be invalidated immediately via API
  • Auditable - Carry metadata about which end-user is acting

Creating Session Tokens

Your backend creates session tokens by calling POST /v1/sessions with M2M authentication:

Available Scopes

Any other value is rejected with 422 at mint time.

What a session token may write

A session token is delivered to a browser, so it does not carry the same authority the same scope carries in your backend M2M credential. Submitting a instruction is the only write it can perform. These return 403 with code SESSION_WRITE_DENIED even when the token holds settlements:write: Creating a settlement fixes the terms of a trade one-sidedly, and a compliance decision rules on a settlement that sanctions screening flagged. Neither belongs to a credential sitting in DevTools. Instruction submission stays open because it is contained: the most it can produce is a settlement at the start of its lifecycle, where compliance screening still runs in full, and the compliance ruling stays behind your backend credential.

Scoping to Specific Settlements

You can restrict a session token to specific settlement IDs. This is useful when a trader should only see their own settlement:
The restriction is enforced at the API’s authorization boundary for every settlement route:
  • Requests addressing a settlement outside the list (get, events, related, compliance decisions, deposit calldata) return 403 with code SESSION_SETTLEMENT_SCOPE_DENIED.
  • Listing settlements returns only the settlements in the list, filtered server-side.
  • A restricted token cannot create settlements or use the instructions endpoints: new settlements and instructions cannot belong to a list fixed at mint time, so those requests return 403. For widgets that submit instructions, mint a token with settlements:write and no settlementIds property at all.
  • settlementIds: [] is rejected with 422. An empty permitted set means the token should reach nothing, so it is never treated as “unrestricted”.
  • The related endpoint authorizes every settlement it returns, not only the one addressed. A token whose list names one leg of a repo but not the other gets 403 with code SESSION_SETTLEMENT_SCOPE_DENIED from /related, and the response names nothing about the missing leg. A closing that does not exist yet is returned as null, so a token minted for the opening before maturity keeps reading {opening, closing: null} until the closing is created. To read the pair, mint the token with both legs listed.
Scopes outside the settlement surface (such as templates:read) are unaffected by the restriction.

Token Refresh

Session tokens expire. The KeystoneProvider supports automatic refresh via the onTokenExpired callback:
The token manager refreshes 60 seconds before expiry to avoid interruptions. Concurrent refresh requests are deduplicated.

Revoking Tokens

Revoke a session token immediately (e.g., on user logout):
Revoked tokens are rejected on the next API call, even if they haven’t expired yet. Revocation is scoped to the environment that minted the token, exactly like creation: call it with the same environment’s credentials. A token minted in another environment returns 404 with code SESSION_NOT_FOUND, so a sandbox credential can never log out your production widget users.

Minting rate

Session tokens are minted on their own per-environment window, lower than your environment’s request limit, and POST /v1/sessions answers 429 RATE_LIMIT_CREDENTIAL_ISSUANCE with Retry-After past it. Mint one token per user session and reuse it for its lifetime rather than one per request.

Security Model

  • M2M credentials stay on your backend. Never sent to the browser.
  • Session tokens are the only auth mechanism in the browser.
  • Each session token is tied to a platform and environment.
  • The KeyStone API validates the token on every request and checks revocation status.