# auth.md — CookieSun Agent Authentication

CookieSun uses OAuth 2.0 (Authorization Code flow with PKCE) for agent and
customer authentication, backed by a Keycloak authorization server. Read actions
on the public catalog need no credentials; cart and order actions act on behalf
of a signed-in customer and require a bearer token.

## Discover
- Authorization server metadata (RFC 8414): https://cookiesun.com/.well-known/oauth-authorization-server
- Protected-resource metadata (RFC 9728): https://cookiesun.com/.well-known/oauth-protected-resource
- JWKS (token validation keys): https://cookiesun.com/.well-known/jwks.json

An unauthenticated call to a protected endpoint returns `401` with
`WWW-Authenticate: Bearer resource_metadata="https://cookiesun.com/.well-known/oauth-protected-resource"`,
which points an agent at the metadata above.

## Register
CookieSun authenticates agents that act on behalf of a customer through the
Authorization Code + PKCE flow — no static API keys are issued. Agent frameworks
that support OAuth should use the `authorization_endpoint` and `token_endpoint`
from the discovery document. For partner/server integrations, request a client
from support@cookiesun.com.

## Claim
1. Generate a PKCE `code_verifier` / `code_challenge` (S256).
2. Send the user to the `authorization_endpoint` with `response_type=code`,
   your `client_id`, `redirect_uri`, `scope`, and the `code_challenge`.
3. Exchange the returned `code` at the `token_endpoint` with `grant_type=authorization_code`
   and the `code_verifier` to obtain an access token.

## Use the credential
Send the token on every write request:

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

Scopes: `catalog:read` (public), `cart:write`, `orders:write`.

## Errors
- `401` → token missing/expired; re-authenticate (see the `WWW-Authenticate` header).
- `403` → wrong scope for the action.
- `429` → rate limited; honor `Retry-After`.
- All errors are RFC 7807 `application/problem+json` with `type`, `title`, `detail`, and `request_id`.

## Revocation
Revoke a token at the Keycloak revocation endpoint listed as `revocation_endpoint`
in the authorization-server metadata, or by signing the customer out.

## agent_auth

```json
{
  "agent_auth": {
    "preferred": "oauth2_authorization_code_pkce",
    "authorization_server_metadata": "https://cookiesun.com/.well-known/oauth-authorization-server",
    "protected_resource_metadata": "https://cookiesun.com/.well-known/oauth-protected-resource",
    "jwks_uri": "https://cookiesun.com/.well-known/jwks.json",
    "scopes_supported": ["catalog:read", "cart:write", "orders:write"],
    "pkce_required": true,
    "self_serve": false,
    "contact": "support@cookiesun.com"
  }
}
```

Last verified: 2026-06-20.
