Skip to Content

Approvals

Agents read and write files, run shell commands, and drive browsers. Approvals are the control surface over that — the difference between an agent you let run unattended and one you watch every keystroke of.

The policy

An ordered list of rules plus a default. The first rule that matches a tool call decides; anything uncovered falls back to the default.

extensions: approval: default: ask-human rules: - match: "bash(git log *)" # tool(pattern); first match wins action: allow - match: "bash(rm *)" action: deny

Four verdicts:

VerdictMeaning
allowRuns immediately
denyRefused, with a reason handed back to the agent
ask-agentA separate approval agent judges the call
ask-humanParked until you decide, in the TUI or web UI

ask-agent is the interesting one: a second, usually cheaper model reviews the call in context and decides. Point it at a model with the provider: key:

extensions: approval: provider: approval-agent default: ask-agent

Approving in practice

A parked call surfaces inline in the transcript — in the TUI, in the web UI, or on your phone. Approve it, deny it, or deny with a comment: the comment goes back to the agent as the reason, which usually redirects it rather than just stopping it (“don’t use rm, move it to /tmp instead”).

Denying can also stop the turn outright when you want the agent to halt, not adapt.

Denial is a first-class outcome, not an error. An agent that gets denied is expected to route around it, and a good deny comment is the cheapest way to steer a long-running task.

Safe shell pipelines

Shell is the hard case: bash(git log *) is easy to allow, but real commands are chains. Boba parses a shell command into its actual structure and evaluates each stage, so a safe chain can auto-approve as a whole without you hand-listing every permutation — and the approved command is executed as parsed arguments, never re-parsed from a string that could mean something different the second time.

This is opt-in. See ADR-003  for the model.

Unattended runs

Scheduled tasks and headless run-task sessions have no human to ask, so ask-human there means “park forever”. Give unattended profiles a policy that terminates: an explicit allow-list with default: deny, or ask-agent.

Further reading: ADR-001  covers the policy and tool-capability model in full.

Last updated on