# Authorization

> OAuth 2.1, PKCE, dynamic registration, and audience-bound tokens.

An unauthenticated request to the MCP endpoint returns 401 with a WWW-Authenticate header naming the protected-resource metadata document. That is the whole discovery mechanism — no configuration on either side.

| Endpoint | Spec |
| --- | --- |
| https://wallet.route402.dev/.well-known/oauth-protected-resource | RFC 9728 |
| https://wallet.route402.dev/.well-known/oauth-authorization-server | RFC 8414 |
| https://wallet.route402.dev/register | RFC 7591 dynamic client registration |
| https://wallet.route402.dev/oauth/authorize | Authorization code + PKCE (S256 only) |
| https://wallet.route402.dev/oauth/token | Token exchange and refresh, with rotation |
| https://wallet.route402.dev/oauth/revoke | RFC 7009 |

### Scopes

| Scope | Grants |
| --- | --- |
| registry:read | Search and read listings for paid services. No access to your wallet. |
| wallet:read | See your balance, remaining budget, and past payments. Cannot pay for anything. |
| wallet:spend | Sign and settle payments, inside the limits below. This is the only permission that moves money. |

Tokens are audience-bound to https://wallet.route402.dev/mcp. A token minted for the publishing server at route402.dev is rejected here, and vice versa. `wallet:spend` is never bundled into a connect grant: it has its own consent screen showing the limits it is bound by, and the connection can always be approved without it.
