skip to content

Production checklist

A v1.2 readiness checklist for HTTPS, terms lifecycle, keys, receipts, authenticated abuse, logging, verification and incident response.

awaiting reviewupdated view markdown ->
for humans

Use this before you take live traffic and again after any change to keys, terms or account handling. It is a checklist, not a second specification; each item links to the rule or the guide.

Transport and discovery

  • GET /.well-known/agent-signup.json returns 200, application/json, no redirect and no authentication.
  • The origin is HTTPS. localhost is development only.
  • Cache-Control is public, max-age=60 or another value within the 300-second maximum.
  • Access-Control-Allow-Origin: * is set where browser inspectors need it.
  • The body is under 1 MiB and contains no secrets, internal hostnames or personal data.
  • Unsupported deployments return 404 or 410, not 401 or 403.
  • issuer_allowlist contains exact origins with no path, query, fragment or wildcard.
  • The validator passes in CI or in a documented manual step.

Terms lifecycle

  • terms.text is the complete agreement the agent accepts, not a summary.
  • terms.sha256 is over the exact UTF-8 bytes and was recomputed after the last edit.
  • terms.version changes whenever the text changes materially.
  • terms.url serves the same text to a human and is on a stable host.
  • Text, hash, version and URL ship atomically.
  • Any grace period for in-flight assertions is bounded and documented outside discovery.
  • A stale hash returns 409 tos_hash_mismatch; it is never accepted silently.

Assertion verification

  • Signature verification uses the issuer's /.well-known/jwks.json, not a jku/x5u header.
  • alg is EdDSA, the kid selects the key and typ is agent-id+jwt.
  • iss is compared against the allowlist exactly.
  • aud is compared against the published audience.
  • exp is enforced with at most 60 seconds of clock skew.
  • Assertion lifetime is capped at five minutes.
  • delegation.scopes covers every required_scopes entry.
  • human.verified is true.
  • delegation.accepted_rp_tos_hash equals the current terms hash.
  • A repeated jti in the same context resolves; a conflicting one is assertion_replayed.

Keys, attestation and rotation

  • You know that the receipt is signed by your RP key, named by service.key_id and present in the exact attestation. The broker does not sign v1.2 receipts.
  • The RP private key is in a secret store, never in the repository, logs or a build artifact. It has an owner, a rotation date and a compromise procedure.
  • The attestation is renewed on a 12-hour target against a 24-hour expiry with 60-second skew. Serve the cached attestation until exp; omit it after expiry (the provider becomes unverified, not invalid).
  • The exact attestation that contained the receipt key is retained for every receipt, and Contract F receives that exact JWS. Never substitute the current attestation.
  • Key rotation uses the 30-day overlap; revocation removes the key from new attestations while old receipts remain verifiable through the snapshot.
  • /.well-known/agent-broker.json metadata and the signed attestation_status_uri are implemented if you operate a broker; caching is at most 1 hour for metadata and 5 minutes for status.
  • If you claim verification in the registry, the entry records broker, level, attestation_jti, checked_at, and status:"active" from a live check. The badge is a snapshot; only active gets it.

Accounts, replay and credentials

  • Account keys follow (iss, human.id) or (iss, agent.id) and are namespaced by issuer.
  • A jti can be used for one account creation only; a unique constraint backs the check.
  • A resolve returns no credential and sends no duplicate welcome or legal mail.
  • Credentials are returned only on creation and are never stored in the receipt, logs or broker.
  • A credential recovery path exists in the context guide.
  • Rate limits protect signup and return 429 rate_limited with an honest delay.

Receipts and Contract F

  • The receipt header is alg: EdDSA, typ: agent-signup-receipt+jwt, and kid equals service.key_id.
  • The payload has no exp; iat and signed_up_at fall inside the named attestation's [iat, exp] window.
  • iss equals service.origin and the attestation rp.origin; aud is the broker issuer.
  • service.attestation_jti names the exact attestation that contained the key; service.audience equals the attestation rp.audience.
  • Contract F sends {signup_token, rp_attestation} with both fields; Tier 2 is the fallback. A missing exact attestation returns attestation_unavailable; a transient outage is retryable rp_broker_unavailable.
  • A duplicate jti with the same body dedupes; a different body is signup_conflict. A different account for the same soft key is flagged, not overwritten.
  • A self-report is only used for an RP that issued no receipt and is visibly weaker (agent_self_reported).

Logging and retention

  • Logs record the assertion jti, agent.id, human.id, account id, terms version and hash, and signed_up_at.
  • Logs do not record provider credentials, raw assertions beyond the audit window, or unnecessary personal data.
  • Error monitoring groups by stable code, not by prose.
  • Retention is documented and follows your legal obligations.
  • A request id or trace id links the agent request to the account event.

Context and abuse

  • context.url stays on the signup endpoint's registrable domain.
  • context.sha256 matches the bytes served and is updated in the same deploy as the guide.
  • The guide contains no credentials and no protocol fields.
  • The broker is never asked to fetch the guide.
  • Abuse reporting uses {rp_attestation, report} with a five-minute JWS and a current attestation. The legacy {agent_id, reporter_service, reason} body is gone.
  • You understand that a verified, receipt-linked report may apply a protective suspension pending review; an unverified report opens a case and does not suspend.
  • A human report about a provider uses the portal path, not D.2.

Abuse, support and incidents

  • contact in discovery is monitored and reaches a human.
  • The abuse reporting path is tested with a synthetic signed report and the exact current attestation.
  • Support knows the difference between a protocol error, a broker error and a vendor API error.
  • An incident plan covers: disable signup, rotate keys or revoke the attestation, invalidate credentials, contact the broker, update the registry.
  • The provider does not retaliate automatically against an agent; revocation and account action are separate decisions.
  • Known limits are stated to customers: human.verified is email verification, verification is identity not safety, revocation does not delete your account, and the protocol does not prevent abuse.

Test plan

  • A staging discovery URL exists and is not in the registry.
  • Synthetic assertions cover every row in Verify assertions.
  • The optional credential is tested absent, valid domain, valid entity, expired, invalid, untrusted, and unavailable.
  • A create and a resolve are both exercised, including the no-credential rule.
  • The validator runs against staging before release, once without and once with --require-attestation.
  • Contract F is exercised with the exact historical attestation and with a renewed current attestation (must not substitute).
  • A terms change is rehearsed end to end, including tos_hash_mismatch.
  • A guide change is rehearsed, including the hash update.

Next

sections

type to search.

up/down navigateenter selectesc close