Skip to content

Approval gates

An agent that can write files, run shell commands, and reach the internet needs a place where you say yes. In Atomic Agent that place is the approval gate: before a dangerous tool runs, the runtime classifies what it is about to do and either lets it through or stops and asks you.

How much it asks is one number. agent.approvalLevel runs from 1 (ask about everything) to 5 (ask about nothing), and each step up hands the agent a broader class of actions to take on its own.

The ladder

The default is level 1. Every gated action prompts you before it happens.

LevelNameRuns without asking
1paranoidNothing. Every gated action prompts.
2workspaceFile writes, edits, and patches strictly inside the session working directory.
3homeAdds file writes anywhere under your home directory, moves to Trash, archive extraction, and HTTP requests.
4operatorAdds guarded shell commands, skill scripts, and process kills.
5full trustEverything, including browser navigation to non-web URLs, writes to the agent’s own trust config, and anything the runtime could not categorise.

The ladder is cumulative by construction. The gate asks level >= threshold, so a category that is silent at level 3 is silent at 4 and 5 too — there is no level where something starts asking again.

// <stateDir>/config.json
{
"agent": {
"approvalLevel": 2
}
}

Categories

Every call site that asks for approval names one of ten categories. The category decides both the level at which it goes quiet and the label you see in the prompt.

CategoryPrompt labelAuto-approves from
fs_write_workspacefile write · workspace2
fs_write_homefile write · home3
fs_trashmove to Trash3
httpHTTP request3
shellshell command4
scriptskill script4
proc_killprocess kill4
browser_nonwebbrowser · non-web URL5
trust_configagent trust config5
otheruncategorised5

other is the deliberate fallback for anything a call site cannot place precisely. Because it only goes silent at 5, an uncategorised action keeps asking on every level below full trust — the conservative default.

The prompt has four answers

When the gate stops, the CLI prompt on stderr is not a yes/no. It takes four:

AnswerEffect
yApprove this one call.
sApprove, and allow this whole category for the rest of the session.
aApprove, and allow this shell command shape for the rest of the session.
NDeny.

Only y and yes count as approval. Anything else — a typo, an empty line, maybe — is a refusal. Denial is the failure mode, which is what you want from a gate.

» approval required for tool: os.fs.write
kind: file write · home
reason: write 2.1 KB to ~/notes/plan.md
affects: /Users/you/notes/plan.md
approve? [y = approve once, s = allow this kind this session, N = deny]

s and a appear only when the request is grantable. a needs a shell command shape to generalise from, so it shows up on shell requests and not on file writes. And trust_config is never grantable at all — those requests only ever offer y/N, and the prompt says so:

(trust-config writes are never granted for the session)

That is the grant-side half of the same invariant as the level pin. A broad category grant earlier in the session must not later cover a write to the file that holds the ladder.

Skipping approvals for one run

Every interactive entry point (run, tui, serve) accepts --no-approval, which forces level 5 for that process.

Terminal window
atomic-agent run --no-approval

The persisted agent.approvalLevel is the baseline and the flag overrides it for the process. run, tui, and serve all resolve the boot level the same way, so the level you set in config applies consistently across entry points.

Setting the level from the TUI

Unlike --no-approval, which lasts one process, these write the persisted level:

  • /privacy level 1..5 sets the ladder directly to that rung.
  • /privacy approve on and /privacy approve off are aliases for levels 5 and 1 — kept so older muscle memory and scripts keep working. There is no bare /privacy approve: the verb is deliberately explicit, because on means “run everything without asking”.

Both open the Privacy panel, where 15 jump to a level and Left / Right step one rung at a time. See TUI panels for the full key list.

Approval-gated calls cannot be batched

Atomic Agent lets the model emit several tool calls in one step, executed by resource class. Approval-gated tools are excluded from that: they carry the virtual approval_gated class and are forbidden inside a multi-call batch.

If the model emits one anyway, the runtime does not fail the step. It trims the batch to the first approval-gated call, executes that one, drops the rest, and tells the model what happened in the next step’s prompt so it can re-emit the dropped calls one at a time.

These are the approval-gated tools:

ToolWhat it does
os.fs.writeWrite a file
os.fs.editEdit a file in place
os.fs.patchApply a patch
os.fs.trashMove to Trash
os.fs.archive.extractExtract an archive
os.shell.runRun a shell command
os.proc.killKill a process
os.http.requestIssue an HTTP request
skill.run_scriptRun a skill script

Read-only counterparts (os.fs.read, os.fs.grep, os.web.fetch, os.git.*, the memory.* recalls) are pure_read and batch freely.

The legacy key

Before config v37 the setting was a boolean, agent.approvalRequired. It is migrated automatically:

Legacy valueBecomes
approvalRequired: trueapprovalLevel: 1
approvalRequired: falseapprovalLevel: 5

The migration runs when the config file is read, and the legacy key is removed from disk afterwards. If a file somehow carries both, agent.approvalLevel wins — an explicit level is never overridden by a stale boolean.

Choosing a level

Level 1 — anything untrusted

The default. Use it when you are exploring, running a new skill, or pointing the agent at code you did not write.

Level 2 — focused project work

The agent edits freely inside the working directory but still asks before touching anything outside it, hitting the network, or running shell.

Level 3 — research and fetching

Adds HTTP and home-directory writes. Good for tasks that read the web and take notes; shell still stops for you.

Level 4-5 — trusted automation

Shell and skill scripts run unattended. Only for workloads and inputs you fully control, ideally in a sandbox.

Why local-first

Every door out of the runtime, and which ones the approval gate stands in front of.

Tools

The full tool catalog, including which verbs are approval-gated.

CLI Reference

--no-approval on run, tui, and serve.

Traces and replay

What the trace records about a turn, including the calls that stopped for approval.