# Agent authentication for kwnva.design


kwnva.design is a public portfolio. Read endpoints do not require a credential. Write endpoints (inquiries, sandbox echoes) accept an optional bearer token so agents that already speak OAuth can attach one. This page is the WorkOS-style auth.md walkthrough.

## Discover

Start at the protected-resource metadata:

- RFC 9728: https://kwnva.design/.well-known/oauth-protected-resource
- RFC 8414: https://kwnva.design/.well-known/oauth-authorization-server
- OpenAPI: https://kwnva.design/openapi.json
- skill: this file

The authorization server advertises an `agent_auth` block. `register_uri` is https://kwnva.design/oauth/register. `identity_types_supported` is `anonymous` and `identity_assertion`. A missing or stale token on a write call returns `401` with `WWW-Authenticate: Bearer resource_metadata="https://kwnva.design/.well-known/oauth-protected-resource"`.

## Pick a method

1. **Anonymous (recommended).** Register a public client and request a client-credentials token. No user is in the loop.
2. **identity_assertion.** If you already hold a verified email assertion or an ID-JAG (`urn:ietf:params:oauth:token-type:id-jag`), exchange it at the claim endpoint.

Most agents should pick anonymous. The catalog is public; the token only exists so retries and writes can be attributed.

## Register

`register_uri`: `POST https://kwnva.design/oauth/register`

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

{ "client_name": "your-agent", "token_endpoint_auth_method": "none" }
```

The response is an RFC 7591 client: `client_id`, `client_id_issued_at`, and `grant_types`. PKCE `S256` is advertised for any authorization-code attempt; the studio does not require a confidential client secret.

## Claim

`claim_uri`: `POST https://kwnva.design/oauth/token`

Anonymous clients use `grant_type=client_credentials`. Identity-assertion clients can `POST https://kwnva.design/oauth/claim` with the assertion. Both return a bearer access token and a scope string (`catalog:read inquiries:write sandbox:write`).

## Use the credential

`Authorization: Bearer <token>`

Attach it to `POST /api/v1/inquiries` or any `/api/v1/sandbox/*` write. `GET /api/v1/projects` works without it. Send `Idempotency-Key` on writes.

## Errors

Failed auth is JSON (`application/problem+json`) plus the `WWW-Authenticate` hint. `invalid_client`, `invalid_grant`, and `invalid_token` are the codes to handle. A 429 includes `Retry-After` and RFC `RateLimit` headers.

## Revocation

`revocation_uri`: `POST https://kwnva.design/oauth/revoke`

Send `token` to drop a bearer. OPTIONS preflight on register, token, claim, and revoke is supported so browsers and agents can probe reachability without a 404.
