---
title: "Use case: Put a person in front of a consequential agent action"
canonical_url: "https://tokenobserve.com/use-cases/require-human-approval"
published: 2026-09-02
last_updated: 2026-10-21
---

# Use case: Put a person in front of a consequential agent action

In Token Observe, a policy whose action is require_approval refuses the request, mints an approval bound to the SHA-256 of the canonicalised action plus the execution context it was proposed in, and holds the trace open until somebody decides. Change any of it and the hash differs and the retry is refused.

## The stated limit

Nothing tells the agent: An approval takes effect only when the agent retries

## A yes in a chat channel evidences nothing.

The person who typed yes is identified by whoever's account was logged in, and approving a category rather than this refund of £240 on this order is a standing licence for every refund afterwards. The failure that makes teams switch the gate off is quieter: an agent waiting on a human has no callback, so it re-submits, and the queue fills with duplicates of one decision.

## The steps, in this order

1. Gate the few actions that deserve it. The ones that move money, delete data, deploy or contact a customer. A queue nobody reads turns a control into a delay with a rubber stamp.
2. Run the rule in shadow first. In shadow it raises no approval and parks no trace, so the interruption rate is a number you measured rather than a surprise your rota discovers.
3. Set a lifetime you will meet. Sixty minutes by default, one minute to seven days by policy. Expiry is terminal after approval as well as before it.
4. Teach the agent to resume. The refusal carries the trace id, a typed code, the approval id and a resume object: the payload must match, and the approval is single-use.

### The approval is bound to one exact payload and its context.

The context half is in the hash because changing it after a human reviewed the action changes what was approved: an approval granted to an agent holding one set of roles must not survive that agent being granted more. What is excluded matters as much: request ids, trace ids and transport session ids never enter it, because a reconnect must not invalidate a decision somebody already made.

- The action: The sanitised model request, or the tool name and its arguments, plus the contract identity where an effect contract governs the call.
- The subject: Id, kind, team, tags and effective grants, normalised so ordering cannot change the hash. A permission added later produces a mismatch.
- The chain and the human: The ordered delegation identities with each hop's grants, plus the on-behalf-of identity, the session id and tags, and the tier hint.
- Excluded on purpose: Request ids, trace ids, credentials and generated transport session ids — everything that changes between proposing and redeeming.

### What the reviewer sees is a summary, not the payload.

The action summary is the tool name (or the model name, on the request path) plus the policy's own reason, passed through the mask redactor and capped at 240 characters. No model-proposed arguments reach the approvals table or the approval webhook. Treat both at the sensitivity of trace content all the same: a policy reason is written by your organisation and can name a customer or an amount.

## What this still does not solve

- There is no approver routing. Any operator whose evidence scope covers the trace's team can decide any approval in it: no approver list, no escalation and no two-person rule.
- The reviewer reads a summary, not the payload, so somebody who skims approves what they were shown rather than what will run.
- Offline approvals on a developer seat cannot be single-use. A signed bundle records consumption as of issue, so within its freshness window one can be spent twice.
- Nothing pushes the decision to the agent. Approving is a permission the agent redeems by retrying, and the gate binds only the calls Token Observe sees.

## Questions and answers

Q: Does approving in the console make the agent carry on?
A: No. Token Observe has no channel that reaches an agent; event delivery goes to webhooks, chat and email, which are human channels. An approval is a permission the agent redeems by repeating the identical request with the approval id attached, so clicking approve moves nothing until the agent tries again.

Q: What happens if the agent changes the request after approval?
A: It is refused. The retry is canonicalised and hashed again, and a differing hash is refused as granted for a different action payload, with no execution and no partial credit. That covers the context too: a different on-behalf-of identity, or grants widened after the decision, both produce a different hash.

Q: What happens if nobody decides in time?
A: The approval expires and the action does not happen. Expiry is applied lazily before the queue is listed and before any decision is written, and expiring the row and releasing the budget reservation are one transaction. The agent is then told a new approval is required rather than that it was refused.
