# Authentication for agents — Kilnwood

This document explains how an AI agent obtains and uses credentials with Kilnwood (`https://market-share-joy.lovable.app`). It follows the agent_auth discovery convention.

## Discover

Start at the protected-resource metadata:

- `https://market-share-joy.lovable.app/.well-known/oauth-protected-resource`

It names the resource, the authorization server, the supported scopes and the accepted bearer method. Machine-readable capability discovery also lives in [/llms.txt](/llms.txt), [/openapi.json](/openapi.json) and [/.well-known/ai-catalog.json](/.well-known/ai-catalog.json).

## Pick a method

Kilnwood has two access tiers:

1. **Anonymous (recommended for agents).** All read endpoints under `/api/public/v1/*` are open. No credential, no registration, no identity_assertion required. Use this for browsing, searching and reading listings.
2. **User-delegated bearer token.** Writing (creating, updating or deleting a listing) happens on behalf of a human account and requires a bearer access token issued by the authorization server listed in the protected-resource metadata.

## Register

There is no agent client registration endpoint for read access — skip registration and call the public API directly. For delegated write access, the human account holder registers by creating an account at `https://market-share-joy.lovable.app/auth` (email + password, or Google). Agents cannot self-register accounts.

## Claim

To claim a delegated credential, direct the human to sign in at `https://market-share-joy.lovable.app/auth`. After sign-in, the browser session holds a JWT access token issued by the authorization server. Agents must never ask a user to paste a password; only an issued access token may be handed to an agent.

## Use the credential

Public reads need nothing:

```
curl https://market-share-joy.lovable.app/api/public/v1/listings?limit=5
```

Delegated calls send the token in the standard bearer header:

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

Tokens are short-lived JWTs. Never place a token in a query string or a log line.

## Errors

All API errors return JSON with a stable machine-readable shape and the matching HTTP status:

```json
{ "error": { "code": "not_found", "message": "No listing with that id.", "hint": "List ids via GET /api/public/v1/listings." } }
```

Common codes: `bad_request` (400), `unauthorized` (401), `forbidden` (403), `not_found` (404), `rate_limited` (429), `internal_error` (500). A 401 response carries `WWW-Authenticate: Bearer resource_metadata="https://market-share-joy.lovable.app/.well-known/oauth-protected-resource"`.

## Revocation

A user revokes agent access by signing out of Kilnwood, which invalidates the refresh token, or by deleting their account. Access tokens expire on their own within one hour; there is no long-lived agent key to rotate.

## Sandbox

Append `?sandbox=true` to any `/api/public/v1/*` read endpoint to receive deterministic fixture data instead of live rows. Sandbox responses never touch production data and are safe to exercise freely.
