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.

gemini-clisandboxingapprovalssecuritycheckpointingFact-checked 2026-06-15
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).

ModeHow to setEdit toolsShell & other tools
default--approval-mode=default (settings default)Prompts each timePrompts each time
auto_edit--approval-mode=auto_edit / Shift+TabAuto-approvedPrompts each time
plan--approval-mode=plan / /plan / Shift+TabRead-only (no edits)Read-only (no edits)
yolo--approval-mode=yolo (flag only)Auto-approvedAuto-approved (sandbox auto-on)
The four approval modes, set with `--approval-mode <mode>`. Only the first three are valid persisted defaults; YOLO is flag-only.

Switch and persist the approval mode

  1. Set per-invocation with a flag

    Pass --approval-mode=<mode> where <mode> is default, auto_edit, yolo, or plan. default is the out-of-the-box behavior (prompt on every tool call).

  2. Cycle mid-session with `Shift+Tab`

    Press Shift+Tab to cycle Default → 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.

  3. 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).

~/.gemini/policies/safety.toml — block a destructive command
toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = "rm -rf"
decision = "deny"
priority = 100

Plan 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)

  1. CLI flag for one run

    Pass -s or --sandbox (boolean, default false). Highest precedence, no persistent state.

  2. Environment variable to pick the engine

    Set GEMINI_SANDBOX to one of true, docker, podman, sandbox-exec, runsc, or lxc. sandbox-exec is macOS Seatbelt; runsc is gVisor; lxc is the experimental LXC/LXD path.

  3. Settings entry to make it the default

    Put sandbox inside the tools object of settings.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.

MethodPlatformHow to selectNotes
Seatbelt (sandbox-exec)macOSGEMINI_SANDBOX=sandbox-execBuilt-in. Default profile permissive-open; tune with SEATBELT_PROFILE.
Docker / PodmanCross-platformGEMINI_SANDBOX=docker (or podman)Full isolation. Image ghcr.io/google/gemini-cli:latest; CWD mounted at the same absolute path.
gVisor (runsc)LinuxGEMINI_SANDBOX=runscStrongest isolation; runs docker run --runtime=runsc. Not auto-detected; configure the runtime first.
LXC / LXDLinux (experimental)GEMINI_SANDBOX=lxcFull-system container. Must already exist and be running — Gemini does not create it.
Native (icacls)WindowsAuto when sandbox enabledSets "Low Mandatory Level"; integrity marks persist after the session — reset with icacls.
Sandbox methods by platform. `runsc` and `lxc` are not auto-detected — select them explicitly.
Env varWhat it doesExample
GEMINI_SANDBOX_IMAGEUse a custom Docker/Podman imageus-central1-docker.pkg.dev/proj/repo/sandbox:latest
SANDBOX_MOUNTSExpose host paths (from:to:opts; to=from, opts=ro, from absolute)/host/cache:/cache:rw
SANDBOX_FLAGSInject raw flags into the docker/podman command--security-opt label=disable
SANDBOX_SET_UID_GIDLinux UID/GID mapping (true forces host UID/GID)true
BUILD_SANDBOXAuto-build local image from .gemini/sandbox.Dockerfile (source installs only)BUILD_SANDBOX=1 GEMINI_SANDBOX=docker gemini -p "…"
Sandbox configuration env vars (containers).
Contain a YOLO run in Docker
… scroll to run this session
YOLO auto-approves the consent prompt, but the Docker sandbox still gates what the command can reach. The destructive command is confined to the mounted workspace; expanding permissions requires explicit approval.

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.

Sandbox method

What can a tool reach once it runs? (containment)

Full process isolation in a container.

Approval mode

Does the CLI pause to ask before acting? (consent)

Tool call

What is the agent about to do?

safety check
default · Docker
run_shell_command rm -rf ./dist

Layer 1 · Approval (consent)

PROMPTS YOUPauses for your approval

default mode prompts for approval on each mutating tool call before it runs.

Layer 2 · Sandbox (containment)

ISOLATED

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=default
Pick a sandbox method and approval mode to see what runs silently, what is gated, and the exact flag/env/setting that produces it.

Folder 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?

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.