kosa8 / Guides

Guide · Gemini CLI

How do I run Gemini CLI in a sandbox?

Updated

Start Gemini CLI with -s (--sandbox), or set GEMINI_SANDBOX to docker, podman or sandbox-exec. On macOS the default Seatbelt profile, permissive-open, confines writes to the project folder but allows network access; Gemini's docs say sandboxing is off by default except in YOLO mode. For a boundary with its own kernel and a network allow-list, run Gemini CLI in a kosa8 microVM with the built-in gemini kit, which keeps your API key outside the VM.

01Steps

  1. Sandbox one session. -s or --sandbox enables sandbox mode for that session. On macOS it can use Seatbelt (sandbox-exec); elsewhere use a container engine.

    terminal
    gemini -s -p "analyze the code structure"
  2. Make it the default. GEMINI_SANDBOX accepts true, false, docker, podman or a custom command. The same choice can go in settings.json under tools.sandbox. The flag wins over the variable, which wins over the settings file.

    terminal
    export GEMINI_SANDBOX=docker
    settings.json
    {"tools": {"sandbox": "docker"}}
  3. On macOS, tighten the Seatbelt profile. SEATBELT_PROFILE switches the profile. strict-open restricts reads as well as writes and still allows network access; the -proxied profiles send traffic through a proxy you configure.

    terminal
    SEATBELT_PROFILE=strict-open gemini -s
  4. Debug a refusal. DEBUG=1 prints more detail. Put it in .gemini/.env rather than the project's .env, which Gemini's docs say has no effect for it. In a container sandbox, SANDBOX_MOUNTS adds mounts, read-only by default.

    terminal
    DEBUG=1 gemini -s -p "debug command"
  5. For a VM boundary, install kosa8. On an Apple silicon Mac or x86-64 Linux, install kosa8, start its daemon and check the setup with kosa8 doctor.

    terminal
    curl -fsSL https://kosa8.com/install.sh | sh
    kosa8 daemon start
    kosa8 doctor
  6. Run Gemini CLI in its own microVM. Set GEMINI_API_KEY on your computer only, read the plan with --dry-run, then run the gemini kit from your project folder. Options for kosa8 go before the kit name; anything after it goes to Gemini CLI. The sandbox is removed when Gemini CLI exits; your folder keeps its changes.

    terminal
    export GEMINI_API_KEY=...
    kosa8 agent run --dry-run gemini
    cd ~/code/api && kosa8 agent run gemini
  7. Read the record. Every request through the broker, allowed or refused, and every tool call the model asked for is in kosa8's hash-chained audit log.

    terminal
    kosa8 audit ls
    kosa8 audit verify

02Is Gemini CLI sandboxed by default?

No. Gemini CLI's documentation says sandboxing is disabled by default, except that it is turned on when you use --yolo or --approval-mode=yolo. Turn it on with -s, the GEMINI_SANDBOX variable or tools.sandbox in settings.json.

Approval and sandboxing are separate controls. --approval-mode decides what Gemini CLI asks you about (default, auto_edit, plan or yolo); the sandbox decides what a command can touch once it runs. YOLO mode approves every tool call, which is why the sandbox matters most there.

03What does each SEATBELT_PROFILE allow?

Gemini CLI ships six Seatbelt profiles for macOS. permissive-open, the default, restricts writes and allows network access; restrictive-open applies stricter restrictions; strict-open restricts reads as well as writes. Each -proxied variant sends network traffic through a proxy instead of allowing it directly.

ProfileFilesNetwork
permissive-open (default)Write restrictionsAllowed
permissive-proxiedWrite restrictionsVia proxy
restrictive-openStrict restrictionsAllowed
restrictive-proxiedStrict restrictionsVia proxy
strict-openRead and write restrictionsAllowed
strict-proxiedRead and write restrictionsVia proxy

On Linux, GEMINI_SANDBOX=runsc runs the container under gVisor, a user-space kernel, and needs Docker installed. LXC/LXD is listed as experimental.

04Why does Gemini CLI say "Operation not permitted" in the sandbox?

The command needed access outside what the sandbox allows. Gemini CLI's documentation suggests trying a more permissive profile or adding mount points, and running with DEBUG=1 for more detail.

With the open profiles, network access is allowed; with the proxied ones, check the proxy configuration. Under gVisor, services bound to your host's loopback interface are not reachable from inside, even with --network host.

05What does a microVM add to Gemini CLI's own sandbox?

Seatbelt is a policy enforced by the macOS kernel, and Docker and Podman containers share the host's kernel. In a kosa8 microVM, Gemini CLI gets its own Linux kernel, sees one shared folder, reaches only the hosts its kit lists, and holds a placeholder instead of GEMINI_API_KEY: a broker on your side adds the real key to requests to generativelanguage.googleapis.com.

  • Network allow-list, enforced on your side. The kit allows registry.npmjs.org and the broker; anything else is refused and logged.
  • Recorded, not held. The claude kit checks each tool call before it runs. The gemini kit has no pre-run hook yet, so its calls, such as run_shell_command, are checked against kosa8's rules in the audit log rather than held for approval.
  • Rewind. Start a kept sandbox with --keep --name and you can kosa8 checkpoint and kosa8 rewind it. A rewind restores the machine, not the shared folder: keep git for that.
  • Not tested together. kosa8 does not document running Gemini CLI's own container sandbox, or --yolo, which turns that sandbox on, inside the kit.

06Other options

  • Seatbelt fits quick, local work on macOS with no extra install.
  • Docker or Podman fits Linux and Windows hosts and teams that already run containers; a custom .gemini/sandbox.Dockerfile adds project tools.
  • gVisor (runsc) adds a user-space kernel between the container and the host on Linux.
  • Docker Sandboxes runs coding agents in isolated microVM sandboxes from Docker's tooling.
  • A full VM in UTM or Lima fits a long-lived, general-purpose environment you manage yourself.
  • Hosted sandboxes such as E2B, Daytona or Modal fit when the agent should run in the cloud.

07Sources

  1. Gemini CLI: sandboxing (methods, SEATBELT_PROFILE, troubleshooting)
  2. Gemini CLI: configuration (--sandbox, --approval-mode, GEMINI_SANDBOX)
  3. kosa8 docs: Run an AI assistant (built-in kits)
  4. kosa8 docs: Writing a kit
  5. kosa8 docs: Rules for tool calls
  6. gVisor documentation