# Authenticating with AUVY

AUVY acts only as a person or a workspace that said yes. An agent gets a credential in one of the ways below and sends it as a bearer token. Nothing is open without one except discovery: `https://api.auvy.ai/health`, MCP `initialize` and `tools/list`, and the well-known documents.

## 1. Discover

- Protected resource metadata (RFC 9728): https://api.auvy.ai/.well-known/oauth-protected-resource/mcp
- Authorization server metadata (RFC 8414): https://auth.auvy.ai/.well-known/oauth-authorization-server/api/auth (issuer `https://auth.auvy.ai/api/auth`)
- OpenID Connect: https://auth.auvy.ai/.well-known/openid-configuration
- Authorization endpoint: https://auth.auvy.ai/api/auth/oauth2/authorize
- Token endpoint: https://auth.auvy.ai/api/auth/oauth2/token
- Revocation endpoint: https://auth.auvy.ai/api/auth/oauth2/revoke
- JSON Web Keys: https://auth.auvy.ai/.well-known/jwks.json
- Scopes: `auvy.access`, `openid`, `profile`, `email`, `offline_access`
- API security schemes: https://api.auvy.ai/openapi.json (`components.securitySchemes`)

A call to `POST https://api.auvy.ai/mcp` without a token still answers `initialize` and `tools/list`; a tool call answers with the OAuth challenge that names the resource metadata above.

## 2. Pick a method

| Method | Use when | Credential |
| --- | --- | --- |
| OAuth 2.1, authorization code with PKCE (S256) | An assistant acts for a person over MCP | Access token for resource `https://api.auvy.ai/mcp`, scope `auvy.access` |
| Workspace key | A developer configures Cursor, Codex, VS Code or a script, or automation acts for a workspace or one project | `ak_live_…` |

There is no anonymous agent registration and no identity assertion grant, so every credential traces back to a person who signed in.

## 3. Register

- OAuth clients identify themselves with a Client ID Metadata Document: the `client_id` is the document's URL. The authorization server fetches it from approved hosts only, such as chatgpt.com and claude.ai for ChatGPT, Claude and Claude Code.
- Dynamic client registration is off in production, so a client that only does that uses a workspace key instead.
- A personal key `auk_p_…` acts as the person who made it, mail and calendar included. Today AUVY's phone app makes one for itself.
- Agents do not register keys. A workspace admin creates one in AUVY under Settings, Keys (https://www.auvy.ai/os/settings/keys), bound to the project open when it is made. Anyone else asks an admin.

## 4. Claim

The person claims the credential by signing in. For OAuth, send them to the authorization endpoint with PKCE (S256), `resource=https://api.auvy.ai/mcp` and `scope=auvy.access`; they sign in and consent on www.auvy.ai, and the authorization server returns a code with `iss`. For a key, creating it in AUVY is the claim. A person without an account gets access at https://www.auvy.ai/access first.

## 5. Exchange

Exchange the code at https://auth.auvy.ai/api/auth/oauth2/token with the PKCE verifier and the same `resource`. The access token is a signed JWT for `https://api.auvy.ai/mcp` and opens nothing else. Request `offline_access` to get a refresh token, and refresh at the same endpoint when the token expires.

## 6. Use the credential

- MCP: `Authorization: Bearer <token>` on `https://api.auvy.ai/mcp`. Cursor, Codex and VS Code send `Authorization: Bearer ak_live_…` there.
- API: `Authorization: Bearer ak_live_…` on `https://api.auvy.ai`, with no other header: the key carries its workspace and project. An `X-Brain-Id` for another project is refused.

## 7. Errors

| Status | Meaning | What to do |
| --- | --- | --- |
| 401 | No credential, or one not valid for this door | Get a token or key as above, or refresh an expired token |
| 403 | Valid, but may not act here (another workspace or project, a missing grant) | Ask the person for access, or use the right project |
| 429 | Over quota | Wait for `retry-after`; `RateLimit` headers show what is left |

Every error is one JSON body: `{"error":{"code","message","status","retryable","request_id"}}`.

## 8. Revocation

A workspace admin revokes a key in AUVY under Settings, Keys, and a client revokes a token at https://auth.auvy.ai/api/auth/oauth2/revoke. The next call with it answers 401, so start again at step 1.
