The Cartographer · 11 min mission
Gemini CLI: Sandboxing & Approvals
Master the two-layer safety model that keeps an agent that edits files and runs shell commands from wrecking your machine.
On this page
Gemini CLI gives mutating tools two independent brakes: approval (does the CLI pause to ask before a tool runs?) and the sandbox (what can a tool reach once it runs?). Wrapped around both is folder trust (whether a project's config loads at all); underneath sits checkpointing/rewind (an undo for AI edits). This guide covers how to set each one, with the exact flag, env var, config key, and default. Scoped to stable v0.46.0 (published 2026-06-10).
| Mode | How to set | Edit tools | Shell & other tools |
|---|---|---|---|
default | --approval-mode=default (settings default) | Prompts each time | Prompts each time |
auto_edit | --approval-mode=auto_edit / Shift+Tab | Auto-approved | Prompts each time |
plan | --approval-mode=plan / /plan / Shift+Tab | Read-only (no edits) | Read-only (no edits) |
yolo | --approval-mode=yolo (flag only) | Auto-approved | Auto-approved (sandbox auto-on) |
Switch and persist the approval mode
Set per-invocation with a flag
Pass
--approval-mode=<mode>where<mode>isdefault,auto_edit,yolo, orplan.defaultis the out-of-the-box behavior (prompt on every tool call).Cycle mid-session with `Shift+Tab`
Press
Shift+Tabto cycleDefault → Auto-Edit → Plan. Plan drops out of the rotation while the CLI is processing a turn or showing a confirmation dialog. YOLO is deliberately absent from the cycle.Persist a default in `settings.json`
Set
general.defaultApprovalMode(default"default"). The enum accepts only"default","auto_edit","plan". Requires restart.
Policy Engine: durable approval rules
The Policy Engine encodes fine-grained, persistent tool-execution rules. Rules live in .toml files under ~/.gemini/policies/ — every file ending in .toml is loaded and combined. Each [[rule]] pairs conditions (toolName, commandPrefix, argsPattern regex, interactive flag, and which modes it applies to) with a decision (allow | deny | ask_user) and a numeric priority 0–999 (higher wins). A deny rule removes the tool from the model's memory entirely. In non-interactive runs, ask_user is treated as deny. The legacy tools.exclude setting is deprecated in favor of deny rules.
Rules are tiered with a base priority: Default 1, Extension 2, Workspace 3, User 4, Admin 5. Final priority = tier_base + (toml_priority / 1000), so Admin always outranks User outranks Workspace, with the in-file priority breaking ties inside a tier. List active policies with /policies list (grouped by mode).
[[rule]]
toolName = "run_shell_command"
commandPrefix = "rm -rf"
decision = "deny"
priority = 100Plan Mode: the read-only approval mode
plan is a read-only environment for research and design — the agent can explore and propose but cannot modify code. It is enabled by default (general.plan.enabled, default true, requires restart). Enter it four ways: launch with --approval-mode=plan; run /plan [goal] (goal optional); cycle in with Shift+Tab; or ask in natural language (which calls the internal enter_plan_mode tool — unavailable in YOLO mode). Related settings: general.plan.directory (where plan markdown is stored; defaults to the system temp dir) and general.plan.modelRouting (Pro for planning, Flash for execution). /plan copy copies the approved plan to the clipboard; Ctrl+X opens the plan file in your external editor.
Approval vs. sandbox — the two layers
Approval (consent)
Decides whether the CLI pauses to ask before a tool runs.
Set per-session with --approval-mode or Shift+Tab; made durable with Policy Engine .toml rules in ~/.gemini/policies/.
Approving a dangerous command satisfies approval — the command still executes.
Sandbox (containment)
Decides what a tool can reach once it runs — the filesystem and network it is confined to.
Set with -s / --sandbox, the GEMINI_SANDBOX env var, or tools.sandbox in settings.json.
Even a fully auto-approved command is boxed in by the chosen sandbox.
Enable the sandbox (three ways, in precedence order)
CLI flag for one run
Pass
-sor--sandbox(boolean, defaultfalse). Highest precedence, no persistent state.Environment variable to pick the engine
Set
GEMINI_SANDBOXto one oftrue,docker,podman,sandbox-exec,runsc, orlxc.sandbox-execis macOS Seatbelt;runscis gVisor;lxcis the experimental LXC/LXD path.Settings entry to make it the default
Put
sandboxinside thetoolsobject ofsettings.json:{"tools": {"sandbox": true}}or{"tools": {"sandbox": "docker"}}. Every session in that scope is then contained.
Sandbox methods by OS
There is no single sandbox; Gemini CLI uses the isolation your platform provides. macOS ships Seatbelt (sandbox-exec), with the default profile permissive-open (restricts writes outside the project dir). Swap profiles with SEATBELT_PROFILE: permissive-open (default), permissive-proxied, restrictive-open, restrictive-proxied, strict-open, strict-proxied — -proxied routes network through a proxy, restrictive-* deny by default, strict-* restrict both reads and writes to the working directory. Define your own with a sandbox-macos-<name>.sb file in the project's .gemini/ directory. Cross-platform, Docker/Podman containers give full process isolation; on Linux, gVisor (runsc) is the strongest option and LXC/LXD (experimental) gives a full-system container. On Windows, the native sandbox uses icacls.
| Method | Platform | How to select | Notes |
|---|---|---|---|
Seatbelt (sandbox-exec) | macOS | GEMINI_SANDBOX=sandbox-exec | Built-in. Default profile permissive-open; tune with SEATBELT_PROFILE. |
| Docker / Podman | Cross-platform | GEMINI_SANDBOX=docker (or podman) | Full isolation. Image ghcr.io/google/gemini-cli:latest; CWD mounted at the same absolute path. |
gVisor (runsc) | Linux | GEMINI_SANDBOX=runsc | Strongest isolation; runs docker run --runtime=runsc. Not auto-detected; configure the runtime first. |
| LXC / LXD | Linux (experimental) | GEMINI_SANDBOX=lxc | Full-system container. Must already exist and be running — Gemini does not create it. |
Native (icacls) | Windows | Auto when sandbox enabled | Sets "Low Mandatory Level"; integrity marks persist after the session — reset with icacls. |
| Env var | What it does | Example |
|---|---|---|
GEMINI_SANDBOX_IMAGE | Use a custom Docker/Podman image | us-central1-docker.pkg.dev/proj/repo/sandbox:latest |
SANDBOX_MOUNTS | Expose host paths (from:to:opts; to=from, opts=ro, from absolute) | /host/cache:/cache:rw |
SANDBOX_FLAGS | Inject raw flags into the docker/podman command | --security-opt label=disable |
SANDBOX_SET_UID_GID | Linux UID/GID mapping (true forces host UID/GID) | true |
BUILD_SANDBOX | Auto-build local image from .gemini/sandbox.Dockerfile (source installs only) | BUILD_SANDBOX=1 GEMINI_SANDBOX=docker gemini -p "…" |
Explore sandbox + approval combinations
Sandbox & approvals explorer
Gemini CLI gives mutating tools two independent brakes: approval (does it pause to ask?) and the sandbox (what can it reach once it runs?). Pick a method, a mode, and a tool call — and see the exact behavior plus the flag and settings.json that produce it.
Layer 1 · Approval (consent)
default mode prompts for approval on each mutating tool call before it runs.
Layer 2 · Sandbox (containment)
The container fully isolates the process: it can only touch the mounted workspace, and reaching beyond it (e.g. network for npm install) triggers a Sandbox Expansion Request you must approve.
GEMINI_SANDBOX=docker gemini --approval-mode=defaultFolder trust: the outermost gate
Folder trust runs before any project config loads. Controlled by security.folderTrust.enabled (default true, requires restart): an unfamiliar project's config and tools do not run until you bless the directory. Opening an untrusted folder first runs a discovery phase — the CLI scans and lists the Commands, MCP Servers, Hooks, Skills, and setting overrides the project defines, and flags security warnings (e.g. a project auto-approving tools or disabling the sandbox) — then prompts with three choices: Trust folder, Trust parent folder (trusts all subdirectories), or Don't trust (restricted safe mode). The choice is saved in ~/.gemini/trustedFolders.json (relocate with GEMINI_CLI_TRUSTED_FOLDERS_PATH). Manage trust anytime with /permissions trust [<directory-path>], or open the dialog with /permissions.
Safe mode (an untrusted workspace) does not: load .gemini/settings.json, load project .env files, install/update extensions, auto-accept any tools (always prompts), auto-load memory, connect to MCP servers, or run custom .toml commands.
Checkpointing and rewind: the undo button
Checkpointing is off by default — enable general.checkpointing.enabled in settings.json (requires restart; the old --checkpointing CLI flag was removed in v0.11.0, so settings is the only way). Once on, approving a file-modifying tool (write_file, replace) auto-creates a checkpoint bundling: a Git snapshot committed to a shadow repo at ~/.gemini/history/<project_hash> (never your real repo), the full conversation, and the pending tool call. Conversation/tool-call JSON is stored under ~/.gemini/tmp/<project_hash>/checkpoints; checkpoint filenames look like 2025-06-22T10-00-00_000Z-my-file.txt-write_file.
To roll back: /restore (no args) lists checkpoints; /restore <tool_call_id> reverts project files and the conversation, then re-proposes the original tool call. For interactive undo, /rewind (press Esc twice) lists past interactions, each offering up to three actions: rewind conversation and revert code, rewind only the conversation, or revert only the code. Separately, /resume (alias /chat) manages manually tagged conversation checkpoints — save, resume/load, list, delete, share.
Knowledge check
You want auto-approve-everything for a long unattended refactor but are nervous about a stray destructive shell command. What actually contains the blast radius?
Recommended baseline
Leave security.folderTrust.enabled on; live in --approval-mode=default and step up to auto_edit only for routine edits; enable general.checkpointing.enabled so AI edits are reversible; enable the sandbox (-s or tools.sandbox) whenever you auto-approve or run untrusted code. Encode hard rules — commands that must never run — as Policy Engine deny rules in ~/.gemini/policies/ (User tier, not the project folder, until issue #18186 is fixed).
Reach the end and this star joins your charted sky.