Skip to content

Authentication

Runne Pass has two independent authentication surfaces:

SurfaceCredentialTransportUsed by
Customer dashboardJWT in an HttpOnly cookieCookie runne_sessionWeb cabinet, browser
Programmatic APIAPI key rn_live_…Authorization: Bearer or x-api-keyServers, scripts, SDKs

They are not interchangeable: cookie sessions authorize dashboard routes, API keys authorize the external chat/balance surface.

Login and registration

  • POST /v1/auth/register{email, password, name}, creates the customer, then auto-logs in and sets the cookie.
  • POST /v1/auth/login{email, password}, sets the cookie and returns {expires_at}.
  • POST /v1/auth/logout — revokes the session server-side and clears the cookie.
  • GET /v1/auth/me — returns the current customer profile.
AttributeValue
Namerunne_session
HttpOnlyyes
SameSiteLax
Secureonly in production (NODE_ENV=production)
Max-Age24h (matches the JWT lifetime)
Path/

The JWT carries customerId, email, isAdmin, and a unique jti.

Server-side revocation

Logout stores the session jti in a Redis denylist keyed bl:sess:{jti} with a TTL equal to the token's remaining lifetime. Every authenticated request re-checks the denylist, so a logged-out session stops working immediately, even though the JWT itself is still cryptographically valid.

API keys (programmatic clients)

Format

rn_live_<keyId>_<secret>
  • keyId — 12 characters, base64url, derived from 9 random bytes.
  • secret — 32 random bytes, base64url.
  • rn_live_ prefix marks the key as a live (non-test) key.

Presenting a key

Two equivalent ways:

bash
# Authorization header (preferred)
curl -H 'Authorization: Bearer rn_live_…'

# x-api-key header
curl -H 'x-api-key: rn_live_…'

Verification

The server parses the key, looks up the row by keyId, and verifies the secret with HMAC-SHA256 against the stored hash. Only the hash is stored — the raw secret is never persisted.

Dual-secret rotation

Key verification supports two server secrets:

  • API_KEY_SERVER_SECRET — the current secret.
  • API_KEY_SERVER_SECRET_PREV — the previous secret, for graceful rotation.

During a rotation window, keys hashed under the previous secret still verify, so you can rotate the server secret without invalidating live keys. Comparison is constant-time.

Scopes

API keys carry a list of scopes. See API Keys for the full scope matrix.

The raw key is shown once

On creation the server returns raw_key, then discards it. There is no recovery path — see API Keys.