# auth.md

You are an agent. This service supports **agentic registration**: discover → register → call API.

Wood DaVinci is a premium e-commerce for 3D wooden puzzles and engineering models. APIs are at `https://www.woodsdavinci.com`.

## Step 1 — Discover

### 1a. Fetch the Protected Resource Metadata

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

This returns the `resource` identifier, `authorization_servers`, and `scopes_supported`.

### 1b. Fetch the Authorization Server metadata

```http
GET <authorization_servers[0]>/.well-known/oauth-authorization-server
```

The `agent_auth` block in the response tells you how to register.

## Step 2 — Pick a method

1. **You have a session tied to a user identity and can exchange it for an ID-JAG** → use `identity_assertion` + `id-jag`.
2. **You have the user's email** → use `identity_assertion` + `verified_email`. Claim ceremony required.
3. **You have neither** → use `anonymous`. You get a scoped API key immediately; claim ceremony is optional.

## Step 3 — Register

### identity_assertion + id-jag

Mint the ID-JAG with `aud` = `https://www.woodsdavinci.com`, then:

```http
POST /api/auth/agent
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "urn:ietf:params:oauth:token-type:id-jag",
  "assertion": "<your ID-JAG JWT>",
  "requested_credential_type": "access_token"
}
```

### identity_assertion + email

```http
POST /api/auth/agent
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "verified_email",
  "assertion": "user@example.com",
  "requested_credential_type": "api_key"
}
```

The service emails the user. Proceed to Step 4.

### anonymous

```http
POST /api/auth/agent
Content-Type: application/json

{
  "type": "anonymous",
  "requested_credential_type": "api_key"
}
```

You get a scoped API key immediately. Skip to Step 5 if you don't need a claim ceremony.

## Step 4 — Claim ceremony

The user receives an email with a 6-digit OTP. Read it back from the user, then:

```http
POST /api/auth/agent/claim/complete
Content-Type: application/json

{
  "claim_token": "<from Step 3>",
  "otp": "123456"
}
```

## Step 5 — Use the credential

```http
GET /api/resource
Authorization: Bearer <credential>
```

For admin endpoints, use the `master_key` header instead:

```http
GET /api/audit-logs
master_key: <your-master-key>
```

## x402 Paid Endpoints

AI service endpoints use the x402 payment protocol (USDC on Base Mainnet):

- `POST /api/enrich` — $0.01
- `POST /api/ai-tools` — $0.02
- `POST /api/translate` — $0.005

Use an x402-compatible client. Facilitator: `https://api.cdp.coinbase.com/platform/v2/x402`

## Public Endpoints (No Auth)

- `GET /api/catalog` — Search and browse products
- `GET /api/products/:id` — Get product details
- `GET /api/categories` — List categories
- `POST /api/orders` — Place an order
- `GET /api/health` — Health check

## Error Responses

| Code | Meaning |
|------|---------|
| 401 | Missing or invalid credential / master_key |
| 402 | Payment required (x402 endpoint) |
| 429 | Rate limit exceeded |
| 404 | Resource not found |
