# auth.md

You are an agent. **HAIL** (Heroes of the AI League) supports agentic registration so you can obtain a scoped credential and call the assessment API on behalf of a user.

HAIL diagnoses a team's AI-adoption + engineering-system-health archetype. Site: https://heroleague.ai · MCP: https://heroleague.ai/mcp · Privacy: https://heroleague.ai/privacy.html · Terms: https://heroleague.ai/terms.html · Refunds: https://heroleague.ai/refunds.html

Public free-tier assessment also accepts email in the request body with no bearer token (see OpenAPI / MCP). Prefer registration when you need a reusable access_token, claim binding, or to recover from a `401`.

## Step 1 — Discover

### 1a. Protected Resource Metadata

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

```json
{
  "resource": "https://heroleague.ai/",
  "resource_name": "HAIL",
  "authorization_servers": ["https://heroleague.ai"],
  "scopes_supported": [
    "assessment:read",
    "assessment:write",
    "playbook:read"
  ],
  "bearer_methods_supported": ["header"]
}
```

On `401`, also look for:

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

### 1b. Authorization Server metadata

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

Read the `agent_auth` block for `register_uri`, `claim_uri`, `revocation_uri`, supported identity types, and credential types.

## Step 2 — Pick a method

1. **You have the user's email and can run a claim ceremony** → `identity_assertion` with `verified_email`.
2. **You have neither a provider assertion nor email yet** → `anonymous`, then claim later with email.

HAIL does not yet accept ID-JAG (`urn:ietf:params:oauth:token-type:id-jag`). If that is your only option, fall back to verified email or anonymous.

## Step 3 — Register

`POST` JSON to `agent_auth.register_uri` (`https://heroleague.ai/agent/auth`).

### verified_email

Before registering, confirm with the user that HAIL may bind a credential to their email.

```json
{
  "type": "identity_assertion",
  "assertion_type": "verified_email",
  "login_hint": "user@example.com"
}
```

Expect a `claim` block (`user_code`, `verification_uri`, `expires_in`, `interval`) plus a `claim_token`. Surface the code and verification URI to the user; do not email the code yourself.

### anonymous

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

Expect a pre-claim `access_token` (or assertion to exchange) scoped to `assessment:read` / limited write, plus a `claim_token` for later ownership binding.

## Step 4 — Claim

When you have a `claim_token` and an email, `POST` to `agent_auth.claim_uri`:

```json
{
  "claim_token": "…",
  "email": "user@example.com"
}
```

Then have the user open `verification_uri`, sign in / confirm ownership, and enter the `user_code`. Poll until the ceremony completes and you receive a post-claim `access_token`.

## Step 5 — Use the credential

Send the access token as:

```http
Authorization: Bearer <access_token>
```

### Scopes

| Scope | Use |
| --- | --- |
| `assessment:read` | `GET /api/questions`, `GET /api/result/{id}`, `GET /api/archetypes` |
| `assessment:write` | `POST /api/session/start`, `PATCH /api/session/{id}/progress`, `POST /api/session/{id}/checkpoint`, `POST /api/diagnose`, `POST /api/run/{id}/save`, `POST /api/run/{id}/save-email` |
| `playbook:read` | `GET /api/playbook/{id}` (requires ownership cookie or Save token) |

Free tier: anonymous scored diagnose (no email required; hero card + five actions). The detailed What to Fix playbook (`get_playbook` / `playbook:read`) requires Premium or Portfolio **and** ownership proof (Save token or `hail_run` cookie). Portfolio / Premium-exhausted responses include `upgrade_url` — agents never handle payment. Once Premium is owned for an email, only Portfolio is offered (and only after Premium runs are exhausted).

MCP tools (same capabilities): `list_questions`, `run_assessment`, `get_result`, `get_playbook` at `https://heroleague.ai/mcp`.

## Revocation

Revoke at `agent_auth.revocation_uri` (`https://heroleague.ai/oauth2/revoke`) with the access token ([RFC 7009](https://datatracker.ietf.org/doc/html/rfc7009)). On the next `401`, rediscover via PRM and register again if needed.

## Errors

| Situation | Agent action |
| --- | --- |
| `401` with `resource_metadata` | Fetch PRM → AS metadata → register |
| `anonymous_not_enabled` / assertion type rejected | Pick another method from Step 2 |
| `authorization_pending` while claiming | Wait `interval` and poll again |
| `expired_token` on claim | Restart claim with the same `claim_token` + email |
| Portfolio / paid pool exhausted (`gated: true`) | Send the user to `upgrade_url` |

## Contact

Integration issues: hello@heroleague.ai · Docs: https://heroleague.ai/llms.txt · OpenAPI: https://heroleague.ai/openapi.json
