Waysafe

Concepts

Four objects, in the order they come into existence. Skip this if you just ran the quickstart above — you already saw all four.

Waysafe sits between the principal who signs a policy and the two payment rails that settle: Stripe asks it before any card charge, and the Safe cannot settle on one signature, so both rails reach the merchant only through a decision Waysafe made. The agent's own call to Waysafe is a preflight, never a control.
Who holds which key, and who asks whom.
Anything an agent asserts -- a merchant name, a PSP account id, a payee address, which resource URL to fetch -- caps at STEP_UP rather than producing ALLOW, and the asset decimals a merchant declares are overridden by Waysafe's own registry. Neither an agent nor a merchant can forge an evidence signature, raise a limit, or turn its own STEP_UP into an ALLOW.
What each party can assert, and what that assertion cannot produce. The rule behind every row: trust comes from who attested an identifier, never from which field it arrived in.

Mandate. A stable handle: which principal, and a lifecycle status (PENDING_AUTHENTICATION, ACTIVE, EXPIRED, REVOKED, SUPERSEDED). It carries no policy of its own.

Mandate version. The actual policy — immutable once written: the compiled policy, the original instruction text, a SHA-256 policy_hash, and the agents it delegates to. A Mandate points at one current version. Authenticated once by the principal over WebAuthn; editing writes a new version rather than mutating this one, so an authorization can always cite the exact bytes it was decided against, even after the mandate changes.

Authorization. One decision: evaluate() run against a specific mandate version’s policy for one proposed action, at one instant. Cites that mandate_version_id and policy_hash directly. Always exactly one of ALLOW, DENY, or STEP_UP.

Evidence entry. One append-only, hash-chained, signed log row recording that something happened — a mandate version authenticated, a decision made. Real example, from the same captured run /proof publishes:

{
  "id": "ev_01m2rbex48kg49n1tesy6cthj6",
  "organization_id": "org_demo",
  "sequence": 437,
  "type": "mandate.authenticated",
  "subject_type": "mandate_version",
  "subject_id": "mdv_01m2rbett9gnyx44a57em5a0m1",
  "payload": {
    "credential_id": "96_4u4fbOvNGwqGETE-zxQ"
  },
  "previous_hash": "1079aeb64b183e80f8f4de2aae2fdcfc6f794bd488ce5715de5cafb10af6e2b0",
  "hash": "a05e6b17b940b0917ed961445af26d361a4d83be87a3763e641c6cef1526d3de",
  "signature": "8s1fD073/4FVs+H496IrUTij6SiAEGVt6gTBflp8KxPAOrDxXogeDqPMaiUv8RNKoJ0W6Pv0PNDBrs5IMqqBCw==",
  "key_id": "2a71ea6ee10e66a5",
  "created_at": "2026-09-17T18:53:26.528Z"
}