One setting gates what the agent may write, read, and run. Change it with shift+tab in chat, --permission-mode per run, or permissions.mode in aster.yaml.

The modes

No mode allows something a looser one refuses, so stepping up the ladder only ever adds freedom.

Rules

allow, ask, and deny hold rules in one language:
A Bash rule is matched against the command line and every command inside a shell script it carries, so Bash(sudo:*) still fires on bash -lc "cargo build && sudo make install". Leading environment assignments are ignored, a shell nested in a shell is followed a few levels down, and a prefix ends at a word boundary, so Bash(rm:*) does not also match rmdir.

Precedence

  1. deny
  2. ask
  3. allow
  4. the built-in rules
  5. mode
User rules come before the built-ins, so a single allow entry overrides one of them without disabling the rest. To read .env files but keep every other secret protected:

Built-in rules

Ask before writing, since anything here runs as code later: .git/**, **/.git/**, .github/workflows/**, .husky/**. Ask before running, in every mode but edit: privilege escalation (sudo, doas, su), destructive filesystem operations (rm, rmdir, dd, mkfs, shred), permission and process control (chmod, chown, chgrp, kill, killall, pkill), system control (shutdown, reboot, halt, systemctl, launchctl), and network egress (curl, wget, nc, ssh, scp, rsync). Pausing on these is the whole difference between auto and edit; an ask rule of your own fires in edit too. Refuse to read, since a secret cannot be taken back out of the model’s context: **/.env, **/.env.*, **/*.pem, **/*.key, **/id_rsa*, **/*.p12, **/*.pfx, **/credentials.json, **/secrets.*. use_default_rules: false drops all three sets at once.

Sandbox

Outside yolo, commands run in a sandbox: filesystem writes are limited to the repository and temp directories, secrets are stripped from the environment, and the network is reachable with per-domain approval. Two keys tune the edges:
The sandbox denies ~/.ssh, ~/.aws, ~/.gnupg, ~/.config/gh, and ~/.kube by default and prompts when a command needs one; an allow_credentials entry skips the prompt for that command-and-directory pair only. ~/Library/Keychains is never grantable.

Headless runs

A prompt needs a front-end that can answer. Headless runs (-p, --json) have none, so anything that reaches ask is refused there. Pre-approve it with an allow rule, or run with --stream and answer approvals on stdin.