{"id":31580978,"url":"https://github.com/matgawin/bubblewrap-claude","last_synced_at":"2026-05-03T16:05:36.765Z","repository":{"id":317442737,"uuid":"1067436527","full_name":"matgawin/bubblewrap-claude","owner":"matgawin","description":"A Nix flake providing a secure, isolated environment for running Claude Code using bubblewrap sandboxing.","archived":false,"fork":false,"pushed_at":"2026-04-26T02:06:07.000Z","size":82,"stargazers_count":8,"open_issues_count":1,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-26T03:35:10.926Z","etag":null,"topics":["bubblewrap","claude","claude-code","flake","nix","sandbox"],"latest_commit_sha":null,"homepage":"https://github.com/matgawin/bubblewrap-claude","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matgawin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-30T21:15:35.000Z","updated_at":"2026-04-25T12:35:14.000Z","dependencies_parsed_at":"2026-01-10T22:03:10.359Z","dependency_job_id":null,"html_url":"https://github.com/matgawin/bubblewrap-claude","commit_stats":null,"previous_names":["matgawin/bubblewrap-claude"],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/matgawin/bubblewrap-claude","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matgawin%2Fbubblewrap-claude","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matgawin%2Fbubblewrap-claude/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matgawin%2Fbubblewrap-claude/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matgawin%2Fbubblewrap-claude/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matgawin","download_url":"https://codeload.github.com/matgawin/bubblewrap-claude/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matgawin%2Fbubblewrap-claude/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32575156,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bubblewrap","claude","claude-code","flake","nix","sandbox"],"created_at":"2025-10-05T21:51:45.647Z","updated_at":"2026-05-03T16:05:36.748Z","avatar_url":"https://github.com/matgawin.png","language":"Nix","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bubblewrap Claude Code Sandbox\n\nA Nix flake providing a secure, isolated environment for running Claude Code using bubblewrap sandboxing. Features a profile-based architecture for language-specific development environments.\n\n## Quick Start\n\n### Standalone Usage\n\n```bash\n# Enter development environment\nnix develop\n# or\ndirenv allow\n\n# Run base sandbox in current directory\nnix run\n\n# Run sandbox in specific directory\nnix run .#claude-sandbox /path/to/project\n\n# Use language-specific profiles\nnix run .#claude-sandbox-go        # Go development\nnix run .#claude-sandbox-python    # Python development\nnix run .#claude-sandbox-rust      # Rust development\nnix run .#claude-sandbox-js        # JavaScript/TypeScript development\nnix run .#claude-sandbox-devops    # DevOps tooling\n```\n\n### Import in Other Flakes\n\n```nix\n{\n  inputs = {\n    nixpkgs.url = \"github:NixOS/nixpkgs/nixos-unstable\";\n    bubblewrap-claude.url = \"github:matgawin/bubblewrap-claude\";\n  };\n\n  outputs = {nixpkgs, bubblewrap-claude, ...}: let\n    system = \"x86_64-linux\";\n    pkgs = nixpkgs.legacyPackages.${system};\n    bwLib = bubblewrap-claude.lib.${system};\n  in {\n    # Create custom profile sandbox\n    packages.${system}.my-sandbox = bwLib.mkSandbox {\n      name = \"my-project\";\n      packages = with pkgs; [ docker kubectl terraform ];\n      env = { MY_VAR = \"value\"; };\n      args = [ \"--ro-bind-try /home/$USER/.config/myapp /home/$USER/.config/myapp\" ];\n    };\n\n    # Extended dev shell\n    devShells.${system}.default = bwLib.mkDevShell {\n      packages = with pkgs; [ docker kubectl terraform ];\n    };\n  };\n}\n```\n\n## Built-in Language Profiles\n\nPre-configured development environments:\n\n| Profile | Command | Tools | Cache Binds |\n|---------|---------|-------|-------------|\n| **Base** | `claude-sandbox` | Core utilities, git, jujutsu, vim | - |\n| **Bare** | `claude-sandbox-bare` | Minimal: bash, coreutils only | - |\n| **Nix** | `claude-sandbox-nix` | nix, alejandra | `/nix` |\n| **Go** | `claude-sandbox-go` | go, gopls, delve, golangci-lint, gotools, gofumpt | `~/go/pkg/mod` |\n| **Python** | `claude-sandbox-python` | python3, pip, poetry, ruff, pyright, uv | `~/.cache/pip`, `~/.cache/pypoetry`, `~/.cache/uv` |\n| **Rust** | `claude-sandbox-rust` | rustc, cargo, rust-analyzer, clippy, rustfmt | `~/.cargo/registry`, `~/.cargo/git` |\n| **C++** | `claude-sandbox-cpp` | gcc, clang, cmake, make, clang-tools | `~/.cache/ccache`, `~/.ccache` |\n| **JavaScript** | `claude-sandbox-js` | nodejs, yarn, pnpm, bun, typescript, eslint, prettier | `~/.npm`, `~/.yarn`, `~/.bun`, pnpm store |\n| **DevOps** | `claude-sandbox-devops` | docker, kubectl, terraform, helm, awscli2, pgcli | `~/.kube`, `~/.aws`, `~/.cache/helm`, `~/.terraform.d` |\n\n## Extensible API\n\n### Core Functions\n\n#### `mkSandbox`\nCreates a sandbox package from a profile specification.\n\n```nix\nbwLib.mkSandbox {\n  name = \"my-sandbox\";  # required\n  packages = with pkgs; [ git vim ];  # required\n  env = { VAR = \"value\"; };  # optional environment variables\n  preStartHooks = [  # optional runtime hooks\n    ''export SECRET=\"$(cat /path/to/secret)\"''\n    ''echo \"Setup complete\"''\n  ];\n  args = [ \"--ro-bind /path /path\" ];  # optional bubblewrap arguments\n  allowList = [\"api.example.com\" \"cdn.example.com\"];  # optional proxy allowlist\n  customPrompt = \"You are an expert in...\";  # optional system prompt\n}\n```\n\n#### `mkDevShell`\nCreates a development shell with sandbox tools available.\n\n```nix\nbwLib.mkDevShell {\n  packages = with pkgs; [ docker kubectl ];  # optional additional packages\n  shellHook = \"echo 'Welcome!'\";  # optional shell initialization\n}\n```\n\n#### `profiles`\nAccess to built-in profile definitions.\n\n```nix\n# Use existing profile\nbwLib.mkSandbox bwLib.profiles.go\n\n# Extend existing profile\nbwLib.mkSandbox (bwLib.deriveProfile bwLib.profiles.python {\n  packages = with pkgs; [ jupyter ];\n  env = { JUPYTER_CONFIG_DIR = \"/tmp/jupyter\"; };\n})\n```\n\n#### `deriveProfile`\nExtends a base profile with additional configuration.\n\n```nix\nbwLib.deriveProfile baseProfile {\n  name = \"extended-profile\";  # optional: override name\n  packages = with pkgs; [ extra-tool ];  # additional packages\n  env = { EXTRA_VAR = \"value\"; };  # additional environment variables\n  preStartHooks = [  # additional runtime hooks\n    ''export API_KEY=\"$(cat /run/secrets/key)\"''\n  ];  # inherits parent hooks and adds these\n  args = [ \"--extra-arg\" ];  # additional bubblewrap arguments\n  allowList = [\"api.example.com\"];  # additional allowed domains\n  customPrompt = \"You are an expert in...\";  # custom system prompt\n}\n```\n\n## Base Sandbox Tools\n\nAll profiles include these core utilities:\n\n**System**: bash, coreutils, diffutils, findutils, procps, which, file\n**Version Control**: git, jujutsu\n**Text Processing**: ripgrep, fd, jq, yq, less, gawk, gnugrep, gnused\n**File Operations**: tree, rsync, zip/unzip, gnutar, gzip, patch\n**Editor**: vim, man\n\n## Usage Examples\n\n### Custom Development Environment\n\n```nix\nlet\n  myProfile = bwLib.deriveProfile bwLib.profiles.python {\n    name = \"data-science\";\n    packages = with pkgs; [\n      python3Packages.pandas\n      python3Packages.jupyter\n      python3Packages.matplotlib\n      R\n      sqlite\n    ];\n    env = {\n      JUPYTER_CONFIG_DIR = \"/tmp/jupyter\";\n      R_LIBS_USER = \"/tmp/R-libs\";\n    };\n    args = [\n      \"--ro-bind-try /home/$USER/datasets /home/$USER/datasets\"\n    ];\n  };\nin {\n  packages.${system}.data-science = bwLib.mkSandbox myProfile;\n}\n```\n\n### Multi-Language Project\n\n```nix\n{\n  packages.${system} = {\n    # Frontend development\n    frontend = bwLib.mkSandbox (bwLib.deriveProfile bwLib.profiles.js {\n      name = \"frontend\";\n      packages = with pkgs; [ sass tailwindcss ];\n    });\n\n    # Backend development\n    backend = bwLib.mkSandbox (bwLib.deriveProfile bwLib.profiles.go {\n      name = \"backend\";\n      packages = with pkgs; [ postgresql redis-cli ];\n      env = { DATABASE_URL = \"postgres://localhost/mydb\"; };\n    });\n\n    # Full-stack environment\n    fullstack = bwLib.mkSandbox {\n      name = \"fullstack\";\n      packages = bwLib.profiles.js.packages ++ bwLib.profiles.go.packages ++ (with pkgs; [\n        postgresql redis-cli sass tailwindcss\n      ]);\n      env = bwLib.profiles.js.env // bwLib.profiles.go.env // {\n        DATABASE_URL = \"postgres://localhost/mydb\";\n      };\n      args = bwLib.profiles.js.args ++ bwLib.profiles.go.args;\n    };\n  };\n}\n```\n\n### Conditional Package Loading\n\n```nix\nlet\n  conditionalPackages = with pkgs; [\n    git vim jq\n  ] ++ lib.optionals stdenv.isLinux [\n    docker systemd\n  ] ++ lib.optionals (system == \"x86_64-linux\") [\n    podman buildah\n  ];\nin {\n  packages.${system}.platform-specific = bwLib.mkSandbox {\n    name = \"platform-sandbox\";\n    packages = conditionalPackages;\n    env = { PLATFORM = system; };\n  };\n}\n```\n\n## Security Model\n\n- **Process isolation**: Complete namespace isolation with `--unshare-all`\n- **Filesystem restrictions**: Only project directory and `/tmp` are writable\n- **Network access**: Controlled via HTTP proxy with domain allowlist filtering\n- **Configuration persistence**: Host `~/.claude.json` automatically mounted if present\n- **Cache management**: Language-specific caches mounted read-only where appropriate\n- **Privilege separation**: Runs as host user with restricted capabilities\n- **Telemetry disabled**: All Claude Code telemetry and auto-updates disabled\n\n## Advanced Configuration\n\n### Custom Hosts and Network\n\nProfiles automatically configure network access for Claude Code's API. HTTP proxy filtering is applied to restrict access to allowed domains only:\n\n```nix\nbwLib.mkSandbox {\n  name = \"custom-network\";\n  packages = with pkgs; [ curl ];\n  allowList = [\n    \"custom-api.example.com\"\n    \"cdn.custom-api.example.com\"\n    \"github.com\"\n  ];\n}\n```\n\n### Custom System Prompts\n\nConfigure Claude Code's behavior with custom system prompts:\n\n```nix\nbwLib.mkSandbox {\n  name = \"specialized-assistant\";\n  packages = with pkgs; [ python3 ];\n  customPrompt = ''\n    You are an expert Python developer specializing in data science.\n    Always provide clean, well-documented code with type hints.\n    Focus on pandas, numpy, and matplotlib usage.\n  '';\n}\n```\n\n### Runtime Setup with Pre-start Hooks\n\nPre-start hooks execute shell commands when the sandbox starts, enabling runtime secret loading and dynamic configuration:\n\n```nix\nlet\n  devProfile = bwLib.deriveProfile bwLib.base {\n    name = \"development\";\n    env = {\n      NODE_ENV = \"development\";\n      DEBUG = \"app:*\";\n      LOG_LEVEL = \"debug\";\n    };\n    preStartHooks = [\n      # Load secrets from sops-nix at runtime\n      ''export ANTHROPIC_API_KEY=\"$(cat /run/secrets/claude-key)\"''\n      # Set up dynamic configuration\n      ''export PROJECT_ID=\"$(basename $(pwd))\"''\n      # Validate environment\n      ''if [ -z \"$ANTHROPIC_API_KEY\" ]; then echo \"Warning: API key not found\"; fi''\n    ];\n  };\n```\n\n## Requirements\n\n- Nix with flakes enabled\n- Linux (x86_64 or aarch64)\n- Bubblewrap (automatically included)\n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatgawin%2Fbubblewrap-claude","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatgawin%2Fbubblewrap-claude","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatgawin%2Fbubblewrap-claude/lists"}