# Coverage Cat Agent Authentication

## Discover

Coverage Cat publishes OAuth protected-resource metadata at `https://coveragecat.com/.well-known/oauth-protected-resource`, authorization-server metadata at `https://coveragecat.com/.well-known/oauth-authorization-server`, a Web Bot Auth key directory at `https://coveragecat.com/.well-known/http-message-signatures-directory`, and this prose guide at `https://coveragecat.com/auth.md`. The protected resource identifier for OpenAI and MCP hosts is `https://coveragecat.com/api/agent/mcp`. Protected entry points answer with `WWW-Authenticate: Bearer resource_metadata="https://coveragecat.com/.well-known/oauth-protected-resource"` so an agent can discover the auth shape from one unauthorized request. The authorization-server metadata includes a standard authorization-code + PKCE `authorization_endpoint`, an `agent_auth` block, modern `identity_endpoint` and `claim_endpoint` fields, and the legacy `register_uri`, `claim_uri`, and `revocation_uri` compatibility aliases.

## Pick a method

For OpenAI apps, ChatGPT developer mode, and other standard OAuth hosts, use `https://coveragecat.com/oauth2/authorize` with `response_type=code`, `resource=https://coveragecat.com/api/agent/mcp`, and PKCE (`code_challenge_method=S256`). Coverage Cat only accepts this browser-based OAuth flow from trusted client hosts managed by the service (currently `chatgpt.com`, `chat.openai.com`, `.openai.com`). Coverage Cat verifies the operator with an email OTP on its own page, then redirects back with an authorization code that you exchange at `https://coveragecat.com/oauth2/token` with `grant_type=authorization_code`. For service-auth agents that already speak Coverage Cat's richer claim flow, call `https://coveragecat.com/agent/identity` with the operator email as the login hint, show the returned user code to the human, have them finish the claim on Coverage Cat's service-owned page at `https://coveragecat.com/agent/identity/claim`, and then exchange the resulting `id-jag` (`urn:ietf:params:oauth:token-type:id-jag`) identity assertion at `https://coveragecat.com/oauth2/token` using the standard OAuth JWT bearer grant (`urn:ietf:params:oauth:grant-type:jwt-bearer`). Coverage Cat also preserves the older `identity_assertion` + `verified_email` path for compatibility with earlier agents and scanners, but that legacy route is an alias over the same operator identity model.

## Register

Modern agents should call `identity_endpoint` at `https://coveragecat.com/agent/identity`. Coverage Cat returns a `claim_token` for polling, a user-facing `verification_uri` / `verification_uri_complete`, a short user code, and the supported OAuth grant types. Legacy agents may still call `register_uri` at `https://coveragecat.com/agent/auth` with an `identity_assertion` whose `assertion_type` is `verified_email`; Coverage Cat will email an OTP directly to that operator inbox and return a `claim_token` for `claim_uri`.

## Claim

In the user-claimed `service_auth` flow, the human completes the claim on Coverage Cat's own page instead of handing an OTP back to the agent. That page authenticates the asserted operator email with a separate Coverage Cat OTP, but the visible claim code still comes from the agent, not from Coverage Cat, so the agent and human stay in sync. The agent can poll `claim_endpoint` at `https://coveragecat.com/agent/identity/claim` or call `https://coveragecat.com/oauth2/token` with `grant_type=urn:workos:agent-auth:grant-type:claim` plus the `claim_token`; once the claim completes, Coverage Cat returns a service-signed `identity_assertion` JWT. Legacy agents can still call `claim_uri` at `https://coveragecat.com/agent/auth/claim` with the emailed OTP and may request either an `access_token` or an `api_key`.

## Use the credential

Exchange either the authorization code or the `identity_assertion` at `https://coveragecat.com/oauth2/token` to mint a bearer access token scoped to `coveragecat:agent_api`. Send that token as `Authorization: Bearer ...` on delegated homeowners, dashboard, NLWeb `/ask`, and other protected agent endpoints. Coverage Cat also accepts additive RFC 9421/Web Bot Auth request signatures: if you send `Signature-Agent`, `Signature-Input`, and `Signature` headers, they must verify against the key directory at `https://coveragecat.com/.well-known/http-message-signatures-directory`. Before you use live customer data, rehearse the flow in the sandbox docs at `https://coveragecat.com/developers/sandbox`. Coverage Cat also exposes a browser sandbox at `https://coveragecat.com/intake?ltp=owned_homes&sandbox=homeowners`, a delegated-homeowners API sandbox using `sandbox: true` only on the first create call for that `uid`, and a delegated-umbrella API sandbox using `sandbox: true` only on the first draft call for that `uid`.

## Errors

Expect OAuth-style `invalid_request`, `unsupported_grant_type`, `authorization_pending`, `slow_down`, and `invalid_grant` responses from `https://coveragecat.com/oauth2/token`. The polling endpoint at `https://coveragecat.com/agent/identity/claim` may return `429 rate_limited` if you ignore the published poll interval. Protected API requests still return `401` plus `WWW-Authenticate` metadata hints when the bearer token is missing, expired, revoked, or malformed, and protected MCP tools return `_meta["mcp/www_authenticate"]` challenges with the same metadata hint. Legacy OTP claim failures return structured JSON such as `invalid_otp`, `otp_expired`, or `invalid_claim_token`. Coverage Cat does not currently accept third-party `id-jag` assertions from agent providers; the supported `id-jag` path is the service-signed assertion returned from a successful user claim.

## Revocation

Revoke OAuth access tokens at `https://coveragecat.com/oauth2/revoke` by POSTing the token to `/oauth2/revoke`. Legacy operator credentials can still be revoked at `revocation_uri` `https://coveragecat.com/agent/auth/revoke` with the current bearer credential. Revoking an operator credential invalidates every access token and API key currently tied to that operator, while `/oauth2/revoke` only revokes the single access token you submit.
