Skip to content
Documentation

Permissions

Approval modes, the risk model, and how a call is decided.

An autonomous agent is only useful if you can bound it. Forge decides every tool call the same way: the tool's risk level, adjusted by pattern matching on what it is actually about to do, resolved against the approval mode you chose. Nothing here depends on the model being well-behaved.

Three risk levels

read

Observes only. Always runs unattended.

write

Creates or modifies things the agent can also inspect and fix.

destructive

Discards work or reaches outside the workspace. Needs a human.

The line that matters is between the second and the third. A write can be inspected and fixed by the agent that made it; a destructive call throws work away, and no amount of iteration gets it back. Only the third class needs you by default.

Approval modes

cautious

Approve every change before it lands.

read: automaticwrite: askdestructive: ask
autodefault

The default. Forge works; anything that discards work stops for you.

read: automaticwrite: automaticdestructive: ask
yolo

Unattended. Deny rules still apply.

read: automaticwrite: automaticdestructive: automatic
$ forge --cautious "refactor the config loader"$ forge "fix the failing auth test"        # auto, the default$ forge --yolo "run the migration and fix what breaks"

Start in cautious on an unfamiliar repository. You will see exactly how the agent works, and you can move to auto once its first move stops surprising you.

How a call is decided

The checks run in this order, and the first one that applies wins.

  • Deny list - matches are refused outright. No mode and no allow-list overrides this.
  • Escalation - a command matching a dangerous pattern is promoted to destructive, whatever its tool's nominal level.
  • Allow-list - calls you have explicitly permitted run without asking again.
  • Mode - the resulting level is looked up against the table above: run it, or ask.

Because escalation happens before the mode is consulted, auto is not “anything that is not obviously read-only”. A shell call is nominally a write, but rm -rf build/ stops for you.

Always refused

These patterns are rejected in every mode, including yolo. They are the operations with no legitimate place in an automated coding task - machine-level destruction, privilege escalation, and publishing.

rm -rf /rm -rf ~rm -rf .sudo git pushmkfsdd if=:(){shutdownreboot> /dev/sdchmod -R 777 /

git push is on that list deliberately. Forge commits; you publish. See Git.

Escalated to destructive

These are allowed but always reach a human in cautious and auto. They are the commands that are ordinary in a shell and expensive to get wrong in an unattended loop.

rm -rrm -frmdirgit reset --hardgit cleangit checkout --git restoregit rebasegit filter-branchgit remotegit tag -dgit branch -Dtruncateshredmv /chownchmod -Rkill -9pkillsystemctldocker rmdocker rminpm publishpip uninstallcurl | sh| sh| bash

Note | sh and | bash in that list. Piping a downloaded script into a shell is exactly the kind of call that deserves a human, including when the script is Forge's own installer.

What an approval looks like

You see the tool, the level, and the exact call - the command as it will run, not a paraphrase.

⚠ shell  -  destructive   rm -rf build/ dist/   Approve this call?  [y/N]

Declining is not a failure. The refusal goes back to the model as a result, and it generally proposes another way to get the same thing done.

Choosing a mode

Use cautious when

  • You are new to Forge, or the repository is new to you.
  • The tree is dirty and you have work you cannot afford to lose.
  • The task touches infrastructure, migrations, or anything with a blast radius.

Use yolo when

  • The run is in CI, a container, or a scratch clone.
  • Everything is committed, so the worst case is git reset.
  • Nobody is at the terminal, and a prompt would just hang the job.

yolo approves everything the policy allows. The deny list still holds, but nothing else stops. Pair it with a sandbox and a clean git state, not with a repo full of uncommitted work.