Requiring Dual Approval Before an n8n AI Agent Moves Client Money
Enforce dual approval where the money-movement tool executes, not in a node the agent can influence. Hold the tool call until two humans, both distinct from the requester and from each other, approve the exact tool name and parameters. Make each approval single use and time-limited, define what happens on timeout or rejection, and write a durable record of who approved what.
Design the dual-approval gate
- 1
Separate requester and approvers
The requester identity (the initiating user or system) must differ from both approvers, and the two approvers must be different people. Compare authenticated identities, not display names or email aliases.
- 2
Bind approval to the exact action
Hash the canonical tool name, all parameters, destination, amount and currency. Store the approval against that hash. The execution component recomputes it at call time and refuses on mismatch.
- 3
Single use
Mark the approval consumed when the tool executes. A replayed approval or a retried call must not run a second payment.
- 4
Expiry
Give each approval a short validity window so stale approvals cannot be used after circumstances change.
- 5
Approver authority outside the agent
Approvers authenticate through a channel the agent cannot write to, and the agent cannot mint, edit or resume an approval itself.
- 6
Fail closed
If the approval service is unreachable or the state is ambiguous, the tool call does not run.
What the approval record should contain
- Requester identity and the originating input that led to the proposed call
- Tool name and the full parameters as proposed, plus the hash used for binding
- Both approver identities, their decisions, and a timestamp for each
- Rejection reasons, expiry or timeout events, and the resulting outcome
- Execution timestamp and result, or the reason execution was refused
- Policy version in force when the decision was made
Why the gate belongs at the tool-call boundary
An AI agent with access to payment, banking or ledger tools can move client money on the strength of model output. That output may be wrong, may be steered by prompt injection, or may follow from a malformed input. OWASP describes this class of problem as Excessive Agency: damaging actions taken in response to unexpected, ambiguous or manipulated model output, regardless of what caused the model to malfunction. Because the cause does not matter, the control cannot depend on the model's judgment.
This shapes where approval should sit. OWASP guidance says consequential tool actions should require human approval before execution, and that the execution component must verify approval for the exact action. It also says approval hooks need application configuration and do not by themselves establish that an action is authorized, and that the same policy should be enforced at each tool boundary, next to the tool that creates the side effect.
In an n8n build, the common pattern is an approval step placed as a node inside the same workflow the agent participates in. That is a notification and a pause, not an enforcement point. If any other path, tool or branch can reach the payment call, the approval is advisory. The design goal is that the payment tool itself refuses to run without a valid, matching approval.
Decide which actions require approval
Start with a written policy that names the actions needing human approval, so the gate enforces policy rather than ad hoc judgment. Classify every tool action by reversibility: read-only, reversible, externally reversible, or irreversible. Let that class decide what may run unattended. Money movement will typically fall in the externally reversible or irreversible classes, which is an inference from the classification, so confirm it against your own settlement and recall rules.
Use an allowlist of actions the agent may take autonomously. Anything not on the list, including a newly added tool, defaults to requiring approval. Apply least privilege per agent instance, so money-movement tools are exposed only to agents that need them. A reporting agent that reads balances should not have a transfer tool in its tool list at all.
Consider stricter confirmation when the triggering input is untrusted, such as content from an email, document or web page. Tool output and retrieved content should be treated as data, never as instructions, so an instruction embedded in a retrieved invoice should not be able to start the approval path on its own authority.
Failure modes, timeouts and rejections
Each common weakness maps to a property above. Test them directly, since a configuration that looks correct does not prove authorization.
Define timeout behavior before go-live and document it. A pending call that expires should be denied, recorded as expired, and not silently retried. A rejection by either approver should end the request, be recorded with the reason where one is given, and not be reopened by the agent re-proposing the same call. If the agent re-proposes a modified call, it is a new request needing two new approvals.
- Approval bypass: Another branch or tool reaches the payment API. Answer: enforce the same policy at every tool boundary and remove direct credentials from the workflow.
- Parameters changed after approval: The amount or beneficiary is altered between approval and execution. Answer: hash binding verified at execution.
- Approver duplication or collusion: One person approves twice, or approves their own request. Answer: identity checks across requester and both approvers. Collusion between two real people needs organizational controls, such as approver rotation and review of approval patterns.
- Replayed approval: An old approval authorizes a new call. Answer: single use plus expiry.
- Approval fatigue: Reviewers click through high volumes. Answer: keep the allowlist wide enough that only consequential actions escalate, and show approvers the exact parameters, not a summary the model wrote.
Where workflow-level approval stops and runtime enforcement starts
Approval patterns built inside an n8n workflow, such as a pause step that resumes after a chat, email or webhook response, are a reasonable way to get a human in the loop. Their limit is structural: they live in the workflow the agent influences, so they cannot by themselves guarantee that the money-movement tool refuses to run without a matching approval. Questions about distinct approvers, parameter binding, single use and record quality are answered by what the enforcing component checks, not by the presence of an approval step. Review any pattern you adopt against the properties listed earlier.
Runtime policy enforcement in the execution path addresses that gap for individual tool calls. Trussed enforces policy in the execution path across models, agents, tools and MCP servers, with actions that include allow, redact, block, rate limit and escalate for human approval. A payment tool call can be escalated for human approval at runtime, and the enforcement itself generates audit-ready evidence. Its scope is individual interactions and tool calls. Whether a given enforcement layer supports your two-approver, single-use and expiry rules should be verified against your own requirements before you rely on it.
A practical next step is to pick one money-movement tool, classify it, write the approval policy, and run the failure-mode tests above against it before extending the pattern to other tools.
Dual-approval gate at the tool-call boundary
Proposed call
The agent proposes a payment, banking or ledger tool call with specific parameters.
Gate holds
The execution path pauses the call and escalates it for human approval.
Two approvers
Two humans, distinct from the requester and each other, review the exact action.
Verified execution
The tool runs only if the call still matches what was approved.
Evidence
Requester, approvers, timestamps, parameters and outcome are retained.
Put the approval gate where the money moves
See how policy enforcement in the execution path can escalate individual tool calls for human approval and produce audit-ready evidence.
Request a Demo