Five gates. One receipt.
Pick the action your auditor will ask about first. Each gate below produces the same signed evidence: the Decision Brief the signer saw, and the receipt that records the decision.
Hiring to build this? Read build-or-buy.
What every receipt proves. Ed25519 signature over: action payload hash · agent ID · named approver · APPROVE or DENY · timestamp · Decision Brief. Verifiable by anyone at /r/{id}. Tampering withholds the approver. Denials are signed too.
Gate 01 · Money out
Which human approved this refund, before the money moved?
Today: Under the threshold, nobody. Over it, a Slack thread that can't be found by the time the auditor asks.
Choke point: Stripe refunds.create / transfers.create / payouts.create; AP release in NetSuite or Bill.com. The call fires only on a signed APPROVE.
You are authorizing a $4,800.00 refund on ch_3Nq8… from agent cx-refunds.
stripe · requested by agent cx-refunds (session 3f9a) · 2m ago · payload sha256 7c1e…9b02 · expires in 14m
Auto-approve limit is $500. Approving moves 9.6× that without a second check.
Approving refunds without a fraud review.
Decision Brief
Risk: elevatedFunds leave the balance and the refund is irreversible; the agent is acting on a customer-supplied claim it cannot verify.
- 1Charge ch_3Nq8… exists and the amount matches ticket #48213.
- 2The refund reason matches the ticket text, not the customer's message.
- 3No prior refund exists on this charge.
Signing as [email protected]
This approval is permanent and auditable
Receipt & controls
What gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgWhat gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgEvery in-scope transaction carries a valid signed receipt in your own ledger. Zero orphans.
Pilot this gateGate 02 · Agent code → prod
Was the SHA that shipped the one a human reviewed?
Today: A PR approve click that doesn't survive a force-push. Nobody at deploy time.
Choke point: Merge to main or the deploy job: GitHub environment reviewer step, merge-queue check, or MCP Guard on the git/deploy tool. Deploy runs only against a signed SHA.
You are authorizing a production deploy of acme/api at commit a891b24.
github · requested by agent codex-bot via PR #512 · 41m ago · commit a891b24 · checks 14/14 passed · expires in 21h
Approving signs a SHA no human has reviewed.
Approving signs a production change with no stated intent.
Decision Brief
Risk: elevatedProduction deploy capability + agent-authored diff + a review that isn't bound to the final SHA.
- 1The diff at a891b24 matches the PR description.
- 2Migration files, if any, are reversible.
- 3Checks are green on this SHA, not a prior one.
Signing as [email protected]
This approval is permanent and auditable
Receipt & controls
What gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgWhat gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgEvery in-scope deploy references a signed receipt naming the approver and the exact SHA that shipped. Zero mismatches.
Pilot this gateGate 03 · Prod infra mutations
Who approved this change, and can you prove nothing went out-of-band?
Today: Plan pasted in a PR or Slack, SRE thumbs-up. IAM via console: nobody. Feature flags: nobody.
Choke point: terraform apply (Atlantis/Spacelift approval hook) · IAM policy write · DNS record write · flag-flip API · migration runner. Gated on plan hash or policy diff.
You are authorizing terraform apply on prod-us-east-1 (plan 3d9f…) from agent sre-agent.
spacelift · requested by agent sre-agent (run 8812) · 5m ago · plan sha256 3d9f…e1a4 · 2 to add, 1 to change, 1 to destroy · expires in 30m
Approving deletes a production resource.
Approving grants the agent broader access than the task needs.
Decision Brief
Risk: elevatedIrreversible destruction and privilege widening in one plan; the agent cannot assess blast radius.
- 1The destroy is intended: ticket or incident reference present.
- 2The IAM diff is the minimum scope for the task.
- 3The plan hash matches what CI rendered, not a re-plan.
Signing as [email protected]
This approval is permanent and auditable
Receipt & controls
What gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgWhat gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgEvery in-scope change matches the plan hash a person approved, receipt attached. Zero out-of-band applies.
Pilot this gateGate 04 · PII/PHI export
Who approved this export, for what purpose, and where's the minimum-necessary determination?
Today: An email ticket at best. The agent's database credentials don't ask.
Choke point: Export endpoint or bulk query: warehouse unload, EHR release-of-information API, presigned S3 URL generation. Gated on record scope + fields + recipient + purpose.
You are authorizing an export of 12,400 patient records (7 fields) to vendor-analytics from agent ops-reporter.
warehouse · requested by agent ops-reporter (job 2201) · 8m ago · query sha256 a07c…44d1 · recipient vendor-analytics · expires in 1h
Approving exports direct identifiers, not a de-identified set.
Approving sends PHI to a party without a signed agreement.
Decision Brief
Risk: elevatedDirect identifiers leaving the boundary to a third party; the agent has not established minimum-necessary.
- 1The purpose on this brief matches an approved use.
- 2The field list is the minimum for that purpose.
- 3The recipient has a signed BAA or DPA on file.
Signing as [email protected]
This approval is permanent and auditable
Receipt & controls
What gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgWhat gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgEvery export carries a signed receipt naming the approver and the purpose. Who approved export X is answered in minutes.
Pilot this gateGate 05 · Identity changes
Who approved this account change, and was it someone other than whoever asked for it?
Today: Tier-2 via Slack escalation. Often nobody: the agent holds an admin key.
Choke point: Password/MFA reset, email change, ownership transfer, role grant, KYC override: PATCH /users/:id, Okta/Entra admin API, internal admin tool.
You are authorizing an MFA reset for [email protected], requested by agent support-agent.
okta · requested by agent support-agent (ticket #9931) · 1m ago · target m.alvarez · payload sha256 51b0…c7d3 · expires in 10m
Approving resets MFA at a third party's request.
Approving repeats a change that was already granted or denied today.
Decision Brief
Risk: elevatedAccount-takeover surface; the agent is acting on unverified identity claims from a support conversation.
- 1Out-of-band identity check completed: callback to the number on file.
- 2You are not the requester.
- 3No open fraud flag on the account.
Signing as [email protected]
This approval is permanent and auditable
Receipt & controls
What gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgWhat gets signed
receiptIdtenantIdagentIdtooloperationinputHashdecisionreasonCodesapproverpolicyVersioncreatedAtreceiptSigsigAlgEvery privileged change carries a signed receipt, and the approver is never the requester. Zero exceptions.
Pilot this gateNot one of these five?
Every gate is the same wrapper at a different choke point.