For the complete documentation index, see llms.txt. This page is also available as Markdown.

Authentication

RobotMoney authenticates humans, tenant-owned agents, tenant API keys, service principals, and MCP agents. The same bearer header is used at resource routes. Only the credential class and allowed scopes differ.

Caller
Mode
Credential

Human owner

Self-serve email and password, or a linked wallet

Bearer owner JWT

Tenant agent

Owner-created agent API key exchanged at /token

Five-minute bearer JWT

Tenant API key

Tenant API key in the sandbox integration environment, read-only

Bearer brain_sk_... key

Service principal

Operator or tenant service credential

Bearer service token

MCP agent

SIWX over Base plus on-chain scope hash

Bearer JWT from the SIWX or MCP auth exchange

Every credential is presented the same way: Authorization: Bearer <token>. There is one bearer mechanism, not several. The brain_sk_test_... / brain_sk_live_... value is a tenant API key when API-key authentication is enabled for that environment. See Server API key below.

Self-serve signup is gated by BRAIN_SELF_SERVE_SIGNUP. A new tenant starts in the sandbox flow with an active owner member, a default review-first policy, and headless decision limits that let an owner-created agent request POST /v1/authorizations decisions with execution: "external". The decision API does not create a PaymentIntent and does not move money. Promotion to live money movement remains a separate controlled process.

Server API key (brain_sk_)

The credential a server-side integration uses is a RobotMoney-issued tenant API key with a brain_sk_ prefix. It authenticates directly as a bearer credential; there is no token exchange step.

Property
Value

Format

brain_sk_test_… (sandbox) / brain_sk_live_… (live)

Availability

Sandbox integration environment at launch; production API-key auth is deliberately disabled pending a separate release gate

Issued by

Tenant-admin key routes when API-key auth is enabled for the environment

Presented as

Authorization: Bearer brain_sk_…, or new Brain({ apiKey: "brain_sk_…" }) in the SDK

Scopes

ledger:read, audit:read, governance:read only. API keys cannot ingest source data.

Sandbox vs live

Distinct brain_sk_test_… and brain_sk_live_… key formats

Lifetime

No automatic TTL at issuance. Revocation and rotation are supported; an optional expires_at is enforced when populated.

The plaintext secret is returned only when a key is issued or rotated. The database retains only a server-peppered SHA-256 digest. Rate limits, idempotency, last-used tracking, and audit attribution are keyed off the authenticated key.

Human Owner Authentication

A developer self-provisions a sandbox tenant, verifies their email, then logs in for a short-lived owner JWT. The owner JWT is the setup credential for the headless path: it can create counterparties, create a tenant agent, manage headless limits, approve needs-review authorizations, void recorded authorizations, and read usage. It never carries payment_intent:execute or rail execution authority.

1. Sign up. Provisions a sandbox tenant + owner.

In production, the API emails the token through the configured ESP client (EMAIL_ENDPOINT, EMAIL_API_KEY, optional EMAIL_FROM). If BRAIN_SELF_SERVE_SIGNUP is enabled in production without ESP credentials, API boot fails before signup routes are served.

2. Verify the email. Single-use, short-TTL token, scoped to the tenant.

3. Log in. Email + password -> owner JWT.

An unknown email and a wrong password return the same 401 auth_invalid_credentials (no user enumeration); an unverified account returns 403 auth_email_unverified.

Tenant Agent API Key (brain_ak_)

A tenant agent API key is an exchange-only machine credential. It is returned once from POST /v1/agents as api_key_once and is never accepted directly at resource routes.

The response includes an exchange object with the token endpoint, resource, grant type, subject token type, and default scope. Use those values exactly.

Exchange the key at the token endpoint:

The response is a five-minute JWT with no refresh token. The agent exchanges the same key again when it needs a fresh JWT.

Property
Value

Prefix

brain_ak_test_... in sandbox, brain_ak_live_... for live tenants

Resource route use

Not accepted directly

Token TTL

300 seconds

Headless scope

payment_intent:propose

First headless call

POST /v1/authorizations with execution: "external"

Forbidden scope

payment_intent:execute

The headless launch path also uses owner-session scopes:

Credential
Headless use

Owner JWT

Signup completion, counterparty setup, agent creation, limit management, approve, void, usage reads

Agent exchanged JWT

POST /v1/authorizations only for propose-time decisions

Tenant API key

Commercial read API only

Wallet Authentication (SIWX). MCP agents and humans

MCP agents and humans who link a wallet authenticate with Sign-In With X (EIP-4361 over Base). This is separate from the tenant agent API key path above. An owner can link a wallet to their tenant:

At sign-in, SIWX resolves the wallet: one linked to a human mints an owner JWT with the same management scopes as email login. An MCP agent wallet registered and active in BrainMCPAgentRegistry mints an MCP agent token.

Step 1: Construct the SIWX Message

A nonce is obtained from POST /v1/auth/siwx/challenge (Redis-held, 5-minute TTL).

Step 2: Sign with the Identity Key

The agent (or human's linked wallet) signs the message with the key registered in BrainMCPAgentRegistry / linked via wallet_identities.

Step 3: Exchange for a Token

Step 4: Use the Token

The MCP auth chain verifies that the agent record is active and that its stored scope_hash matches the hash registered in BrainMCPAgentRegistry. Agents can read, contribute evidence, and propose. Never execute. There is no execute tool, and every settlement passes the section 6 gate.

Agent Scope Hash

The current scope mechanism is a hash commitment, not an EIP-712 scope-attestation object. RobotMoney sorts an agent's plain scope strings lexicographically, joins them with |, and calculates keccak256 over that value. The resulting scope_hash must match the agent's registered on-chain hash. It has no per-grant amount, resource, time-window, or nonce fields.

Token Lifetimes

Token
Default TTL
Refreshable

Owner JWT (email/wallet)

15 minutes

Yes. Log in / re-sign again

Tenant agent JWT (brain_ak_ exchange)

5 minutes

Exchange the agent key again

MCP agent token (SIWX)

1 hour

Yes, by re-signing SIWX

Server API key (brain_sk_, sandbox only at launch)

No automatic TTL

Rotated or revoked by tenant admin

Service-token mint (/v1/auth/service-token)

1 hour

Re-mint (break-glass sandbox/testnet)

Email-verification token

24 hours

No, single-use

Policy verdict

60 seconds

No, single-use

Owner JWTs include surfaces:admin so a tenant admin can connect or revoke Slack, Teams, and email approval surfaces. Surface onboarding endpoints derive the RobotMoney tenant from this bearer principal, not from request bodies.

Agent Control

Operation
Endpoint
Behavior

Halt

POST /v1/agents/{agent_id}/halt

Requires payment_intent:approve. Pauses approved in-flight payment intents from the agent and quarantines its local agent record.

Restore

POST /v1/agents/{agent_id}/restore

Requires payment_intent:approve. Restores a quarantined local agent record to active. Returns 404 when the agent is not registered and 409 unless its current state is quarantined.

Token

Re-authenticate or rotate the credential

Tokens are short-lived by design and expire after their configured lifetime.

What's Next

🌐 API Overview

Endpoints, versioning, rate limits.

📜 BrainMCPAgentRegistry

The on-chain agent registry.

Last updated