# Permissions & human sign-off

> Permissions are the rules your app enforces about which tools your agent may call for a task, and which actions wait for a named person.

Decide what your agent may do alone, and make the rest wait for a named person.

Track: Agents
Card: https://buildsparkai.com/permissions-hitl
Plain text: https://buildsparkai.com/permissions-hitl.md
Last checked: 2026-10-21

## What it is

Permissions are the rules your app enforces about which tools your agent may call for a task, and with what access. Human sign-off, also called human-in-the-loop, is a pause before an action that changes something. The run waits until a named person approves or rejects that exact action.

## Why it matters

**Cost.** A wrong refund or a sent email costs more to undo than a pause costs to approve.

**Quality.** The approver sees the exact fields, so a wrong account or a wrong address is caught before it lands.

**Risk.** [OWASP, LLM03:2026 Excessive Agency](https://genai.owasp.org/resource/owasp-genai-llm-top-10-2026/) names three causes of an agent doing too much: too many tools, too much access, and too little sign-off. The table cuts all three: leave tools the task doesn't need off the list, give each tool the least access, and make act tools wait for a person.

## Try today

Take one agent or one AI model setup that has tools. Write each tool on a line, mark it read, draft or act, and write the name of the person who approves each act tool. Delete any line the task doesn't need.

## Common mistake

Writing "ask before sending" in the prompt and calling it a permission. The model can still propose the call. The rule has to live in the code that runs the tool, or in the system that owns the data. Anthropic, Configure permissions says permission rules are enforced by Claude Code, not by the model.

## Self-check

Filing a ticket alerts the support team. Where should the "wait for approval" rule live?

In the app, before the tool runs

## Understand it: whose access, and who may say yes

6 min, optional

The list says what this task may do. The approver is a named person who could take that action themselves.

### Whose access is it?

A tool can run as the person who is signed in, or as an account the agent holds on its own. Prefer the user's own access, and use read-only access where the tool only reads. [OWASP, LLM03:2026 Excessive Agency](https://genai.owasp.org/resource/owasp-genai-llm-top-10-2026/) says to run tools in the user's context, and to check permission in code, in the tool or the system that owns the data, not by asking the model.

### Allow, ask, deny

[Anthropic, Configure permissions](https://code.claude.com/docs/en/permissions) evaluates rules as deny, then ask, then allow, so a deny wins. The same page says the rules are enforced by Claude Code, not by the model. The modes it lists are `default` (labelled Manual), `acceptEdits`, `plan` (labelled Plan), `auto`, `dontAsk`, and `bypassPermissions`. The mode a session starts in depends on your settings and plan, so check it rather than assume Manual. `bypassPermissions` belongs in an isolated environment, such as a container or a virtual machine. File reads need no approval there, but shell commands do, except a built-in set of read-only commands. So don't treat every tool that only reads as free of approval.

[Google, Function calling with the Gemini API](https://ai.google.dev/gemini-api/docs/function-calling) says the model doesn't execute the function itself. You can limit which tools are offered, and the page says to validate function calls before executing them.

### The list can change with who is asking

[Model Context Protocol, Tools](https://modelcontextprotocol.io/specification/2026-07-28/server/tools) says a server may vary the tool list by authorization, and that clients must treat tool annotations as untrusted unless they come from a trusted server. A label on a tool is not a permission. Your app still decides what runs.

### What the approver sees, and no answer means no

Show the exact inputs, the reason, and the effect. The Tools specification says to show tool inputs before calling the server. [OpenAI, Guardrails and human review](https://developers.openai.com/api/docs/guides/agents/guardrails-approvals) says human review pauses the run so a person or a policy can approve or reject. If review times out or becomes unavailable, fail closed: the action doesn't run.

The person who approves is someone allowed to take that action themselves. Not the requester. Not the agent. [You'll use this rule again at merge time: Working with a coding agent.](/coding-agent) On that card, your own approval of the agent's pull request doesn't count when the repository requires another reviewer.

### Keep the record

Write down what was asked, who approved it, and what ran. The Tools specification says to log tool usage for audit. [NIST, Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile](https://www.nist.gov/publications/artificial-intelligence-risk-management-framework-generative-artificial-intelligence) (published July 26, 2024) asks, in MANAGE 2.4, for mechanisms and assigned responsibility to supersede, disengage, or deactivate a system whose outcomes don't match the intended use. The same profile's MS-4.2-004 says to monitor and document cases where a person or another system overrides the system's decisions.

### Too many asks, and how you test it

Advice, not a sourced claim: people start approving without reading when every step asks. Keep asks on act tools, and make each ask name the exact action.

Add approval cases to the set you already grade. [Test it: Evaluation basics.](/evaluation-basics)

See the pasted note in the [support assistant](/practice/support-bot/part-2#injection). The live page shows the note asking for a refund the docs don't allow. It does not show a tool that sends email.

## Practice and deep

Example: made up to show the idea.

Same support assistant, same four tools, with the reason filled in. search_docs is a read: it looks up help pages this user may already see, so it runs alone and is logged. lookup_account is a read that uses the customer's own access. create_ticket is an act when filed: it alerts the support team, so the draft runs alone and filing waits for the support person on duty. send_email is an act, and this task doesn't need it, so it stays off the list.

Now a new task: handle a refund request. Two rows are filled. You pick the rest.

Tool
Effect
Gate

lookup_order
read
runs alone

draft_reply
draft
runs alone, draft shown

## Sources

- [Anthropic, Configure permissions](https://code.claude.com/docs/en/permissions)
- [Google, Function calling with the Gemini API](https://ai.google.dev/gemini-api/docs/function-calling)
- [Model Context Protocol, Tools](https://modelcontextprotocol.io/specification/2026-07-28/server/tools)
- [NIST, Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile](https://www.nist.gov/publications/artificial-intelligence-risk-management-framework-generative-artificial-intelligence)
- [OpenAI, Guardrails and human review](https://developers.openai.com/api/docs/guides/agents/guardrails-approvals)
- [OWASP, OWASP GenAI LLM Top 10 2026: LLM03:2026 Excessive Agency (LLM means large language model)](https://genai.owasp.org/resource/owasp-genai-llm-top-10-2026/)

The Tools specification is dated 2026-07-28. NIST's profile was published July 26, 2024.
