DEV Community

Gautam K
Gautam K

Posted on

How do you prove a human approved what your AI agent did?

AI agents are starting to do things that are hard to undo: send emails, issue refunds, merge code, change customer data. Most setups I've seen put a human approval step in front of the risky ones.

I'm trying to understand how teams actually handle the approval part today, so I'd love to hear real setups, including the messy ones:

  1. What does the approval step look like for you? A Slack button, a PR review, a confirm dialog, nothing?
  2. What does the person approving actually see before they say yes? The full action, a summary, just the tool name?
  3. Where does the record of that yes live, and who can read it later?
  4. Has a customer, auditor or insurer ever asked you to prove a human signed off on something an AI did? What did you hand them?
  5. When an agent did something nobody meant it to, how did you find out who had approved it?

Even "we don't track this at all" is a useful answer. I'll summarise what people share in a follow-up post.

Top comments (6)

Collapse
 
ontomato profile image
ontomato •

The yes has to be on the exact payload, not a summary of it.

If the approver only sees "issue a refund" or a one-line recap, you can't later show they signed off on this customer, this amount, and this destination. I'd store that signed payload, then read the system of record back and check the landed row still matches. A green tool result is not that check.

Collapse
 
gautamtalksdev profile image
Gautam K •

Agreed, a recap is not a yes on this customer, this amount and this destination. One case I'd like your view on: the landed row matches the signed payload, but the call was retried and the refund landed twice. Should the read back check count as well as content, or does that belong to an idempotency key on the call itself?

Collapse
 
lakhyajit profile image
Lakhyajit Changmai •

I’d want the approval record bound to a canonical action payload plus approver identity, timestamp, and policy/version context. Execution should reference that approval ID, and a read-back can confirm the resulting state matches. That makes approval auditable without treating the tool’s success response as proof.

Collapse
 
gautamtalksdev profile image
Gautam K •

Binding the yes to a canonical payload plus the policy version is the part most setups skip. Without the version you can't say which rule decided that a yes was needed in the first place, and the read back gives you a second leg that doesn't depend on the tool's own success message.

How do you canonicalise the payload when the tool accepts the same action in more than one shape, for example an amount as a string or a number, or fields in a different order?

Collapse
 
mickyarun profile image
arun rajkumar •

Taking your questions from payments rather than from agents, because this is a solved problem there and the solution is not the part people copy.

What the approver sees is the whole thing. A Slack button reading "Approve refund for order 4417?" records a click, not an approval. Six weeks later nobody can reconstruct what was on the card when the thumb came down, and if that message was rendered from a template over live data, the data has moved since. So the record has to carry the rendered content, not a reference to it.

Payments has a name for the fix: dynamic linking. PSD2 requires the authentication to be bound to the amount and the payee that were shown to the payer. Change either one and the code is void. The mechanism is less interesting than the direction it runs in. You cannot later claim approval of something that was not on screen, because the approval does not verify against it.

On where the yes lives, the test I would apply is who wrote the record. If the agent's own log says a human approved, that is the agent attesting on its own behalf. A card authorisation is evidence because it is issued by the party that could have declined, and the record is a by-product of the decision rather than a description of it. Inside one process there is nobody who can refuse. I do not have a good answer for that, and I have stopped pretending the logging layer supplies one.

On auditors: yes, and what they asked for was not the approvals. They wanted the actions that went out without one, and the rule that was meant to have caught them. The approved set is easy to produce and nobody is interested in it. The gap is the finding.

One request on your follow-up. When you summarise, separate the teams who can produce the record from the teams who can produce the gap. My guess is that the second group is much smaller, and that the difference is not tooling.

I wrote the narrow version of this up last week, on the distance between what an agent logged doing and what it meant to do: dev.to/mickyarun/your-agent-logs-w...

Collapse
 
gautamtalksdev profile image
Gautam K •

The point about who wrote the record is the sharpest part of this. An agent saying a human approved is the agent vouching for itself, and inside one process nobody could have refused. Your auditors story fits too: the approved set is easy to produce, and the actions that left without one are the finding.

When you found those gaps, were they mostly actions the rule never classified as needing approval, or approvals that existed but were bound to a different payload than the one that ran?