Listing is opt-in. The protocol does not require it. See The service directory for what a listing does and doesn’t mean.
Before you start
You need:- A live AFAuth discovery document at
https://your-host/.well-known/afauth. If you don’t have one yet, see the /.well-known/afauth reference. - The ability to publish a file at
https://your-host/.well-known/afauth-registry-proof(a single short text file). - A
service_diddeclared in your discovery document.did:web:your-hostis the recommended form (and is the only form that carries a DNS anchor;did:keyis also accepted but is rendered with a “no domain anchor” indicator on browse interfaces).
The four steps
Request a challenge
Ask the directory for a one-time challenge token bound to your discovery host:Response:The challenge is single-use and expires in 30 minutes.
The token format is
ch_ followed by 22 url-safe-base64 characters
(128 bits of entropy). Treat it as opaque — don’t try to parse it.Publish the challenge token at the proof URL
Make Verify locally before submitting:The body must equal the
proof_url respond with HTTP 200, Content-Type: text/plain, and the bare challenge token as the body. No surrounding JSON, no quotes, no trailing newline.challenge_token byte-for-byte.Submit the listing
Tell the directory you’ve published the proof. It will fetch Session tokens are bearer credentials and expire in 7 days. Treat them like API keys — secret, short-lived, scoped to a single listing.You can now remove the proof file from
proof_url, fetch your discovery document, validate both, and create the listing:title, description, and tags are optional and shown on the browse page.On success you get a session token scoped to your service_did:/.well-known/afauth-registry-proof if you want; the directory does not re-fetch it except when you re-challenge.What if I lose the session token?
Repeat steps 1–3 with the samediscovery_url. The directory recognises that a listing already exists for that DID, revokes all prior session tokens, and issues you a fresh one.
The recovery path is identical to the initial flow: regaining host control regains the listing. This is the §4.3 re-challenge path.
What if someone hostile gets host control?
If your discovery host is compromised and the attacker submits a hostile listing, the same recovery mechanism works the moment you regain control. Re-challenge from the recovered host, and all prior sessions are revoked — including the attacker’s. The directory’s authority model is exactly the host’s authority. There is no second account, no recovery email, no support channel that can override host control.How the directory keeps your listing fresh
By default, the directory re-fetches your discovery document once a day. After three consecutive revalidation failures (i.e., three days in a row at the default cadence), the listing transitions tostale status. Stale listings remain visible (with status: "stale") for 30 days before being soft-deleted. A successful fetch at any point resets the failure counter.
You don’t need to do anything — just keep /.well-known/afauth reachable and valid. If you take it down deliberately, use DELETE to soft-delete; the stale-then-deleted path is for unintended outages.
See §7 revalidation for the full state machine.
Rate limits
The directory enforces some abuse limits per IP, listed in the API reference. For ordinary registration and management, you won’t notice them. They only kick in if something is trying to spam the directory.Errors you might hit
| Code | Meaning | Fix |
|---|---|---|
invalid_challenge | Challenge expired (>30 min old) or already used | Request a fresh challenge. |
proof_fetch_failed | The directory couldn’t reach proof_url | Check the URL is publicly reachable over HTTPS; check your firewall. |
proof_mismatch | The body at proof_url does not equal the token | Ensure the file contains only the token — no surrounding whitespace, JSON, or HTML. |
discovery_fetch_failed | The directory couldn’t reach your discovery URL | Same as above, applied to /.well-known/afauth. |
discovery_invalid | Your discovery document failed schema validation | See schemas/well-known.json. |
discovery_did_mismatch | Your discovery document’s service_did (a did:web:host) does not match the discovery host | Either correct the DID, or move discovery to the host the DID names. |
conflict | A different listing already claims this host or DID | If it’s a stale entry of yours, re-challenge to take it back; otherwise contact the operator. |
Where to next
API reference
All endpoints, request and response shapes, query parameters.
What the directory is
Background, governance, federation, identity model.