Skip to content

Capability tokens

The platform issues five distinct token types. Each has a different audience, lifetime, and revocation path. Confusing them is a security bug; this page enumerates them.

1. mx_session — HMAC JWT, 7 days

The browser session token.

PropertyValue
AlgorithmHMAC-SHA256
Issuermatrix-host:<authorityRoot>
SubjectprincipalId
Lifetime7 days
StorageHttpOnly cookie
Revocationby jti into HostAuthStateStore.revokedSessions[]
SourceHostSessionService.createSession (host-auth.ts:215-217)

Used for: HTTP requests with a session cookie.

NOT used for: NATS bus traffic (browsers use a Bus token instead).

2. Bus token — short-lived JWT, 5 minutes

A short-lived token a browser uses to authenticate to NATS over the WebSocket gateway.

PropertyValue
AlgorithmHMAC-SHA256 (same secret as mx_session)
SubjectprincipalId
LifetimeBUS_TOKEN_DURATION_MS = 5 * 60 * 1000 — 5 minutes
Storagememory only in the browser
Refreshevery ~4 minutes from /api/nats-jwt
Revocationnot separately revoked (lifetime is the bound)
SourceHostSessionService.createBusToken (host-auth.ts:219-221)

Used for: browser-to-NATS WebSocket auth. Per CLAUDE.md Rule 7, browsers connect via same-origin /nats-ws.

The Bus token's short lifetime is the security property — even if leaked, exposure window is ≤5 minutes.

3. Heartbeat token — opaque random, rotates per refresh

A Device's bearer token for the platform's heartbeat endpoint.

PropertyValue
Algorithmrandom bytes; HMAC at rest
Lifetimerotates per credential refresh; explicit rotation any time
Storageplaintext on the Device only
Revocationimplicit on link.status = 'revoked'
SourceHostLinkStore.rotateHeartbeatToken

Used for: /_auth/host-link/heartbeat and /_auth/host-link/credentials/refresh.

4. NATS user JWT — per-Device

A NATS user JWT signed by the principal's NATS account, scoped to that Device.

PropertyValue
AlgorithmEd25519 NKey signed
Issuerthe principal NATS account
Subjectthe Device's NATS user public key
LifetimeDEVICE_NATS_CREDENTIAL_TTL_SECONDS = 86_400 — 24 hours
Storageplaintext on the Device
Refreshauth.hostLink.credentials.refresh
Revocationaccount JWT revocation list update
SourcecreateDeviceScopedNatsCredentials (system-auth/src/index.ts:1487-1497)

Used for: NATS bus traffic from the paired Device. Authenticates the Device's NATS connection via NKey challenge-response (the JWT alone is not a bearer token).

The 24-hour TTL plus daily refresh is the principal rotation cadence. A Device that doesn't refresh for 24 hours loses its bus connection.

5. NATS account JWT — per-principal, server-side

The principal's NATS account JWT. Signed by the platform's NATS operator key.

PropertyValue
AlgorithmEd25519 NKey signed
Subjectaccount public key
Lifetimelong-lived
Storageserver-side only (in HostCredentialStore)
Revocationrotate the account; manage user revocations within
SourceensurePrincipalNatsAccount (system-auth/src/index.ts:1466-1485)

Used for: signing per-Device user JWTs. The principal account seed never leaves the server. Per HIVECAST-DEVICE-ENROLLMENT-SPEC.md:

The principal account seed remains server-side for NATS account provisioning.

Operators who suspect compromise of a principal account can rotate the account JWT, which invalidates every Device's user JWT signed under it.

Constant-time compare

Heartbeat-token verification (auth.hostLink.verifyHeartbeat) uses constant-time HMAC compare to avoid timing oracle attacks. Session JWT verification likewise.

What about CSRF tokens

The platform does not issue separate CSRF tokens. Mitigation today:

  • SameSite=Lax on mx_session cookie.
  • Bus tokens are memory-only and not in the cookie jar.
  • Most write paths require a non-cookie credential (the Bus token is sent as a NATS auth payload, not as a cookie).

A target hardening: explicit Origin header validation on POST/PUT/DELETE HTTP routes.

Token cheat-sheet

LayerTokenLifetimeWhere it livesRevocation
Browser → HTTPmx_session7dHttpOnly cookierevokedSessions[]
Browser → NATSBus token5mmemorylifetime
Device → HTTPheartbeat tokenrotateslocal filelink.status
Device → NATSuser JWT24hlocal fileaccount JWT revocation
Server-sideaccount JWTlongplatform DBrotate

See also

Source: projects/matrix-3/packages/system-auth/src/host-auth.ts:196-380 for the session service. projects/matrix-3/packages/system-auth/src/index.ts:1466-1497 for NATS account/user issuance. projects/matrix-3/packages/nats-auth/ for the NATS NKey/JWT primitives.