Space Agent uses a file-backed authentication model. User credentials are stored as sealed SCRAM verifier envelopes inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/agent0ai/space-agent/llms.txt
Use this file to discover all available pages before exploring further.
L2/<username>/meta/password.json. Active sessions are tracked in L2/<username>/meta/logins.json as signed verifier records. The space_session cookie issued by a successful login acts as the bearer token for every subsequent authenticated request.
Single-user mode — When
SINGLE_USER_APP=true, every request automatically resolves to the implicit user principal. No cookie is checked and no login flow is required. The /api/login and /api/password_change endpoints return 403 in this mode.Login Flow
Normal password login uses a two-step SCRAM challenge-proof exchange. The browser callslogin_challenge first to obtain a server nonce and the account’s userCrypto state, then calls login with the computed client proof to complete authentication and receive the session cookie.
Call /api/login_challenge
Send the username to start a SCRAM challenge. The response includes a server nonce and the current
userCrypto state for the account.Compute the client proof
Use the server nonce, the user’s password, and the SCRAM algorithm to compute a
clientProof and a challengeToken to prove knowledge of the password without sending it.POST /api/login_challenge
Initiates a SCRAM login challenge for the given username. Returns the server nonce, SCRAM parameters, and the account’suserCrypto bootstrap state. This endpoint is public (no session required).
In clustered mode, challenges are stored in the primary-only login_challenge state area so workers cannot issue conflicting nonces.
Request
The username to challenge.
Client-generated nonce used to build the SCRAM auth message. The browser generates this; it must be unique per challenge.
Response
Opaque server-side challenge token to supply to
/api/login.SCRAM server nonce to incorporate into the client proof.
SCRAM iteration count for the password KDF.
Base64-encoded SCRAM salt for the password KDF.
Password scheme identifier for the sealed verifier.
Account crypto state object.
POST /api/login
Completes the SCRAM login flow using the challenge token and client proof from the previouslogin_challenge call. On success, sets the space_session cookie and returns session and crypto metadata. This endpoint is public (no session required).
If the account had a missing userCrypto state, the server persists the browser-generated wrapped record before issuing the cookie. If provisioning cannot complete, login is refused rather than issuing a cookie that would require immediate logout.
Request
The opaque token returned by
/api/login_challenge.SCRAM client proof derived from the user’s password and the server nonce.
Browser-generated wrapped key record to persist for accounts with
userCryptoState: "missing".Response
SetsSet-Cookie: space_session=<token>; HttpOnly; SameSite=Strict; Path=/; Max-Age=2592000.
Always
true on success.The authenticated username.
Backend session ID. Used by the browser to bind its session-scoped
userCrypto cache.SCRAM server signature for the browser to verify.
The wrapped user master key record needed to unlock the current browser session.
GET /api/login_check
Checks whether the current request’s session cookie is still valid. Returns the authentication state and, if authenticated, the username. This endpoint is public — it stays available even whenLOGIN_ALLOWED=false.
If the session cookie is present but references a cleared or expired session, the response includes a Set-Cookie header that clears the stale cookie.
Response
Whether the current session is valid.
The authenticated username, or an empty string if not authenticated.
GET /api/user_self_info
Returns the authenticated user’s identity snapshot and browser crypto bootstrap metadata. This is the canonical frontend call for determining writable roots, group membership, and current key state. Requires a valid session.Response
Authenticated username.
Display name from
user.yaml, falling back to username.Ordered list of group IDs the user belongs to.
Group IDs where the user has admin/manager rights.
Current backend session ID.
ID of the current wrapped user crypto key.
Crypto state for the current account:
"ready", "missing", or "invalidated".POST /api/password_change
Changes the current user’s password. Validates the suppliedcurrentPassword against the sealed verifier before writing the new one. On success:
- Rewrites
meta/password.jsonwith the new sealed verifier. - Rewraps
meta/user_crypto.jsonwith the new password when the account has ready browser crypto (requiresuserCryptoRecord). - Clears all entries in
meta/logins.json, invalidating every active session. - Clears the current browser cookie via
Set-Cookie.
SINGLE_USER_APP=true). Failed attempts are artificially delayed by at least 1 second to slow enumeration.
Request
The user’s current password, as a plain string.
The desired new password, as a plain string.
Browser-produced replacement wrapped key record. Required when the account’s
userCryptoState is "ready" to preserve the encrypted user data key through the password rotation.Response
Clears thespace_session cookie via Set-Cookie.
Always
true on success.Always
true — all sessions are cleared.The username whose password was changed.
POST /api/guest_create
Creates a new guest account with a randomly generatedguest_<id> username. Available when ALLOW_GUEST_USERS=true is set in runtime config. This endpoint is public — it works even when LOGIN_ALLOWED=false, because guest accounts are used for hosted-share flows that bypass the normal login form. After receiving this response, the caller completes authentication by running the normal /api/login_challenge + /api/login flow with the returned username and password.
Response
The newly created guest username (e.g.
guest_a7f3c2).The randomly generated plaintext password for the guest account. Use this with
/api/login_challenge to complete background authentication.POST /api/user_crypto_bootstrap
Authenticated recovery endpoint for the current user’s browser encryption state. Returns the currentuserCrypto state and, when the state is missing, can return a provisioning share and accept a browser-generated wrapped record — allowing the first authenticated app load to self-heal without a second login.
When called without a request body (or with a body that omits record), the server returns the current state. If state is "missing", the response also includes a provisioningShare the browser should use to create the wrapped record. On the second call, supply record and provisioningShare to persist the new wrapped key.
Request (optional — for provisioning)
Browser-generated wrapped key record to persist. Required on the second call when
state is "missing".The provisioning share returned by the first call. Required alongside
record to complete provisioning.Response
ID of the current wrapped user crypto key.
Client-facing wrapped key record.
Backend server share (present and non-empty when
state is "ready").Current crypto state:
"ready", "missing", or "invalidated".One-time provisioning share (only present when
state is "missing" and no record was supplied in the request).GET /api/user_crypto_session_key
Returns the session-scoped localStorage wrapping key for the current browser session. The key is derived by HMACing the live backendsessionId with the server-held session secret. The browser uses this key to encrypt or decrypt the single localStorage blob that caches the unlocked user master key.
The server never stores this derived key or any copy of the user master key. Calling this endpoint is the only way for the browser to recover the wrapping key after a page reload without requiring a fresh login.
Response
Derived wrapping key (base64-encoded).
POST /api/password_generate
Generates a backend-sealed password verifier envelope for a given plaintext password. This is an authenticated utility endpoint used by admin tooling and the_core/user management page to pre-seal new or reset passwords before writing them to meta/password.json. Requires a valid session.
Request
The plaintext password to seal into a SCRAM verifier envelope.
Response
Returns the backend-sealedpassword.json payload object. The exact shape is owned by the auth service; it includes the SCRAM verifier, salt, iteration count, and scheme identifier in a server-sealed envelope.
Logout
GET /logout is a browser-facing endpoint (not under /api/). It clears the space_session cookie with a Set-Cookie: space_session=; Max-Age=0 header and redirects to /login. No JSON body is required.