Skip to main content
Every tool call passes through a per-agent permission gate before it runs. This page will cover the permissions section of settings.yaml (was permissions.yaml) in full: the default_action verdict, the deny / ask / allow glob lists matched against qualified tool names, and the dangerous_default_deny list that ships as ["shell:*"] so shell execution is default-deny the moment a shell tool registers. It will also cover the human-in-the-loop path (an ask verdict raises an approval interrupt rendered as a modal in the TUI and a prompt in the REPL, while headless runs auto-deny and fail closed), plus remember_default_scope, which decides whether an approval is remembered once, for the thread, or durably per user and agent.
The permissions section can widen authority, so it is trust-gated: a copy in an untrusted project layer is ignored wholesale (it falls through to the user and bundled layers) until you trust the folder.

Git commands

An agent allowed to run the shell can also run git, so the gate looks inside every run_shell command, even for an agent whose policy allows the shell without asking:
  • Commands that can lose work ask every time, and the approval is never remembered: git stash, reset --hard, checkout <path>, restore, switch --force/--discard-changes, clean -f, rebase, commit --amend, branch -D, push, worktree remove --force, submodule deinit -f, and similar. Switching to an existing local branch with checkout or switch does not ask.
  • A plain git commit asks once per thread (or for good, with allow_always).
An unrecognized git subcommand (such as an alias from your .gitconfig) also asks, since it could expand to anything. The check also looks inside scripts the command runs (bash commit.sh, python fix.py), inline code (bash -c "...", python -c "..."), command substitution, and git run through another program (watch git stash, find -exec git ...). The prompt shows git status and git diff --stat, so you see what the command would touch, or says plainly when that could not be read. The auto execution mode skips both, in the TUI and in ziro -p --mode auto alike. A plugin language server’s lsp:* tools read source on the agent’s behalf, so a call is never more permitted than read_file: the stricter of the two verdicts (deny, then ask, then allow) applies in every mode, front end and subagent.
This is a backstop, not a sandbox. It reads one command at a time, so it can miss git reached another way: a wrapper binary, code assembled at run time, or state an earlier command left behind (with shell.session: persistent, an exported GIT_PAGER or a cd carries over to the next call). If an agent must never touch your history, deny shell:* for it or run it in a sandbox.
This page is in progress. The shipped permissions section for each agent is fully commented and is the best reference until it lands. Legacy split permissions.yaml files still resolve at each layer as an alternative.
See Configuration for how the permissions section resolves across config layers, Tools for how tools are named and namespaced, and Shell and files for the allow-plus-ask recipe the shipped agents use for run_shell.