# TempoWeb auth.md

Authenticated agents can save and retrieve their own draft project briefs for human review. The public catalog and /mcp remain anonymous and read-only.

## Scope and consent

Ask the person before registering and storing their brief. Do not upload passwords, payment details, special-category personal data or confidential customer records. An anonymous registration is an isolated temporary agent identity, not a TempoWeb customer account. Its credentials cannot access Supabase, dashboards, customer projects, messages, bookings or payments.

Scopes: briefs:read, briefs:create. Each registration can create at most 10 immutable drafts, with a 120-character title, en/nl/ar locale and up to 6,000 characters of plain text. Drafts become inaccessible after 7 days and are removed by daily cleanup (within the following 24 hours). Registrations and credentials expire after 24 hours; access tokens last at most 15 minutes. Human claiming does not expand agent permissions or extend this lifetime.

## Discover

- Protected resource: https://tempowebstudio.nl/.well-known/oauth-protected-resource
- Authorization server: https://tempowebstudio.nl/.well-known/oauth-authorization-server
- Public signing keys: https://tempowebstudio.nl/.well-known/agent-jwks.json
- Resource audience: https://tempowebstudio.nl
- Draft API base: https://tempowebstudio.nl/api/agents/v1
- OpenAPI: https://tempowebstudio.nl/agents-openapi.json

## Register

POST https://tempowebstudio.nl/agent/identity with Content-Type: application/json and body {"type":"anonymous"}. Only anonymous registration is supported; provider assertions, email assertions and automatic customer signup are not supported.

A 201 response contains registration_id, a signed identity_assertion, its expiry and a claim_token. Keep these secrets private and out of URLs and logs. Registration allows 5 requests per IP per hour across application instances.

## Obtain and use credentials

POST https://tempowebstudio.nl/oauth2/token as application/x-www-form-urlencoded with grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer, assertion=<identity_assertion>, and resource=https://tempowebstudio.nl. The optional scope must exactly match "briefs:read briefs:create". The response contains access_token, token_type Bearer, expires_in and scope. Re-exchange the assertion until its fixed expiry to obtain a fresh token; no refresh_token is issued. Do not use identity assertions as API access tokens.

Use Authorization: Bearer <access_token> with:

- POST https://tempowebstudio.nl/api/agents/v1/briefs — JSON {"request_id":"<fresh UUID>","title":"Project brief","locale":"en","content":"User-reviewed requirements"}. Reuse the same request_id and identical body on a retry. Conflicting retries return 409. A draft is never submitted to the studio automatically.
- GET https://tempowebstudio.nl/api/agents/v1/briefs — list this registration's drafts.
- GET https://tempowebstudio.nl/api/agents/v1/briefs/<id> — retrieve one owned draft. Another registration cannot retrieve it.

Missing, expired or revoked access returns 401 with a protected-resource discovery challenge. Invalid input returns 400; oversized requests 413; rate limiting 429 with Retry-After; temporary dependency failure 503. Requests are limited to 16 KiB. Token exchanges allow 30/minute/IP; draft API calls allow 60/minute/IP across instances. These APIs are intended for server-side agents; cross-origin browser calls are rejected.

## Human review and claiming

POST https://tempowebstudio.nl/agent/identity/claim with JSON {"claim_token":"<secret>"}. The response contains claim.user_code, claim.verification_uri, expires_in and interval. Show the user both the URL and six-digit code. They open it, sign in through the normal TempoWeb login, manually enter the code and explicitly approve the connection. Never complete this step on their behalf. The link expires in 10 minutes; 5 wrong code attempts invalidate it. Starting a new attempt replaces the previous one.

The verification link uses a URL fragment so the attempt secret is not sent in requests or referrers. Do not strip the fragment. The user can sign in in a separate tab and then return to the approval page.

While waiting, POST https://tempowebstudio.nl/oauth2/token with grant_type=urn:workos:agent-auth:grant-type:claim, claim_token=<secret>, and resource=https://tempowebstudio.nl. Poll no faster than once per 5 seconds. Handle authorization_pending, slow_down and expired_token. A successful poll returns an access token and identity assertion for the same isolated registration. No customer data scopes are added.

The signed-in owner reviews claimed briefs and revokes connections at https://tempowebstudio.nl/agents/briefs. The person can copy a draft into the existing contact flow; only their explicit submission sends an enquiry. No payment, booking or account-creation tool is provided.

## Revocation

POST https://tempowebstudio.nl/oauth2/revoke as application/x-www-form-urlencoded with token=<access_token>&token_type_hint=access_token. This revokes the entire associated agent registration, including its assertions and other tokens; it is deliberately broader than a single-token revoke. Unknown or already expired tokens return 200 without revealing identity information. A human can revoke a claimed connection independently through the review page. Previously stored drafts remain available to their human owner until retention expiry.

## Protocol details

The authorization server implements the RFC 7523 JWT-bearer grant and the auth.md claim grant. It does not implement OpenID Connect, authorization-code, implicit or dynamic OAuth-client registration. Current agent_auth identity_endpoint/claim_endpoint and compatibility register_uri/claim_uri identify the same functioning endpoints. Only advertised flows are supported. OAuth issuer and audience checks, typed ES256 signatures and live revocation checks isolate these credentials from ordinary TempoWeb login sessions.
