# auth.md

You are an AI agent. This document explains how to register with **Reelbase**
and obtain an access token to call our API. Reelbase generates images and video.

- **Resource server** (the API you call): `https://reelbase.ai/api/mcp`
- **Authorization server** (where you register and get tokens): `https://reelbase.ai`

Reelbase supports the [WorkOS agent-auth profile](https://workos.com/auth-md/docs).
Read the Discovery section first, then pick a method, then register.

---

## 1. Discover

On any `401` from the resource server you get a pointer to discovery:

```http
WWW-Authenticate: Bearer resource_metadata="https://reelbase.ai/.well-known/oauth-protected-resource/api/mcp"
```

Fetch the Protected Resource Metadata, then the Authorization Server metadata:

- Protected resource: `https://reelbase.ai/.well-known/oauth-protected-resource/api/mcp`
- Authorization server: `https://reelbase.ai/.well-known/oauth-authorization-server`

The AS metadata carries an `agent_auth` block with:
`identity_endpoint`, `claim_endpoint`, `events_endpoint`, `identity_types_supported`,
plus the standard `token_endpoint` and `revocation_endpoint`.

## 2. Pick a method

- `identity_assertion` — you hold a provider-issued ID-JAG for this audience.
  Only available if `identity_types_supported` includes `identity_assertion`.
- `service_auth` — you know the user's email but have no ID-JAG.
- `anonymous` — you have neither. Register now, the user claims you later.

## 3. Register — `POST https://reelbase.ai/agent/identity`

### anonymous
```json
{ "type": "anonymous" }
```
Returns a pre-claim `identity_assertion` (read-only `api.read`), a `claim_token`,
and a `claim_url`. To upgrade to `api.write` (generation), run the claim ceremony.

### service_auth
```json
{ "type": "service_auth", "login_hint": "user@example.com" }
```
Returns a `claim_token` plus a `claim` block (`user_code`, `verification_uri`,
`interval`, `expires_in`). No pre-claim token is issued.

### identity_assertion
```json
{
  "type": "identity_assertion",
  "assertion_type": "urn:ietf:params:oauth:token-type:id-jag",
  "assertion": "<your ID-JAG JWT>"
}
```
On a clean match we return a service-signed `identity_assertion` immediately.
If the email matches an existing account that you are not yet linked to, you get
`401 interaction_required` with a `claim` block — run the claim ceremony once.

## 4. Claim ceremony (user-claimed methods)

**4a. Get materials.** For `anonymous`, call
`POST https://reelbase.ai/agent/identity/claim` with `{ "claim_token", "email" }` to obtain
the `user_code` + `verification_uri`. For `service_auth` / step-up they are already
in the registration response.

**4b. Hand off to the user.** Show them the `verification_uri` and the `user_code`.
They open the link, sign in to Reelbase, and confirm the code.

**4c. Poll.** Call the token endpoint with the claim grant until it completes:
```http
POST https://reelbase.ai/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=<clm_...>
```
Responses: `{ "error": "authorization_pending" }` (keep polling, respect `interval`),
`{ "error": "slow_down" }` (back off), `{ "error": "expired_token" }` (restart), or
success with an `access_token` **and** a fresh post-claim `identity_assertion`.

## 5. Exchange the assertion — `POST https://reelbase.ai/oauth2/token`

For the `identity_assertion` method (and to refresh any token), exchange the
assertion via RFC 7523 JWT-bearer:
```http
POST https://reelbase.ai/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https://reelbase.ai/api/mcp
```
Returns `{ "access_token", "token_type": "Bearer", "expires_in", "scope" }`.
There is **no refresh_token** — re-exchange the same assertion to refresh until it
expires.

## 6. Use the access token

Send it as a Bearer token to the resource server:
```http
POST https://reelbase.ai/api/mcp
Authorization: Bearer <access_token>
```
`api.read` tokens (pre-claim) can discover but cannot generate. `api.write`
tokens (post-claim) can run every generation tool and spend the linked user's
credits.

## 7. Errors

| Code | Where | Do |
|------|-------|----|
| `login_required` | /agent/identity | ID-JAG `auth_time` too old — re-authenticate the user |
| `interaction_required` | /agent/identity | First link — run the claim ceremony |
| `authorization_pending` | /oauth2/token | Keep polling at `interval` |
| `slow_down` | /oauth2/token | Increase your poll interval |
| `expired_token` | /oauth2/token | Claim window closed — register again |
| `invalid_grant` | /oauth2/token | Assertion/token invalid or expired |

## 8. Revocation

Revoke an access token (RFC 7009):
```http
POST https://reelbase.ai/oauth2/revoke
Content-Type: application/x-www-form-urlencoded

token=<access_token>&token_type_hint=access_token
```
The `identity_assertion` stays valid for re-exchange unless your provider revokes
the underlying delegation.
