Skip to main content
You’re going to make an AI agent sign itself up to a service that supports AFAuth. The agent generates its own Ed25519 keypair, derives a did:key identifier from it, signs an HTTP request per RFC 9421, and the service treats it as a first-class principal — with no human approving the signup.

Install

Make your first signed request

A few things just happened:
  • Agent.generate() made a fresh Ed25519 keypair and computed a did:key for the public half.
  • buildAccountIntrospection produced a fully signed request: covered components (@method, @target-uri), signature parameters (created, expires, nonce, keyid, alg), and the Ed25519 signature itself. See Signing requests.
  • The first signed request from an unrecognised DID triggers implicit signup on the service (§6.3). The account exists immediately in UNCLAIMED state.
The UNCLAIMED result above assumes a service in unclaimed_mode: "free". Services created with defineService default to attested_only (§9.2) — including the one from the service quickstart — and reject an un-attested request with 401 attestation_required, creating no account. The next step makes your agent acceptable to them.
Persist agent somewhere durable — the private key is the sole credential for pre-claim operations.
Services created with defineService default to unclaimed_mode: "attested_only" (§9.2) — the service from the service quickstart is one of them. They reject an un-attested signed request with 401 attestation_required and create no account. To be accepted, the agent presents a short-lived JWT from the canonical trust attestor at trust.afauth.org proving a verified human stands behind it — carrying no PII. You do this once per human/agent pair; the binding persists as long as the agent keeps minting (it lapses only after ~90 days of inactivity), and each per-service JWT is minted fresh.
The service verifies the JWT offline against trust.afauth.org/.well-known/jwks.json — no enrollment, no API key. If the target service advertises unclaimed_mode: "free", skip this step; the signed request alone suffices. Full walkthrough, error handling, and the afauth trust CLI shortcut: Link your agent to a human.

Invite a human to claim the account

When you want a human to own the account, the agent stages an invitation. The binding only commits after the human authenticates from the invited address — see The ceremony for why. This is a different human binding from the trust link above. Linking proves a human stands behind the agent so an attested_only service accepts its requests — ownership stays with the agent. Claiming hands ownership to a human and is always optional. The two are independent and can happen in either order.
The service sends a magic link to alice@example.com. After Alice clicks and authenticates, the account transitions to CLAIMED and the agent continues to operate it — but ownership-changing operations now require Alice’s session.

Next steps