Skip to content
Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3,290 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Gemini CLI - Oleg's sandboxes fork

Gemini CLI CI Gemini CLI E2E Version License

About This Fork

This is an experimental fork of Gemini CLI that introduces Docker Sandbox Mode for isolated execution of LLM-initiated operations.

Why This Fork?

The original Gemini CLI executes all LLM-initiated operations (file reads/writes, shell commands) directly on the host machine. While the CLI has safety mechanisms like approval modes and allowlists, there's an inherent security concern when an AI agent has direct access to your filesystem and can execute arbitrary commands.

Docker Sandbox Mode addresses this by:

  • Isolating LLM operations in a Docker container
  • Preserving the native CLI experience - the CLI itself runs on your host
  • Maintaining compatibility with existing workflows and directory mounting
  • Providing an additional security layer for teams that require stronger isolation

This implementation demonstrates how to integrate Docker's sandbox capabilities (docker sandbox run) with an AI coding agent, serving as a reference architecture for secure LLM tool execution.


Docker Sandbox Mode Architecture

Overview

Docker Sandbox Mode uses a split architecture: the Gemini CLI runs on the host while LLM-initiated operations execute in an isolated Docker container.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  HOST MACHINE                                               β”‚
β”‚                                                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Gemini CLI Process                                   β”‚ β”‚
β”‚  β”‚  β€’ Configuration & Settings (~/.gemini/)              β”‚ β”‚
β”‚  β”‚  β€’ Authentication & OAuth                             β”‚ β”‚
β”‚  β”‚  β€’ UI/Terminal Rendering                              β”‚ β”‚
β”‚  β”‚  β€’ Extension Management                               β”‚ β”‚
β”‚  β”‚  β€’ Container Lifecycle Management                     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚                    β”‚                                         β”‚
β”‚                    β”‚ docker exec <container-id> <command>    β”‚
β”‚                    ↓                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚  β”‚  Docker Sandbox Container (Long-Running, Detached)   β”‚ β”‚
β”‚  β”‚  β€’ File Operations (read/write)                       β”‚ β”‚
β”‚  β”‚  β€’ Shell Command Execution                            β”‚ β”‚
β”‚  β”‚  β€’ Network Operations (future)                        β”‚ β”‚
β”‚  β”‚  β€’ Mounted: /Users/shelajev/project β†’ /Users/...     β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Operations Breakdown

πŸ–₯️ Operations on HOST

The following operations run directly on the host and are not sandboxed:

  1. CLI Initialization

    • Loading settings from ~/.gemini/settings.json
    • Reading OAuth credentials
    • Loading extensions and custom commands
    • Reading .env files
    • Managing session state and history
  2. Container Management

    • Starting the Docker sandbox: docker sandbox run --detached gemini
    • Stopping the container on CLI exit
    • Health checks and container status monitoring
  3. UI Rendering

    • Terminal output and interactive prompts
    • Progress indicators and status updates
    • User input handling
  4. File Discovery

    • Finding GEMINI.md files
    • Scanning for extension directories
    • Project structure analysis (synchronous glob operations)

🐳 Operations in CONTAINER

The following LLM-initiated operations run inside the Docker container:

  1. File Operations

    • βœ… Reading files (text files via ReadFile tool)
    • βœ… Writing files (WriteFile tool, Edit tool, SmartEdit tool)
    • βœ… Reading binary files (images, PDFs, audio, video)
    • ⚠️ File stat operations (currently use host as fallback - TODO)
  2. Shell Operations

    • βœ… All shell commands executed via Shell tool
    • βœ… Background processes and command streaming
    • βœ… Working directory context preserved
  3. Binary Operations

    • βœ… Image processing for multimodal LLM input
    • βœ… PDF reading for document analysis

How It Works

  1. Build it:
npm install
npm run build
  1. CLI Starts on Host

    GEMINI_SANDBOX=docker-sandbox node bundle/gemini.js
    # or
    node bundle/gemini.js --sandbox docker-sandbox
  2. Container Lifecycle

    • CLI executes: docker sandbox run --detached gemini
    • Container starts and runs in the background
    • Container ID is stored for subsequent operations
    • Container persists for the entire CLI session
  3. LLM Operation Flow

    User: "create a file hello.txt"
    ↓
    LLM generates tool call: WriteFile(path="hello.txt", content="...")
    ↓
    WriteFile Tool β†’ config.getFileSystemService()
    ↓
    SandboxedFileSystemService (detects docker-sandbox mode)
    ↓
    DockerSandboxedFileOperations.writeTextFile()
    ↓
    Executes: docker exec <container-id> sh -c 'cat > hello.txt << EOF...'
    ↓
    File created inside container (and visible on host due to volume mount)
    
  4. Session Cleanup

    • On CLI exit, container is stopped: docker stop <container-id>
    • Container is preserved for potential reuse by docker sandbox

Building and Running

Prerequisites

  • Node.js v20 or higher
  • Docker with docker sandbox command support
  • macOS, Linux, or Windows (with WSL2)

Build Instructions

  1. Clone this repository

    git clone https://github.com/YOUR_USERNAME/gemini-cli.git
    cd gemini-cli
  2. Install dependencies

    npm install
  3. Build the project

    npm run build
  4. Create the bundle

    npm run bundle

    The compiled CLI will be available at bundle/gemini.js

Running with Docker Sandbox

Option 1: Direct execution

GEMINI_SANDBOX=docker-sandbox node bundle/gemini.js

Option 2: Using npm start (development)

GEMINI_SANDBOX=docker-sandbox npm run start

Option 3: Global installation

# Link for development
npm link

# Run from anywhere
GEMINI_SANDBOX=docker-sandbox gemini

Option 4: Persistent configuration

Set the environment variable permanently:

export GEMINI_SANDBOX=docker-sandbox
gemini

Or configure in ~/.gemini/settings.json:

{
  "tools": {
    "sandbox": "docker-sandbox"
  }
}

Verifying Docker Sandbox is Active

When running with DEBUG=1, you should see:

DEBUG=1 GEMINI_SANDBOX=docker-sandbox gemini

Expected output:

Starting Docker sandbox container...
Executing: docker sandbox run --detached gemini
Docker sandbox container started: 026d5a7bf7ae...
docker-sandbox mode: CLI runs on host, operations run in container

[Docker Sandbox] Writing file: /path/to/file.txt (42 bytes)
[Docker Sandbox] File written successfully
[Docker Sandbox] Executing shell command: ls -la

Testing the Sandbox

Try these commands to verify operations run in the container:

# 1. Check filesystem isolation
> list the contents of the root directory
# Should show Linux directories (bin, etc, lib, usr) not macOS (Applications, Library)

# 2. Test file operations
> create a file called test.txt with content "hello from docker"
> read the file test.txt

# 3. Test shell commands
> run the command "uname -a"
# Should show Linux kernel, not Darwin/Windows

⚠️ Experimental Status

This is an experimental implementation with the following caveats:

Known Limitations

  1. Incomplete Coverage

    • Some LLM-initiated operations may still execute on the host
    • Network operations are not yet fully sandboxed
    • File stat operations use host as fallback
  2. Not Production Ready

    • No formal security audit has been performed
    • The codebase has not been comprehensively verified for complete sandboxing
    • Edge cases and error handling may be incomplete
  3. Performance

    • Each operation requires docker exec, adding latency
    • Binary file operations may be slower due to encoding/decoding
  4. Compatibility

    • Requires docker sandbox command (Docker Desktop extension)
    • May not work with all Docker configurations
    • Some host-specific tools may not be available in the container

What This Fork Demonstrates

This implementation serves as a proof of concept showing:

  • βœ… How to integrate container isolation with an LLM agent CLI
  • βœ… Split architecture: native CLI experience + sandboxed operations
  • βœ… Minimal changes to existing tool implementations
  • βœ… Reuse of Docker's native sandbox capabilities

It is not intended as a complete security solution but rather as a reference implementation for teams building similar systems.


Architecture Details

Code Organization

The sandbox implementation introduces several key abstractions:

1. Sandboxed Operations Interfaces

  • SandboxedFileOperations - Abstract interface for file operations
  • SandboxedShellOperations - Abstract interface for shell operations
  • SandboxedNetworkOperations - Abstract interface for network operations

2. Docker-Specific Implementations

  • DockerSandboxManager - Container lifecycle management
  • DockerSandboxedFileOperations - File operations via docker exec
  • DockerSandboxedShellOperations - Shell execution via docker exec

3. Bridge Layers

  • SandboxedFileSystemService - Bridges FileSystemService β†’ sandboxed ops
  • Tools (ReadFile, WriteFile, Shell) use config.getSandboxedXXXOperations()

Key Design Decisions

  1. No CLI Relaunch

    • Traditional sandbox modes (docker, podman) relaunch the entire CLI inside the container
    • Docker sandbox mode keeps CLI on host, only sandboxes individual operations
    • Avoids the exit code 42 relaunch loop entirely
  2. Long-Running Container

    • Container starts once at CLI initialization
    • Persists for entire session
    • Reused across multiple operations for performance
  3. Preserved Path Semantics

    • Working directory mounted at identical path in container
    • Absolute paths work identically in both contexts
    • Simplifies tool implementations
  4. Separation of Concerns

    • SystemFileOperations - CLI's own files (settings, credentials) on host
    • SandboxedFileOperations - LLM operations in container
    • Clear boundary prevents chicken-and-egg problems

License

Apache License 2.0 - Same as upstream Gemini CLI

See LICENSE file for details.

Experimental Fork

About

An open-source AI agent that brings the power of Gemini directly into your terminal.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages