Put a Human at the Authority Boundary

Explain this chapter with AI

Copy this prompt into ChatGPT, Claude, Gemini, a local model, or another AI.

Apply this chapter with AI

Copy this prompt into ChatGPT, Claude, Gemini, a local model, or another AI.

“Ask the user before doing anything dangerous” sounds like a safety design.

It is only a slogan until we define what the user sees, when approval occurs and exactly what the approval authorizes.

A useful authority boundary turns a model’s proposal into a concrete, validated effect. The user approves that effect—not a vague intention and not the model in general.


1. Classify effects before requesting permission

Not every tool call deserves the same interruption. Begin with effect classes:

Class Example Default handling
Read Search the current book Allow within declared scope and log
Prepare Draft an email without sending Allow, show the artifact
Reversible change Apply a local label Allow or confirm by user policy
External or irreversible Send, publish, purchase or delete Require effect-specific approval

These are defaults, not universal truths. Reading a private mailbox may deserve more protection than changing a local theme. The correct class depends on data sensitivity, destination, reversibility and user policy.

The important move is to classify the effect outside the model. The model may propose an action, but deterministic application code assigns the required authority.


2. Approve the normalized effect

Suppose an agent proposes:

{
  "tool": "send_email",
  "arguments": {
    "to": "editor@example.com",
    "subject": "Chapter review",
    "body": "Here is the draft..."
  }
}

Before approval, the application should:

  1. validate the arguments against the tool schema;
  2. resolve aliases and defaults;
  3. compute the actual destination and data leaving the browser;
  4. reject values outside policy;
  5. render the final effect for inspection.

The approval surface might say:

Send one email
To: editor@example.com
Subject: Chapter review
Includes: 1,842 characters and no attachments
Effect: data leaves this browser

“Allow this agent?” is not enough. It hides the decision the user is being asked to make.


3. Bind approval to the arguments

An approval must not become a reusable blank cheque.

One simple design produces an authorization record from the validated proposal:

{
  "toolId": "mail.send/v1",
  "argumentDigest": "sha256:…",
  "origin": "https://example.test",
  "approvedAt": "2026-09-02T17:04:10Z",
  "expiresAt": "2026-09-02T17:05:10Z",
  "singleUse": true
}

Execution recomputes the digest. If the recipient, body, tool version or origin changed, the approval no longer matches.

This prevents two common failures:

  • time-of-check/time-of-use changes after the user reviewed the action;
  • replay of an old approval for a new invocation.

The authorization record should expire quickly and be consumed atomically when the effect begins.


4. Separate proposal, authorization and execution

These stages should be visible in the architecture:

    flowchart TD
    P[Model proposal] --> V[Schema and policy validation]
    V --> A[User approval]
    A --> E[Deterministic executor]
    E --> R[Result and audit record]
  

The model does not call a privileged implementation directly. It produces a proposal. The policy layer decides whether the proposal is admissible. The human authorizes the normalized effect when required. A constrained executor performs only that operation.

This separation lets us test each boundary independently.


5. Treat refusal and timeout as ordinary outcomes

An agent workflow must survive:

  • explicit denial;
  • an approval window closing;
  • the user editing the proposed arguments;
  • policy rejection before the dialog appears;
  • the external operation failing after approval.

Denial should not trigger repeated persuasion or an automatic fallback that performs the same effect another way. It should return a typed result such as:

{
  "status": "denied",
  "reason": "user-declined"
}

The model can offer a non-executing alternative, such as leaving a draft for the user, but it cannot reinterpret refusal as an obstacle to route around.


Confirmation fatigue is a safety failure. If every read, render and local calculation opens a dialog, users learn to approve without reading.

Permission can be scoped by:

  • tool identity and version;
  • origin;
  • data class;
  • destination;
  • maximum effect;
  • duration;
  • whether each invocation still needs review.

A user might allow search_book for the current origin during a session while requiring every external message to be reviewed. A remembered permission should remain inspectable and revocable.


7. Record the complete authority trace

The Agent Inspector should connect:

user goal
  → model proposal
  → validated arguments
  → policy decision
  → approval presentation
  → approve / edit / deny / timeout
  → execution
  → observed effect

For each stage, record time, origin, tool version and correlation identifiers. Sensitive values may be redacted, but the trace must still say what was removed and whether the remaining record is application-reported or directly observed.

An audit trail is useful after failure, but its larger value is experimental. It lets us measure how often a model proposes disallowed actions, how often users edit arguments and which approval designs cause confusion.


8. Test the boundary, not just the dialog

Useful fixtures include:

  • arguments mutate after approval;
  • an expired authorization is replayed;
  • two tabs race to consume one token;
  • a low-risk tool attempts a high-risk side effect;
  • an origin tries to use another origin’s grant;
  • the user denies and the model proposes the same action again;
  • execution partially succeeds and returns an ambiguous result.

A polished confirmation window cannot compensate for an executor that accepts unbound or stale authority.


Conclusion

Human involvement is not a magical safety property. It works only when a person sees a comprehensible, final effect and their decision is bound to exactly that effect.

With this boundary, the Agent Inspector can show not only what a model said, but how a proposed action acquired—or failed to acquire—authority. The next chapter generalizes that mechanism. Instead of applying policy only to agent tool calls, we will let the browser apply the user’s policy to the experience itself.


Sources and further reading

  1. OWASP, Authorization Cheat Sheet.
  2. W3C, Permissions.