stripe.refund, its arguments
in canonical form, the resource it touches, the principal proposing it, and the environment it
runs in. The action hash is the SHA-256 of that canonical form, and it is the value every
approval is bound to.
What the canonical form is
Two calls that mean the same thing must hash the same, and two that differ in anything a human would care about must hash differently. So the form is fixed:- keys sorted, recursively;
- no insignificant whitespace,
separators=(",", ":"); - UTF-8,
ensure_ascii=False; - argument values are
str,int,bool,None, or nested containers of those; floatis rejected at any depth.0.1and0.10are the same money and different bytes, so amounts are integer minor units:200000is €2,000.00.
action_id, a fresh identifier per proposal, is excluded from the hash on purpose. Two
proposals of the same action from the same principal hash the same, which is what lets an
approval granted against the first pass of a LangGraph node match the second.
runnable
The guarantee it supports
Approval binding. A human approves a hash, and only the action with that hash can consume the approval. Change the amount, the payment, the principal or the environment and the hash moves.What it does not do
The hash does not identify a consequence. Two different actions can cause the same effect, and one action can be proposed twice; the effect key, not the hash, is what stops a duplicate. The hash also says nothing about whether the arguments are sensible; the policy does.Next
- Approval binding: what the hash is for.
- Effect keys: the other identity, for the consequence.
- Why · Get started.