# auth.md

You are an agent. This service supports **agentic registration**: discover → register → (claim if needed) → exchange for an access_token → call API → handle revocation. Follow the steps in order; do not skip ahead.

Canonical host: `https://www.tryx402.app` (the resource server and authorization server for tryx402 spend governance).

## Step 1 — Discover

Discovery is two hops — you may have already done this.

The 401 response that pointed you here also carries a `WWW-Authenticate` header with the PRM URL:

```http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://www.tryx402.app/.well-known/oauth-protected-resource"
```

Fetch the Protected Resource Metadata:

```http
GET /.well-known/oauth-protected-resource
```

Response shape:

```json
{
  "resource": "https://www.tryx402.app/",
  "resource_name": "tryx402",
  "resource_logo_uri": "https://www.tryx402.app/favicon.ico",
  "authorization_servers": ["https://www.tryx402.app/"],
  "scopes_supported": ["tools.read", "tools.execute", "billing.read"],
  "bearer_methods_supported": ["header"]
}
```

Fetch the Authorization Server metadata:

```http
GET /.well-known/oauth-authorization-server
```

Response shape:

```json
{
  "resource": "https://www.tryx402.app/",
  "authorization_servers": ["https://www.tryx402.app/"],
  "scopes_supported": ["tools.read", "tools.execute", "billing.read"],
  "bearer_methods_supported": ["header"],
  "issuer": "https://www.tryx402.app",
  "token_endpoint": "https://www.tryx402.app/oauth2/token",
  "revocation_endpoint": "https://www.tryx402.app/oauth2/revoke",
  "grant_types_supported": [
    "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "urn:workos:agent-auth:grant-type:claim"
  ],
  "agent_auth": {
    "skill": "https://www.tryx402.app/auth.md",
    "identity_endpoint": "https://www.tryx402.app/agent/identity",
    "claim_endpoint": "https://www.tryx402.app/agent/identity/claim",
    "events_endpoint": "https://www.tryx402.app/agent/event/notify",
    "identity_types_supported": ["anonymous", "identity_assertion", "service_auth"],
    "identity_assertion": {
      "assertion_types_supported": ["urn:ietf:params:oauth:token-type:id-jag"]
    },
    "events_supported": [
      "https://schemas.workos.com/events/agent/auth/identity/assertion/revoked"
    ]
  }
}
```

## Step 2 — Pick a method

Use this decision tree:
1. **You have a session tied to a user identity and can exchange it for an ID-JAG, audience-bound to this service** → `identity_assertion + id-jag`.
2. **You have only the user's email** → `service_auth`. Claim ceremony required.
3. **You have neither** → `anonymous`. Claim ceremony optional; deferred until the user wants to take ownership.

## Step 3 — Register

### anonymous registration

```http
POST /agent/identity
Content-Type: application/json

{
  "type": "anonymous"
}
```

Response (200):

```json
{
  "registration_id": "reg_anon_tryx402_12345",
  "registration_type": "anonymous",
  "identity_assertion": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "assertion_expires": "2027-09-01T00:00:00.000Z",
  "scopes": ["tools.read", "tools.execute"],
  "claim_url": "https://www.tryx402.app/agent/identity/claim",
  "claim_token": "clm_tryx402_67890"
}
```

## Step 4 — Claim

For `service_auth` or claiming an anonymous registration:
POST to `/agent/identity/claim` with your `claim_token`. The user completes the verification ceremony at the returned `verification_uri` using `user_code`.

## Step 5 — Use credential

Exchange the identity assertion for a scoped `access_token` at `/oauth2/token` or send `Authorization: Bearer <access_token>` on API requests.

```http
POST /api/v1/call
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "url": "https://api.example.com/enrich",
  "price": 0.05,
  "max_budget": 0.50
}
```

## Step 6 — Errors & Handling

| Error Code | HTTP Status | Resolution |
|---|---|---|
| `interaction_required` | 401 | Surface verification_uri and user_code to operator |
| `login_required` | 401 | Re-authenticate upstream provider |
| `budget_exceeded` | 422 | Ceiling reached; increase budget or request human approval |
| `rate_limited` | 429 | Honor `RateLimit-Reset` and `Retry-After` headers |

## Step 7 — Revocation

POST form-encoded `token=<access_token>&token_type_hint=access_token` to `/oauth2/revoke` to terminate credentials cleanly.
