# Authentication for AI Agents (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.

The endpoints referenced below use the canonical service host `https://www.pedagioeletronico.com.br`.

## Step 1 — Discover

Discovery is two hops.

The 401 response that points here carries a `WWW-Authenticate` header with the Protected Resource Metadata (PRM) URL:

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

Pull the `resource_metadata` value from that header and fetch it. If you don't have the 401 response in hand, the conventional path on the resource server is `/.well-known/oauth-protected-resource`.

### 1a. Fetch the Protected Resource Metadata

```http
GET https://www.pedagioeletronico.com.br/.well-known/oauth-protected-resource
```

Response shape:

```json
{
  "resource": "https://www.pedagioeletronico.com.br",
  "resource_name": "Pedágio Eletrônico API",
  "resource_logo_uri": "https://www.pedagioeletronico.com.br/logo.svg",
  "authorization_servers": ["https://www.pedagioeletronico.com.br"],
  "scopes_supported": ["read:public", "write:consultas"],
  "bearer_methods_supported": ["header"]
}
```

Fields explanation:
- `resource`: The canonical resource URL of the API. Use this as the `aud` when minting an ID-JAG assertion.
- `authorization_servers`: Base URLs of the OAuth Authorization Server(s). The `agent_auth` block lives on one of these.
- `scopes_supported`: Scopes understood by the resource server (`read:public`, `write:consultas`).
- `bearer_methods_supported`: Sends access tokens via `Authorization: Bearer <token>` header.

### 1b. Fetch the Authorization Server metadata

```http
GET https://www.pedagioeletronico.com.br/.well-known/oauth-authorization-server
```

Response shape:

```json
{
  "resource": "https://www.pedagioeletronico.com.br",
  "authorization_servers": ["https://www.pedagioeletronico.com.br"],
  "scopes_supported": ["read:public", "write:consultas"],
  "bearer_methods_supported": ["header"],
  "issuer": "https://www.pedagioeletronico.com.br",
  "token_endpoint": "https://www.pedagioeletronico.com.br/oauth/token",
  "revocation_endpoint": "https://www.pedagioeletronico.com.br/oauth/revoke",
  "grant_types_supported": [
    "authorization_code",
    "client_credentials",
    "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "urn:workos:agent-auth:grant-type:claim"
  ],
  "agent_auth": {
    "version": "1.0",
    "skill": "https://www.pedagioeletronico.com.br/auth.md",
    "identity_endpoint": "https://www.pedagioeletronico.com.br/api/v1/agent/identity",
    "claim_endpoint": "https://www.pedagioeletronico.com.br/api/v1/agent/claim",
    "events_endpoint": "https://www.pedagioeletronico.com.br/api/v1/agent/events",
    "identity_types_supported": ["anonymous", "service_auth", "identity_assertion"],
    "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"
    ]
  }
}
```

The `agent_auth` block is the agentic bootstrap surface:
- `issuer`: Canonical issuer URL.
- `token_endpoint`: Where you exchange a service-signed `identity_assertion` for an `access_token`.
- `revocation_endpoint`: Where you POST to revoke an `access_token`.
- `agent_auth.skill`: The URL of this specification document.
- `agent_auth.identity_endpoint`: Where you POST to register.
- `agent_auth.claim_endpoint`: Where you POST claim requests for ceremonies.
- `agent_auth.events_endpoint`: Where security event tokens (SET) are delivered.

## Step 2 — Pick a registration method

Review `agent_auth.identity_types_supported`:
1. `identity_assertion`: Use an [ID-JAG](https://datatracker.ietf.org/doc/draft-ietf-oauth-identity-assertion-authz-grant/) minted by your agent provider (`urn:ietf:params:oauth:token-type:id-jag`).
2. `service_auth`: Email-based or API key delegation.
3. `anonymous`: Bootstrap without existing user context, followed by claim ceremony.

## Step 3 — Register

Send a POST request to `agent_auth.identity_endpoint`:

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

{
  "type": "identity_assertion",
  "assertion": "<id-jag-jwt>",
  "scope": "read:public"
}
```

Response (200 OK):

```json
{
  "identity_assertion": "<service-signed-jwt>",
  "expires_in": 3600
}
```

## Step 4 — Claim ceremony

For anonymous registrations or when user consent confirmation is required:

### 4a. Deliver the claim URL
Present `claim_url` to the user to authorize access.

### 4b. Step-up authorization for existing accounts
The user completes the web consent ceremony.

### 4c. Polling for completion
Poll `agent_auth.claim_endpoint` using grant `urn:workos:agent-auth:grant-type:claim` until authorized.

## Step 5 — Exchange the assertion for an access_token

Exchange the `identity_assertion` at `token_endpoint`:

```http
POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>
```

Response (200 OK):

```json
{
  "access_token": "pe_sec_token_example",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read:public"
}
```

## Step 6 — Use the access_token

Present the `access_token` in the `Authorization` header on API requests:

```http
GET /api/v1/cnpj?cnpj=58237723000199
Authorization: Bearer <access_token>
```

## Errors

| Code | Where | Action |
| --- | --- | --- |
| `invalid_request` | `/api/v1/agent/identity` | Check request parameters and assertion signatures. |
| `anonymous_not_enabled` | `/api/v1/agent/identity` | Select `identity_assertion` or `service_auth`. |
| `invalid_grant` | `/oauth/token` | Assertion expired or revoked. Restart at Step 3. |
| `authorization_pending` | `/oauth/token` | User consent in progress; wait and retry. |
| `rate_limited` (429) | any | Observe `RateLimit-Reset` and `Retry-After` headers. |

## Revocation

- **Credential layer (RFC 7009):** POST to `revocation_endpoint` (`/oauth/revoke`) with `token=<access_token>` to revoke access immediately.
- **Registration layer (RFC 8935 SET):** Providers push revocation events to `events_endpoint` (`/api/v1/agent/events`).
