> ## Documentation Index
> Fetch the complete documentation index at: https://docs.axon402.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Credential model for the Decision API

AXON supports three credential shapes on the Decision API. If neither a static operator key nor platform auth is configured, the daemon is misconfigured and will not start.

> [!NOTE]
>
> Hosted launch posture uses three different trust tiers on purpose: a wallet-scoped runtime key for agents, org-wide operator keys for control-plane automation, and Supabase sessions for human dashboard use. Do not hand `AXON_DECISION_API_KEY` to end users or agent runtimes.

## Static Operator Key

Use `AXON_DECISION_API_KEY` for static operator access: admin routes, worker triggers, `/v1/metrics`, and static-key access to `/v1/operator/mcp`.

**Configuration:**

```env theme={null}
AXON_DECISION_API_KEY=your-32-byte-hex-secret
```

**Request header:**

```http theme={null}
Authorization: Bearer <AXON_DECISION_API_KEY>
```

## Database API Keys (`axon_sk_*`)

AXON can mint database-backed API keys through `/v1/api-keys`.

* Wallet-scoped keys: runtime surface for `/v1/mcp` and wallet-bound REST calls.
* Org-wide keys: operator automation surface for `/v1/operator/mcp` and org-scoped REST routes.
* Scope enforcement applies only to database-backed keys; static operator keys are unrestricted.

## Supabase Session Auth

When `AXON_PLATFORM_AUTH_ENABLED=true`, the daemon also accepts a Supabase user access token on supported platform routes.

The daemon then:

1. Validates the Supabase session
2. Loads `user_organizations`
3. Grants org-scoped access based on membership

**Configuration:**

```env theme={null}
AXON_PLATFORM_AUTH_ENABLED=true
AXON_PLATFORM_ALLOWED_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
```

**Constraints:**

* User must exist in Supabase Auth
* User must belong to the organization in `user_organizations`
* In production, browser origin must be in `AXON_PLATFORM_ALLOWED_ORIGINS` or CORS rejects the request

## Route/Auth Matrix

| Route | Auth Mode | Notes |
| :- | :- | :- |
| `GET /health`, `GET /ready`, `GET /v1/health`, `GET /v1/ready` | Public | No bearer required |
| `GET /v1/`, `GET /v1/discovery/resources`, `POST /v1/services/:id/quote` | Public | Catalog, Bazaar discovery, and quote path |
| `POST /v1/cli/init` | Public | Rate-limited by client IP |
| `POST /v1/orgs/bootstrap` | Supabase session only | Browser-authenticated |
| `POST /v1/orgs/bootstrap/browser` | Supabase session only | Browser-authenticated; can be disabled with `AXON_HOSTED_BROWSER_BOOTSTRAP_DISABLED=true` |
| `GET /v1/me` | Bearer or Session | Static operator key returns no org context; tenant keys and sessions return surface/org details |
| `GET /v1/orgs/:id/readiness` | Bearer or Session | Session requires org membership |
| `GET /v1/orgs/:id/workforce` | Bearer or Session | Session requires org membership |
| `GET /v1/orgs/:id/vault` | Bearer or Session | Session requires org membership |
| `POST /v1/orgs/:id/transfers/*` | Bearer or Session | Write access |
| `POST /v1/provider-search` | Authenticated caller plus wallet context | Wallet-scoped keys use their binding; operator/static callers must supply `wallet_id` |
| `POST /v1/operator/mcp` | Static operator key or org-wide database API key | Wallet-scoped keys and platform sessions are rejected |
| `POST /v1/webhooks/dispatch`, `POST /v1/providers/sync`, `POST /v1/approvals/expire`, `POST /v1/transactions/confirm`, `GET /v1/metrics` | Static operator key only | These routes reject tenant keys and platform sessions |

## MCP Stdio Auth

The MCP server over stdio does not use HTTP bearer auth. Access control is provided by:

* Local process/environment permissions
* Runtime sandbox/tool allowlists in the agent host

The MCP process still needs backend secrets in its environment:

* `SUPABASE_SERVICE_KEY`
* `MASTER_MNEMONIC` (full-signing mode only)
* `BASE_RPC_URL`
* `AGENT_WALLET_ID`

## OpenClaw Plugin

```json theme={null}
{
  "decisionApiUrl": "http://127.0.0.1:3030",
  "decisionApiKey": "your-static-daemon-bearer"
}
```

## Dashboard API Keys

The dashboard page at `/settings/api-keys` is an organization-scoped key registry. It does **not** replace:

* Daemon `AXON_DECISION_API_KEY`
* Browser Supabase session auth
* Runtime/operator surface separation

## Common Auth Failures

> **401 Unauthorized**
>
> * Missing `Authorization` header
> * Invalid `AXON_DECISION_API_KEY` or revoked `axon_sk_*` key
> * `AXON_PLATFORM_AUTH_ENABLED` is off, so Supabase tokens are rejected
> * Session token is valid, but user has no `user_organizations` membership

> **403 Bootstrap requires browser session**
>
> Calling `POST /v1/orgs/bootstrap` with static bearer instead of a Supabase session token. Use the CLI bootstrap for headless setup.

> **Dashboard login works, but org routes fail**
>
> * Org was created via CLI and operator is missing a `user_organizations` row
> * Dashboard origin is not in `AXON_PLATFORM_ALLOWED_ORIGINS`

> **500 Neither auth mode configured**
>
> Daemon started without `AXON_DECISION_API_KEY` and without `AXON_PLATFORM_AUTH_ENABLED=true`.

## Hardening Checklist

* Keep `AXON_DECISION_API_KEY` in a secret manager, never in source control
* Keep `SUPABASE_SERVICE_KEY` and `MASTER_MNEMONIC` out of browser code and agent transcripts
* Restrict daemon network exposure
* Avoid logging full auth headers
* Rotate `AXON_DECISION_API_KEY` on compromise or environment changes


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.