Skip to main content
Which attestor an agent should use is the service’s call, not the agent’s: a service lists the issuers it trusts in its discovery document’s billing.accepted_attestors. Most services accept afauth-trust, so the default just works. But a service may instead (or also) accept a private enterprise attestor or an alternative public one — and your agent can link to it and present the right token.
You only need this when a target service lists an attestor other than afauth-trust — or when you run your own. If every service you use accepts afauth-trust, the default link flow is all you need.

How the agent picks an attestor

An agent can hold bindings to several attestors at once. When it signs up to a service, it picks the binding whose issuer (iss) is in that service’s accepted_attestors:
  • Exactly one of your bindings matches → it’s used automatically.
  • Several match (or the service names none) → you disambiguate with --attestor.
  • None match → you get a local error naming the attestors the service does accept, before any request is sent — so you re-link instead of debugging an opaque server rejection.
That last point is the whole reason to reconcile on the agent side: a token from an unaccepted issuer would just be rejected by the service with a generic 401. The agent catches it first.

With the CLI

1

Link to the attestor the service accepts

Point afauth trust link at the attestor’s base URL. This adds a binding; it doesn’t replace an existing one, so you can keep afauth-trust and a private attestor side by side.
afauth trust status lists each binding with its attestor identifier, base URL, and expiry.
2

Sign up — the accepted attestor is chosen for you

signup reads the service’s accepted_attestors and mints from the binding that matches. If more than one of your bindings qualifies, name the one to use (by issuer or base URL):
The same --attestor flag works on afauth trust token, and AFAUTH_TRUST_BASE selects a binding when no flag is given.
3

If you linked to the wrong attestor

You don’t have to guess. If none of your bindings is accepted, signup fails locally with the fix:
Re-link against an accepted attestor (or run your own and ask the service to add it), then retry. Drop a binding you no longer need with afauth trust forget --attestor <iss-or-url> (omit the flag to clear all).

With the TypeScript SDK

Point a TrustClient at the attestor’s base URL to mint from it, and pass the service’s accepted_attestors to AttestedFetcher so an unaccepted attestor fails locally instead of over the wire:
Minted tokens expose iss (TrustToken.iss); attestationIssuer(jwt) and assertAttestorAccepted(token, accepted) are exported if you want to reconcile outside AttestedFetcher. Omit acceptedAttestors to skip the check.

Where to next

Run your own attestor

Operate an attestor under your own iss for a fleet or as a public alternative.

The trust attestor

What afauth-trust is, and the federation model that allows alternatives.

Accept an attestor (service side)

The other half: declaring which attestors your service trusts.

afauth trust

link --base, status, token --attestor, forget --attestor.