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

# immersivecommons.com Authentication

> How an AI agent gets a per-user agt_ bearer token for the Immersive Commons API.

Immersive Commons issues per-user agent tokens. An agent registers its human once, receives a bearer token, then calls the MCP server, the A2A endpoint, and the REST surface with it. Ten SIGNAL, presentations, news, and donation tools are public and need no token.

## Discover

Machine-readable auth metadata (this page is the prose mirror):

* Authorization-server metadata (RFC 8414): [/.well-known/oauth-authorization-server](https://www.immersivecommons.com/.well-known/oauth-authorization-server) — carries the `agent_auth` extension block: `register_uri`, `claim_uri`, `verification_uri`, `revocation_uri`, `key_register_uri`, and `identity_types_supported`.
* Protected-resource metadata (RFC 9728): [/.well-known/oauth-protected-resource](https://www.immersivecommons.com/.well-known/oauth-protected-resource)
* Full manifest (scope catalog, endpoints, rate limits): [/.well-known/ai-agent.json](https://www.immersivecommons.com/.well-known/ai-agent.json)
* A2A agent card: [/.well-known/agent-card.json](https://www.immersivecommons.com/.well-known/agent-card.json)

<Note>
  API 401s do not yet carry a `WWW-Authenticate: Bearer resource_metadata="..."` hint — start from this page or the well-known documents above rather than probing for the header.
</Note>

## Pick a method

`identity_types_supported` is `["anonymous"]`: the agent holds no prior identity of its own; a signed-in human authorizes it. Identity chaining via `identity_assertion` (e.g. `id-jag` / `urn:ietf:params:oauth:token-type:id-jag`) is NOT offered. The credential issued is an api\_key-style bearer token.

Two registration paths:

1. **Device-code flow (RFC 8628, agent-driven — recommended).** No human credentials ever reach the agent. Steps in Register + Claim below.
2. **Browser mint (human-driven).** The human signs in at [/floor10/agent-console](https://www.immersivecommons.com/floor10/agent-console), picks scopes, clicks Mint, and pastes the plaintext token into the agent's environment.

## Register

The `agent_auth.register_uri` is `https://www.immersivecommons.com/api/agent/signup/start`.

1. `POST https://www.immersivecommons.com/api/agent/signup/start`
   Body: `{ "scopes": ["read:public", "membership:read"], "client_name": "Your Agent" }`
   Returns: `{ device_code, user_code, verify_url, verify_url_complete, expires_in, interval }`.
   `scopes` is REQUIRED and non-empty; pick the narrowest set for your workflow.
2. Show the human `verify_url_complete` (or `verify_url` plus the `user_code`). They approve at [/signup-with-agent](https://www.immersivecommons.com/signup-with-agent) while signed in.

## Claim

The `agent_auth.claim_uri` is `https://www.immersivecommons.com/api/agent/signup/poll`.

3. Poll `GET https://www.immersivecommons.com/api/agent/signup/poll?device_code=<device_code>` every `interval` seconds. Returns `{ "status": "pending" }` until approval, then ONCE `{ "status": "completed", agent_token, tier, granted_scopes, next_steps }`. Store `agent_token` immediately — it is delivered exactly once; subsequent polls return `410`.

<Warning>
  Deviations from stock RFC 8628 (tolerate these in a generic client): the token endpoint is polled with GET plus a `device_code` query param; the success field is `agent_token`, not `access_token`; pending is `200 { "status": "pending" }`, not `400 authorization_pending`.
</Warning>

## Use the credential

Bearer `agt_<base64url-32bytes>`, sent as `Authorization: Bearer agt_...`. The server stores only a SHA-256 of the token; the plaintext is shown once at mint time and is individually revocable.

Connect it to any of the three equivalent surfaces:

* MCP (Streamable HTTP): `https://www.immersivecommons.com/api/mcp`. Add the URL to your client, paste `agt_...` in the Authorization header.
* A2A (JSON-RPC 2.0): `https://www.immersivecommons.com/api/a2a`
* REST: per-endpoint docs in [llms.txt](https://www.immersivecommons.com/llms.txt) and [/.well-known/ai-agent.json](https://www.immersivecommons.com/.well-known/ai-agent.json)

Scopes are tier-gated; the full catalog (id, description, tier) lives in `/.well-known/ai-agent.json` (`auth.schemes[0].scopes`). Starter sets:

* Read only: `read:public`, `membership:read`
* Events and RSVP: add `events:read_upcoming`, `events:rsvp`
* Submit a highlight: add `events:submit_recap`, `directory:search`

<Note>
  Scopes cannot be added to an existing token — call the `ic_capabilities` MCP tool to learn what a NEW token needs, then re-register.
</Note>

### Optional: signed requests (RFC 9421)

Upgrade a bearer token to bearer plus Ed25519 signature so a leaked bearer alone is useless. Bind a public key (Clerk session required, so a leaked bearer cannot bind its own key):

* Register: `POST https://www.immersivecommons.com/api/agent/keys/register`
* Revoke: `POST https://www.immersivecommons.com/api/agent/keys/revoke`
* Enforce toggle: `POST https://www.immersivecommons.com/api/agent/keys/enforce-toggle`

Covered components, freshness window, and header examples are in `/.well-known/ai-agent.json` (`signed_requests` block).

## Errors

* `400 { "error": "missing_scopes" }` — registration POST without a non-empty `scopes` array; the response includes a usable example body.
* Over-scoped registration fails cleanly with structured `denied_scopes` (requested scopes above the human's tier).
* `401` / `403` — missing, malformed, unknown, or revoked bearer (no `WWW-Authenticate` challenge yet; see Discover).
* `410` — device code already consumed or expired; restart at Register.
* `429` — per-token daily write limits; back off until the next UTC day.

If a documented surface doesn't match the deployed behavior, POST a structured report to `https://www.immersivecommons.com/api/agent/feedback` (kinds: `broken_url`, `schema_mismatch`, `stale_doc`, `endpoint_404`, `other`). Out-of-band: [admin@immersivecommons.com](mailto:admin@immersivecommons.com).

## Revocation

* **Self-revoke (agent-driven):** `POST https://www.immersivecommons.com/api/agent/token/revoke` with the bearer to revoke — a token can kill only ITSELF (no Clerk session needed; cross-token revoke is deliberately not possible from a token). Returns `200 { ok: true, revoked: true, prefix }`. Idempotent.
* **Console revoke (human-driven):** the advertised `agent_auth.revocation_uri` — [/floor10/agent-console](https://www.immersivecommons.com/floor10/agent-console) — where the signed-in human can revoke ANY of their tokens.
* **Key rotation:** `POST https://www.immersivecommons.com/api/agent/keys/revoke` clears an Ed25519 binding (then re-register a fresh key).
