Back to blog
n8n Governance

Human Approval in n8n: Keep Critical Decisions Under Human Control

An approval contract beyond a chat button

Evidence, policy, authority, expiry and revalidation before execution

Original APPROVE-7 workflow with input/output examples and acceptance criteria
Human approval in n8n, review tasks, attributable decisions, idempotent execution and production operations
Primary nodeApproval contract
Routing modeAPPROVE-7
StatusPUBLISHED
A business event moves through an AI proposal, deterministic policy gate and human review before an approved action, with rejection, escalation and audit routes
APPROVE_7_V01: persist the proposal, verify authority, expire stale decisions and revalidate before the side effect.
TERMINAL_PREVIEW.LOG
$ gate n8n --contract APPROVE-7
> receive: event / identity / version
> propose: action / evidence / uncertainty
> policy: auto / human-review / reject / repair
> decide: reviewer / reason / expiry
> execute: revalidate / idempotency / receipt
human approval in n8n

Prerequisites and data: approval starts before the AI call

Human approval in n8n is not a button placed after an AI node. It is a contract that prevents a proposal from becoming a costly, irreversible or policy-sensitive action until an authorised person has reviewed the relevant evidence.

The first design decision is therefore the action boundary. List every side effect the workflow may request: changing a CRM field, sending a customer message, approving a discount, moving money, deleting a record, publishing content or opening access to data. For each action, name the owner, the permitted scope, the rejection path and the maximum time a proposal may remain valid.

This article focuses on that narrow implementation question. The broader choice and delivery of business automation belongs to the AI automation service, while local commercial AI expertise is described on the AI specialist in Armenia page.

The minimum approval envelope

A reviewer should never receive only model prose. Persist a typed envelope before the review request is sent:

json
{
  "approvalId": "apr_01J...",
  "correlationId": "evt_01J...",
  "workflowVersion": "lead-routing@12",
  "actionType": "crm.update",
  "target": { "system": "crm", "recordId": "lead_8421" },
  "proposedChange": { "status": "qualified", "ownerId": "sales_17" },
  "evidence": [
    { "source": "form", "version": "2026-07-31T08:14:00Z" },
    { "source": "crm", "version": "lead_8421:v9" }
  ],
  "policyResult": { "route": "human_review", "reasons": ["high_value"] },
  "requestedAt": "2026-07-31T08:14:10Z",
  "expiresAt": "2026-07-31T10:14:10Z"
}

The envelope separates facts from inference and inference from authority. The model may propose qualified; the policy layer decides that review is required; the reviewer may approve or reject; only an execution worker may write to the CRM.

Decide what requires review

Use explicit policy rules, not a vague confidence threshold. Confidence is useful diagnostic data, but it is not permission. Human review is normally required when at least one of these conditions is true:

  • the action is irreversible or expensive to reverse;
  • it affects a customer, employee, payment, contract or access right;
  • evidence is incomplete, stale, contradictory or outside the expected schema;
  • the proposed action exceeds a monetary, volume or permission threshold;
  • the case belongs to a new segment not covered by acceptance tests;
  • a policy rule returns review or stop;
  • the reviewer must provide a reason that becomes part of the audit record.

Low-risk and reversible actions may be auto-approved only when policy, data freshness and test coverage explicitly allow it. The workflow should be able to explain why it took the automatic route.

Workflow design: the APPROVE-7 sequence

The project-bound workflow is named APPROVE-7. It has seven controlled stages and three terminal outcomes: executed, rejected or expired.

1. Receive and persist the event

The Webhook, Trigger or polling node validates required fields, creates a correlation ID and writes the original event to durable storage. A successful webhook response means “accepted for processing”, not “business action completed”.

2. Build bounded context

Fetch only the records required for this decision. Store source identifiers, versions and timestamps. If an upstream system cannot provide a stable version, record a hash of the fields used by the proposal.

3. Produce a structured proposal

The AI node returns a schema-constrained object: proposed action, target, field-level changes, evidence references, assumptions and uncertainty. Free-form explanation may accompany the object, but it must not be the executable command.

4. Apply deterministic policy

A Code, Rule or sub-workflow node checks permissions, allowed action types, value thresholds, required evidence and current workflow version. It returns one of four routes:

  • auto: low-risk action may proceed;
  • human_review: create an approval request;
  • reject: proposal violates a known policy;
  • repair: required data is missing or invalid.

5. Create and deliver the review task

Persist the approval record before notifying the reviewer. The task must include the proposed change, evidence, risk reason, expiry time and approve/reject controls. Email, Slack, Teams or a custom internal UI can carry the notification, but the message itself is not the source of truth.

6. Receive an attributable decision

The callback must identify the approval record, reviewer identity, decision, reason and decision time. Verify that the reviewer is authorised, the request is still pending and the callback has not already been consumed. A signed, single-use token can identify the request; authentication and role checks must still identify the person.

7. Revalidate, execute and reconcile

Approval does not freeze the world. Before execution, re-read the target record and critical policy inputs. If data changed, the approval expired or the workflow version is no longer active, return to review. Otherwise execute with a stable idempotency key, persist the target receipt and read the authoritative postcondition.

The neighbouring guide on n8n retries, idempotency and dead-letter flow explains the recovery mechanics used after this gate. The production n8n architecture article covers the wider runtime and operating model.

Integrations and contracts

Approval store

The approval store is the state machine, not the notification channel. A compact record needs:

  • approvalId, correlationId and workflowVersion;
  • immutable proposal and evidence snapshots;
  • current state: pending, approved, rejected, expired, executing, executed or failed;
  • reviewer identity, authority and reason;
  • optimistic version or compare-and-set field;
  • expiry, execution receipt and reconciliation result.

Only valid transitions should be accepted. Two clicks, two channels or a delayed webhook must not create two actions.

Reviewer channel

Choose a channel that fits identity and urgency. A chat approval is convenient, but it can hide evidence and makes forwarding risky. A dedicated review page can show diffs, source links and history. For high-impact actions, require authenticated access and a typed reason instead of one-tap approval.

Target system

The executor receives a command derived from the approved proposal, never the raw callback body. The target contract should support an idempotency key or a repository-side operation ledger. If the target times out after accepting the request, reconcile before retrying.

Input and output example

Input to review:

json
{
  "approvalId": "apr_01J...",
  "summary": "Set lead_8421 to qualified and assign sales_17",
  "riskReason": "dealValue exceeds automatic threshold",
  "currentVersion": "lead_8421:v9",
  "expiresAt": "2026-07-31T10:14:10Z"
}

Attributable decision:

json
{
  "approvalId": "apr_01J...",
  "decision": "approve",
  "reviewerId": "user_42",
  "reason": "Source documents confirm scope and owner",
  "decidedAt": "2026-07-31T08:19:44Z"
}

Execution output:

json
{
  "operationId": "op_apr_01J...",
  "status": "executed",
  "targetReceipt": "crm_req_7782",
  "postcondition": { "recordVersion": "lead_8421:v10", "matched": true }
}

Checks before launch

Acceptance criteria

The controlled pilot is ready only when all of these statements are demonstrably true:

  1. Every sensitive action type is named and defaults to review or stop.
  2. The reviewer sees the proposed change, current value, evidence and risk reason.
  3. Reviewer identity and authority are verified server-side.
  4. Approve, reject, expiry and repair routes are tested.
  5. Duplicate callbacks cannot create duplicate side effects.
  6. Approval expires and stale source data forces revalidation.
  7. The executor uses a stable idempotency key.
  8. The target receipt and authoritative postcondition are stored.
  9. Notifications can be retried without creating a second approval.
  10. Operators can find pending, expired and failed records by correlation ID.
  11. A kill switch can prevent new executions while preserving evidence.
  12. The owner knows how to resolve a failed or ambiguous action.

Test fixtures

Test the workflow with deterministic fixtures rather than a live happy-path demonstration:

  • valid proposal approved once;
  • valid proposal rejected with a reason;
  • expired approval;
  • unauthorised reviewer;
  • duplicate approve callback;
  • approve and reject racing from different channels;
  • target changed after review was created;
  • policy changed after review was created;
  • target timeout before receipt;
  • notification failure with a persisted pending record.

The test result should identify the workflow version and fixtures used. A successful canvas execution alone does not prove the approval boundary is safe.

Operations and improvement

Monitor the queue, not model vanity metrics

Useful operational signals include pending age, expired share, rejection reasons, revalidation failures, duplicate callback attempts, execution failures after approval and time from request to decision. These describe the process. A single “AI accuracy” percentage does not show whether high-risk cases were controlled.

Keep evidence and permissions current

Reviewers change roles, policies change and target schemas evolve. Periodically verify reviewer groups, token lifetime, evidence links, workflow versions and retention rules. Remove access when a reviewer changes responsibility.

Improve by narrowing safe routes

The goal is not to eliminate people from every decision. Use review records to find repeated low-risk cases with stable evidence and reversible outcomes. Those cases may later receive a deterministic auto route. High-impact exceptions should remain reviewable even if the model becomes more capable.

Production checklist

Before rollout, assign an owner for the approval queue, an owner for execution failures and a decision-maker for policy changes. Start with one bounded action type and non-destructive targets. Measure real review latency and failure modes, then expand only when audit records show the contract is working.

If you need to design that bounded pilot, discuss an AI automation review. The useful outcome is not an impressive approval screen; it is an attributable, expiring and revalidated decision between an AI proposal and a verified business action.

CODE_BLOCK.TXT
require(proposal.evidence && policy.route && approval.expiresAt);
require(reviewer.authorized && decision.reason && state === "pending");
execute = revalidate() && consumeOnce() && idempotentCommand();