# Brendan's auth.md

This service supports agent registration for Brendan's private owner MCP endpoint. The public MCP endpoint at `https://irvinebroque.com/mcp` is anonymous and read-only; do not register for it.

## Audience and supported method

- Resource: `https://irvinebroque.com/owner/mcp`
- Agent audience: OAuth clients acting for the configured site owner
- Identity type: `service_auth`
- Credential type: `access_token` (Bearer)
- Grants: authorization code with PKCE (S256), then refresh token
- Scopes: `taste:read` and `taste:write`

Only the configured owner can finish authorization. Registration does not create a public account or bypass the owner's Google sign-in and consent.

## 1. Discover

Fetch the OAuth Protected Resource Metadata:

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

Then fetch the advertised authorization server's metadata:

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

The `agent_auth` block is the machine-readable source for the registration, authorization, token, and revocation URLs.

## 2. Register the OAuth client

POST RFC 7591 client metadata to `register_uri`. Use a redirect URI controlled by the client and request the authorization-code and refresh-token grants.

```http
POST /oauth/register
Content-Type: application/json

{
  "client_name": "Example agent",
  "redirect_uris": ["http://127.0.0.1:8765/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}
```

Store the returned `client_id`. Dynamically registered clients expire after 90 days. Public clients do not receive a client secret and must use PKCE.

## 3. Ask the owner to authorize

Generate a fresh PKCE verifier, its S256 challenge, and a CSRF `state` value. Open the authorization URL in a user-controlled browser:

```text
https://irvinebroque.com/oauth/authorize?client_id=<client_id>&response_type=code&redirect_uri=<encoded_redirect_uri>&scope=taste%3Aread%20taste%3Awrite&state=<state>&code_challenge=<challenge>&code_challenge_method=S256&resource=https%3A%2F%2Firvinebroque.com%2Fowner%2Fmcp
```

The configured owner signs in with Google and explicitly approves the requested scopes. Validate `state` when the authorization server redirects to the registered callback. There is no separate Auth.md claim ceremony or `claim_uri`; owner identity is bound during this authorization step.

## 4. Exchange the code

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

grant_type=authorization_code&client_id=<client_id>&code=<code>&redirect_uri=<encoded_redirect_uri>&code_verifier=<pkce_verifier>&resource=https%3A%2F%2Firvinebroque.com%2Fowner%2Fmcp
```

The response contains a short-lived `access_token`, a `refresh_token`, expiry information, and the granted scope. Keep credentials out of logs and persistent agent output.

## 5. Use and refresh the credential

Send the access token only to the canonical owner resource:

```http
POST /owner/mcp
Authorization: Bearer <access_token>
Content-Type: application/json
```

When the access token expires, POST `grant_type=refresh_token`, `client_id`, `refresh_token`, and `resource=https://irvinebroque.com/owner/mcp` to `/oauth/token`.

## 6. Revoke

The authorization server's `revocation_endpoint` and `agent_auth.revocation_uri` are both `https://irvinebroque.com/oauth/token`. Revoke an access or refresh token with an RFC 7009 form request authenticated as the registered client:

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

client_id=<client_id>&token=<token>&token_type_hint=refresh_token
```

The owner can also revoke the complete client grant from the site's connected-clients page. After revocation or an `invalid_grant` response, discard the affected credentials and restart at registration if access is still required.

## Errors and recovery

- `invalid_client_metadata`: correct the registration document; do not retry it unchanged.
- `invalid_request` or `invalid_scope`: correct the authorization or token request.
- `access_denied`: the owner declined or is not authorized; stop without retrying.
- `invalid_grant`: discard the code or token and restart the relevant authorization step.
- 5xx: retry the same safe request with bounded exponential backoff.

API and MCP setup documentation: `https://irvinebroque.com/mcp/setup`.
