Skip to content

Agent mandates: proof of authority for agents that pay

Proof that a real person is behind an agent does not tell a merchant what that person allowed the agent to do. A mandate is that allowance, written down by the person themself:

  • the currency the agent may pay in,
  • the most it may pay in one payment and in total,
  • the merchants or payees it may pay,
  • how long the mandate lasts (up to 90 days),
  • optionally, an amount above which each payment waits for the person’s yes.

Before it pays, the agent asks Shield360. The payment goes through the same decision function as every other agent action, so the agent’s kill switch, its run context and the person’s own permissions apply first. An allowed payment comes back with a signed proof of authority that the merchant can check offline, or with one call to Shield360.

Mandates are part of the Security module. Open an agent at Govern → Agent access → Agent authorization and choose its Mandates tab.

ActionWho
Give a mandateThe signed-in person whose authority it is. Their role must let agents change things for them (agent_delegation.write), and the agent must be enrolled, with its token live and its kill switch off. The mandate is always theirs: it cannot name someone else.
Revoke a mandateThe person who gave it, or anyone who can manage agent authorization.
Approve or reject a waiting paymentThe person who gave the mandate, or anyone who can approve agent elevations.
See mandates and paymentsAnyone who can view agent authorization. Auditors see them and change nothing.

Pulling the agent’s kill switch revokes all its mandates. Payments waiting for approval lapse. Clearing the kill switch does not bring the mandates back.

If the person’s role later stops letting agents act for them, the agent’s payments under their mandates are refused (delegator_not_permitted).

The agent calls POST /api/agent-mandates/authorize with its own token:

Terminal window
curl -X POST "$SHIELD360_URL/api/agent-mandates/authorize" \
-H "Authorization: Bearer $SHIELD360_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "amountMinor": 1999, "currency": "USD", "counterparty": "shop.example.com", "reference": "order-42" }'
FieldMeaning
amountMinorA whole number in the currency’s minor units: 1999 is 19.99 USD, 500 is 500 JPY.
currencyISO 4217 code.
counterpartyThe merchant’s host name or a payee id. A mandate lists hosts (shop.example.com, or *.example.com for its subdomains) or payee ids.
referenceOptional. The merchant’s order or invoice reference, up to 128 characters. Kept with the payment.
mandateIdOptional. Use this mandate only. Otherwise Shield360 picks a live one that fits, preferring one that needs no approval, then the one expiring soonest.
paymentIdSet it only to make a payment a person has approved (see below).

The answer is always 200 with one shape:

outcomeWhat it means
allowPay. proof is the proof of authority and proofExpiresAt says when it stops being accepted (five minutes). The amount is already counted against the mandate.
needs_approvalThe payment is above the mandate’s approval amount. It waits in the agent’s Mandates tab under paymentId. Once a person approves it, ask again with the same amount, currency and counterparty plus paymentId, within 24 hours.
denyDo not pay. reason says why.
reasonWhy
mandate_grantedAllowed by a mandate.
mandate_noneNo live mandate: none was given, or each has expired or been revoked.
mandate_currencyNo live mandate covers this currency.
mandate_counterpartyNo live mandate lists this merchant or payee.
mandate_per_paymentMore than any live mandate allows in one payment.
mandate_exhaustedThe payment would take the mandate past its total.
mandate_approvalAbove the approval amount; waits for a person.
kill_switch, agent_revoked, run_context, delegator_not_permittedThe agent-wide rules, as for any other action.

The remaining amount is read, the decision made, the decision logged and the payment counted under the agent’s lock in one transaction. Two payments at once cannot both fit where only one does. If an allowed payment cannot be counted, it is denied (spend_unrecorded), never made off the books. Every answer is in the agent’s decision log under the Payments enforcement point.

The agent sends the proof to the merchant, for example in a Shield360-Mandate header. It is a compact JWS (RFC 7515) signed with EdDSA (Ed25519). Its header is { "alg": "EdDSA", "typ": "shield360-mandate+jwt", "kid": "…" } and its claims are:

ClaimMeaning
issYour Shield360 address.
subagent:<id>, the agent.
audThe counterparty it may pay.
jtiThe payment’s id. Accept each proof once.
iat, expIssued and expiry times (five minutes apart).
agentThe agent’s id and name.
principal{ ref, verified: true, kind: "organisation_member" }. The person whose mandate allowed it, as a one-way reference: stable per person, never their name or address.
mandateIts id, currency, per-payment limit and expiry.
paymentAmount in minor units, currency, counterparty and reference.
approvalWhether a person approved this payment, and who (a one-way reference).
decisionThe decision log id and the policy version it was decided under.

Offline. Read kid from the header and fetch the key once: GET /api/agent-mandates/keys?kid=<kid> returns { keys: [<JWK>] } and the PEM. Any JOSE library verifies the proof with it. Check exp, check that aud is your host or payee id, check that the amount matches the cart, and reject a jti you have already accepted.

Online. POST /api/agent-mandates/verify with { "proof": "…", "counterparty": "shop.example.com" }. It checks the signature, expiry and counterparty, then what an offline check cannot see: whether the payment is still authorized and the mandate has not been revoked since. The answer is { valid, reason?, claims, payment, mandate }.

Neither route needs an account. Each answers about one key or one proof and lists nothing. The signing key is the environment’s attestation key, which also signs AI-code attestations and provenance checkpoints. A rotated-out key stays published, so earlier proofs still verify.

To prove to any API or MCP server which agent is calling, not only to merchants it pays, see Agent passports.

  • It does not move money. The merchant’s own payment flow runs as before; the proof tells it the agent was authorized to decide.
  • It does not prove that a person is unique or human. Signals like that answer a different question and can sit alongside a mandate.
  • A refund does not give the amount back to the mandate yet. Give a new mandate if the total is used up.