Approve the Exact Payload: Hashing Actions So What Was Approved Is What Runs
A common gap in approval flows: a person approves an action, then something changes it before it runs. A retry rebuilds the message with a new price. A teammate edits the amount. The approval still says "yes". In a huma
A common gap in approval flows: a person approves an action, then something changes it before it runs. A retry rebuilds the message with a new price. A teammate edits the amount. The approval still says "yes".
In a human-in-the-loop approval flow for AI workflow actions, the fix is to approve a fingerprint of the exact action, and refuse to run anything that does not match.
1. Canonicalise and hash
import hashlib, json
def fingerprint(action: dict) -> str:
canon = json.dumps(action, sort_keys=True, separators=(",", ":"))
return hashlib.sha256(canon.encode()).hexdigest()
action = {"type": "refund", "order": "A-1042", "amount": "18.00", "currency": "usd"}
fp = fingerprint(action)
2. Store the approval against the fingerprint
approval = {"fp": fp, "approved_by": "priya", "at": "2026-10-30T10:15:00+05:30"}
3. Check before executing
def execute(action, approval):
if fingerprint(action) != approval["fp"]:
raise PermissionError("action changed after approval; re-approve")
# run_action(action)
4. Show the approver what is hashed
The approval screen must display every field that goes into the fingerprint. Approving a summary while hashing hidden fields defeats the point.
5. Keep the record
Log the fingerprint, the approver and the full action. When someone asks "who approved this?", you can show exactly what they saw.
Edge cases
- Normalise number formats before hashing, or harmless differences will force re-approval.
- Exclude fields that legitimately change, such as a retry counter, and say so in the code.
For where approval gates sit in a full build, see where approval gates sit in a full build.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.