claudebox/CLAUDE.md

6.9 KiB

Project

claudebox

A Nix derivation that produces a claudebox wrapper script for Claude Code. It runs Claude inside a bubblewrap sandbox with an allowlisted environment, explicit filesystem mounts, and a minimal PATH — keeping SSH keys, GPG/age secrets, cloud tokens, and Tailscale state completely invisible to the AI agent.

Core Value: Secrets never enter the Claude Code environment. If a secret is accessible inside the sandbox, it's a bug.

Constraints

  • Stack: Nix derivation + shell script — no Docker, no systemd, no external dependencies beyond nixpkgs
  • Sandbox: Own bwrap call — not delegating to Claude Code's --sandbox or Nix's build sandbox
  • Env model: Allowlist, not denylist — start empty, add explicitly

Technology Stack

Core: Nix Derivation via writeShellApplication

Technology Version Purpose Why Confidence
writeShellApplication nixpkgs stable Produce the claudebox wrapper script Generates a shellcheck-validated bash script in the Nix store with runtime PATH wired to declared runtimeInputs. Superior to writeShellScriptBin because it runs shellcheck at build time and sets set -euo pipefail automatically. HIGH
bubblewrap (bwrap) 0.9.x+ Sandbox runtime Unprivileged user-namespace sandbox. In nixpkgs as bubblewrap. No setuid needed on NixOS (user namespaces enabled by default). HIGH
claude-code CLI The wrapped tool Provided by Anthropic's npm/standalone installer. Assumed pre-installed or passed as input. HIGH

Runtime Dependencies (runtimeInputs)

Package Purpose Why This One Confidence
bubblewrap Sandbox The whole point HIGH
coreutils Basic shell utils env, cat, echo, mkdir, etc. HIGH
git Version control Claude Code requires git for repo operations HIGH
curl HTTP requests Claude Code's MCP and tool use HIGH
jq JSON processing Env audit display, config manipulation HIGH
ripgrep Search Claude Code's preferred grep HIGH
fd File finding Claude Code's preferred find HIGH
nix Package manager Required for nix shell inside sandbox HIGH
comma On-demand packages Runs nix shell nixpkgs#<pkg> -c <cmd> via , <cmd> syntax HIGH
nix-index Package database Required by comma to resolve command -> package mapping HIGH
bash Shell bwrap needs a shell to exec into HIGH
nodejs Runtime Claude Code is a Node.js application HIGH

NOT in runtimeInputs (Important)

Package Why Excluded
gnupg Secret material -- explicitly hidden
openssh Secret material -- explicitly hidden
age / agenix Secret material -- explicitly hidden
tailscale Infrastructure access -- explicitly hidden

Key Nix Functions

writeShellApplication -- Use This

Why NOT These Alternatives

Alternative Why Not
writeShellScriptBin No shellcheck, no automatic set -euo pipefail, no runtimeInputs wiring. You'd have to manually construct PATH.
makeWrapper / wrapProgram Designed for wrapping existing binaries with env vars/flags. Overkill and wrong abstraction -- we're writing a new script, not patching an existing binary.
symlinkJoin + makeWrapper Pattern for combining multiple derivations. Not needed -- we have one script.
stdenv.mkDerivation Too heavy. writeShellApplication is a specialized shortcut for exactly this use case.
runCommand / writeScript Lower-level, no shellcheck, no runtimeInputs.

Bubblewrap Flags

Namespace Isolation

Filesystem Mounts

Mount Ordering Matters

Environment Handling

Process Execution

Comma and nix-index

How Comma Works

Packaging in nixpkgs

  • pkgs.comma -- the comma binary itself
  • pkgs.nix-index -- the indexer that builds/queries the database
  • Database: comma needs a pre-built index. Two options:

For claudebox

  • Mount ~/.cache/nix-index read-only into the sandbox (if using nix-index-database on the host)
  • Or use the nix-index-database flake's comma-with-db package which bundles the database

Flake Structure

Why builtins.readFile for the Script Body

  • Shell syntax highlighting in editors
  • Shellcheck can run independently
  • Easier to iterate on the script without touching Nix expressions
  • writeShellApplication still runs shellcheck on it at build time

PATH Construction Inside Sandbox

Nix Store Access Inside Sandbox

Testing Strategy

Sources

  • Training data knowledge of nixpkgs writeShellApplication (stable API since 2022)
  • Training data knowledge of bubblewrap (stable API, project is mature)
  • Training data knowledge of comma/nix-index-database (nix-community project)
  • All versions should be verified against current nixpkgs before implementation

Verification Checklist (for implementation phase)

  • Confirm bubblewrap version in current nixpkgs channel
  • Confirm comma and nix-index-database flake are current and compatible
  • Test Nix daemon socket access through bwrap bind mount
  • Test mount ordering with CWD under $HOME
  • Confirm --clearenv + --setenv pattern works with Claude Code (it may need vars we haven't listed)
  • Check if Claude Code needs ~/.local or ~/.config beyond ~/.claude

Conventions

Conventions not yet established. Will populate as patterns emerge during development.

Architecture

Architecture not yet mapped. Follow existing patterns found in the codebase.

Project Skills

No project skills found. Add skills to any of: .claude/skills/, .agents/skills/, .cursor/skills/, or .github/skills/ with a SKILL.md index file.

GSD Workflow Enforcement

Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.

Use these entry points:

  • /gsd-quick for small fixes, doc updates, and ad-hoc tasks
  • /gsd-debug for investigation and bug fixing
  • /gsd-execute-phase for planned phase work

Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.

Developer Profile

Profile not yet configured. Run /gsd-profile-user to generate your developer profile. This section is managed by generate-claude-profile -- do not edit manually.