# auth.md

> Agent authentication and registration for RenoPlumb (https://renoplumb.co.uk).

## Summary

**Most of this site needs no authentication.** Services, coverage areas, guides,
business details, the MCP server and every discovery document are public and
read-only — send the request, no credential required.

**One endpoint requires OAuth 2.0:** `GET https://renoplumb.co.uk/api/v1/export`, a bulk export of
the entire catalog in a single response. Registration is open and automatic: an
agent can go from nothing to a working token in two HTTP requests, with no human
approval and no account.

## Audience

AI agents, crawlers and integrators reading RenoPlumb's services,
coverage areas, self-help guides and business details.

## Endpoints

| Resource | URL | Auth |
| --- | --- | --- |
| REST API | `https://renoplumb.co.uk/api/v1` | None |
| OpenAPI 3.1 description | `https://renoplumb.co.uk/api/v1/openapi.json` | None |
| MCP server (Streamable HTTP) | `https://renoplumb.co.uk/api/mcp` | None |
| API catalog (RFC 9727) | `https://renoplumb.co.uk/.well-known/api-catalog` | None |
| MCP server card | `https://renoplumb.co.uk/.well-known/mcp/server-card.json` | None |
| Agent skills index | `https://renoplumb.co.uk/.well-known/agent-skills/index.json` | None |
| Human documentation | `https://renoplumb.co.uk/docs/api` | None |
| **Bulk catalog export** | `https://renoplumb.co.uk/api/v1/export` | **Bearer token, `catalog:read`** |

## Discovery

| Document | URL |
| --- | --- |
| Authorization server metadata (RFC 8414) | `https://renoplumb.co.uk/.well-known/oauth-authorization-server` |
| Claim endpoint (auth.md) | `https://renoplumb.co.uk/api/oauth/claim` |
| Protected resource metadata (RFC 9728) | `https://renoplumb.co.uk/.well-known/oauth-protected-resource/api/v1` |
| JSON Web Key Set | `https://renoplumb.co.uk/api/oauth/jwks.json` |

A `401` from the protected resource carries a `WWW-Authenticate` challenge
with a `resource_metadata` parameter pointing at the document above, so no
prior knowledge of these URLs is needed.

## Registration

Open dynamic client registration (RFC 7591). No initial access token, no
approval step, no human in the loop.

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

{ "client_name": "Your agent's name" }
```

Returns `201` with `client_id`, `client_secret` and a `claim_token`. The
secret does not expire (`client_secret_expires_at: 0`). Store all three; none
can be recovered if lost — register again instead.

A client registered this way has identity type `anonymous`.

## Claiming an identity

Optional. Attaches a named operator to an anonymous client, so that traffic can
be attributed to someone contactable.

```http
POST https://renoplumb.co.uk/api/oauth/claim
Content-Type: application/json

{
  "claim_token": "<from registration>",
  "owner": { "name": "Acme Agents Ltd", "contact": "ops@acme.example" }
}
```

Returns `201` with a **new** `client_id` and `client_secret` — use those
from then on. The owner details are sealed into the `client_id`, so they
cannot be altered later without invalidating the credential, and they appear as
`owner_name` and `owner_contact` on every access token issued to it.

**What claiming gets you:** access tokens valid for
86400 seconds instead of
3600. That is the whole benefit — there is no privileged
data and no additional scope.

**What claiming is not:** verification. This deployment has no email or SMS
delivery, so the owner details are self-asserted and never confirmed
(`owner_verified: false`, `claim_verification: "self_asserted"` in the
metadata). Do not treat a claimed identity as an authenticated organisation.

## Credentials

`client_secret`, presented with the client credentials grant (RFC 6749 §4.4).

```http
POST https://renoplumb.co.uk/api/oauth/token
Authorization: Basic <base64(client_id + ":" + client_secret)>
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=catalog:read
```

`client_secret_post` is accepted too: send `client_id` and
`client_secret` in the form body instead of the header.

Returns an `access_token` valid for 3600 seconds
(86400 for a claimed client). Use it
as `Authorization: Bearer <token>`. The header is the only accepted method —
query-string and form-body tokens are rejected.

```http
GET https://renoplumb.co.uk/api/v1/export
Authorization: Bearer <access_token>
```

## Token format

Signed JWT, `EdDSA` (Ed25519). Claims: `iss` = `https://renoplumb.co.uk`, `aud` =
`https://renoplumb.co.uk/api/v1`, plus `sub`, `client_id`, `scope`, `iat`, `exp` and
`jti`. Claimed clients also carry `owner_name` and `owner_contact`. Verify
against `https://renoplumb.co.uk/api/oauth/jwks.json`.

## Methods supported

- `anonymous` — unauthenticated access to every public resource listed above,
  and, after self-service registration, to the bulk export.
- `client_credentials` — machine-to-machine access to the bulk export.

Identity types supported: `anonymous` only. There is no ID-JAG
(`identity_assertion`) support, because accepting identity assertions means
trusting a named set of agent providers and this service has made no such trust
decisions.

There is no user-facing authorization flow: `authorization_endpoint` is absent
from the metadata, which RFC 8414 §2 permits when no supported grant type uses
it.

## Scopes

- `catalog:read` — read the full catalog export.

## Rate limits

No hard limit is enforced. Be reasonable: the data is small, fully cacheable and
changes rarely. Honour the `Cache-Control` headers rather than polling. Prefer
one `https://renoplumb.co.uk/api/v1/export` call over crawling every individual endpoint.

## Revocation

Credentials are stateless and cannot be revoked individually. If a
`client_secret` leaks, nothing sensitive is exposed — the data behind it is
public — but you may report it to the contact below.

## Usage terms

Content is licensed CC BY 4.0 — attribute RenoPlumb and link back to
https://renoplumb.co.uk. The `Content-Signal` directive in `https://renoplumb.co.uk/robots.txt`
declares `ai-train=no, search=yes, ai-input=yes`: do not train generative
models on this content; indexing it and using it to answer questions, with
attribution, is welcome.

## Contact

- Website: https://renoplumb.co.uk
- Telephone: 07460 824073
- Address: 2nd Floor, 255-259 Commercial Rd, London E1 2BT, GB
