# auth.md — Clever Mum agent authentication

Clever Mum publishes UK parenting advice, buying guides and open datasets.
**Reading them requires no authentication at all.** Authenticate only if you
want a registered agent identity for future rate limits. The lifecycle below
is procedural — follow it in order.

| Field | Value |
|---|---|
| Issuer | `https://clevermum.co.uk` |
| Protected resource | `https://clevermum.co.uk/api/v1` |
| Identity types supported | `software_agent`, `anonymous` |
| Credential types supported | `client_secret`, `access_token` |
| Anonymous access | Supported for all public read paths |

## Step 1 — Discover

Fetch the two metadata documents. Everything else is derived from them; do not
hard-code endpoints.

```http
GET https://clevermum.co.uk/.well-known/oauth-authorization-server
GET https://clevermum.co.uk/.well-known/oauth-protected-resource
```

The first returns `issuer`, `token_endpoint`, `authorization_endpoint`,
`registration_endpoint`, `jwks_uri`, `grant_types_supported` and an
`agent_auth` block. The second returns the resource identifier, its
`authorization_servers`, and `scopes_supported`.

## Step 2 — Register

Dynamic client registration (RFC 7591) is open and immediate — there is no
approval queue and no human review.

```http
POST https://clevermum.co.uk/oauth/register
Content-Type: application/json

{ "client_name": "My parenting research agent", "redirect_uris": [] }
```

Returns `client_id` and `client_secret`. Send an empty `redirect_uris` for
machine-to-machine use; supply https (or loopback) URIs to also enable the
authorization-code flow. Store both values — the secret is not recoverable and
registration is not idempotent.

## Step 3 — Claim (optional)

Clever Mum has no agent-level identity claim. Registered clients are
pseudonymous by design. Skip to step 4 for public data.

## Step 4 — Exchange credentials for a token

Machine-to-machine (no user involved):

```http
POST https://clevermum.co.uk/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=...&client_secret=...&scope=content:read
```

Or, when a human should approve the grant, the authorization-code flow with
PKCE (`S256` is required):

1. Send the user to `https://clevermum.co.uk/oauth/authorize` with
   `response_type=code`, `client_id`, a registered `redirect_uri`,
   `code_challenge`, `code_challenge_method=S256` and `state`.
2. On approval you receive `code` at your `redirect_uri`.
3. POST it back to `https://clevermum.co.uk/oauth/token` with
   `grant_type=authorization_code` and your `code_verifier`.

Access tokens are bearer credentials valid for 3600 seconds. Scopes are
`content:read` and `content:bulk`.

## Step 5 — Use the token

```http
GET https://clevermum.co.uk/api/v1/recommend-gear?category=pushchairs
Authorization: Bearer <access_token>
```

Public endpoints (`/answers-index.json`, `/llms.txt`, `/data/datapackage.json`,
Markdown negotiation, MCP tools) also work **without** an `Authorization`
header — anonymous access is first-class.

## Step 6 — Revoke

Tokens are short-lived and expire on their own; discard them at end of use.
To retire a client, discard the credentials. If a `client_secret` leaks, email
editors@clevermum.co.uk so the client can be blocklisted, and register a
replacement via step 2.

## Other agent surfaces

- MCP server: `https://clevermum.co.uk/mcp` — card at `https://clevermum.co.uk/.well-known/mcp/server-card.json`
- A2A: `https://clevermum.co.uk/a2a` — card at `https://clevermum.co.uk/.well-known/agent-card.json`
- Skills: `https://clevermum.co.uk/.well-known/agent-skills/index.json`
- Site map for LLMs: `https://clevermum.co.uk/llms.txt`
- Answers index: `https://clevermum.co.uk/answers-index.json`
