Anatomy

The auth.md file

auth.md is a single Markdown file an application publishes at a well-known location to tell agents how to register. This page walks through where to host it, the sections it should contain, and how agents are expected to parse it.

Example

See the example auth.md for a complete template you can adapt.

Where to host it

Serve the file at your service root: https://service.com/auth.md. Agents discover it the same way humans do — by reading documentation, following SDK pointers, or by examining a WWW-Authenticate header you return on 401 responses. The structured Protected Resource Metadata (PRM) at /.well-known/oauth-protected-resource remains the authoritative source for endpoint URLs and supported flows; auth.md is the prose companion that points back at it.

Sections in order

A well-formed auth.md is organized as a numbered walkthrough an agent follows top to bottom. Here is what each section should cover:

Title and intro

A one-line title (# auth.md) followed by a short preamble addressed to the agent. State that the service supports agentic registration and name the real hostnames you'll use throughout the file — your resource server (the API base, e.g. https://api.yourservice.com) and your authorization server (where registration and claim live, e.g. https://auth.yourservice.com) — so the agent knows which host each example targets.

Discover

A two-hop discovery walkthrough. Show the agent how to:

  • Pull the PRM URL from the WWW-Authenticate: Bearer resource_metadata="…" header on a 401, or fall back to the conventional /.well-known/oauth-protected-resource path.
  • Fetch the Protected Resource Metadata and read resource, resource_name, authorization_servers, scopes_supported, and bearer_methods_supported.
  • Fetch the Authorization Server metadata at /.well-known/oauth-authorization-server and read the agent_auth block in full — skill, register_uri, claim_uri, revocation_uri, identity_types_supported, the per-type *_supported arrays, and events_supported.

Document every field. The agent uses these to decide what to call next.

Pick a method

A decision tree mapping what the agent has on hand to the right registration method:

  • An ID-JAG bound to this service's audience → identity_assertion + id-jag.
  • Only the user's email → identity_assertion + email (claim required).
  • Neither → anonymous (claim optional, deferred).

Tell the agent to cross-check its pick against the matching *_supported array in the agent_auth block before sending — if the service doesn't accept that shape, it should pick another or stop.

Register

One subsection per registration shape your service accepts. For each: show the exact POST /agent/auth body and the success response in full. Use fenced http and json code blocks so the agent can extract the templates directly.

  • identity_assertion + id-jag — completes immediately; the response carries credential, credential_expires, and scopes.
  • identity_assertion + email — returns a claim_token and post_claim_scopes but no credential; the service emails the user during this call.
  • anonymous — returns both a pre-claim credential and a claim_token so the agent can start working at reduced scopes.

Claim ceremony

The OTP ceremony, broken into three substeps:

  • 4a. Trigger the claim email — anonymous registrations only. POST /agent/auth/claim with the claim_token and the user's email. Email-verification registrations skip this step.
  • 4b. Wait for the OTP — describe what the agent should say to the user while waiting for them to read the code back.
  • 4c. Submit the OTPPOST /agent/auth/claim/complete with the claim_token and otp. For anonymous, the existing credential's scopes upgrade in place; for email-verification, a fresh credential is issued in the response.

Use the credential

Show that both access_token and api_key credentials are presented as Authorization: Bearer <credential>. Document refresh behavior per credential type (mint a fresh ID-JAG, re-run the ceremony, or rely on a non-expiring API key) and tell the agent to drop a credential and restart at Step 1 on any 401 from a previously-working credential.

Errors

A table mapping each error code to the endpoint that returns it and the action the agent should take. Cover invalid_signature, replay_detected, audience_mismatch, credential_expired, the *_not_enabled family, unsupported_credential_type, rate_limited, invalid_claim_token, otp_invalid, otp_expired, claim_expired, and previously_claimed.

Revocation

Spell out that the agent does not initiate revocation. Two paths:

  • Provider-driven (ID-JAG flows) — the provider that minted the ID-JAG POSTs a logout+jwt to the service's revocation_uri. The agent discovers the result on the next 401.
  • Email / anonymous flows — no agent-facing revoke endpoint; the agent detects revocation as a 401 and restarts at Step 1.

How agents parse it

Agents are expected to treat auth.md as both prose and structured data:

  • Scan headings to find sections relevant to the current step (registration vs. operation).
  • Read the Discovery section first to learn which flows are supported before committing to one.
  • Extract code blocks as templates for HTTP requests. Use fenced blocks with language hints (http, json) so the agent can identify request shapes without ambiguity.
  • Treat the PRM as authoritative if anything in this file conflicts with it. The PRM is the runtime source of truth.

Keep the file conservative in length and high in signal. Anything an agent doesn't need to register or operate against your API belongs in your main documentation, not in auth.md.