4.2 KiB
4.2 KiB
claudebox
What This Is
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.
Requirements
Validated
(None yet — ship to validate)
Active
- Wrapper script that execs
claude --dangerously-skip-permissionsinside a bwrap sandbox - Environment allowlist: start with empty env, explicitly pass only known-safe vars (HOME, PATH, TERM, EDITOR, LANG, etc.)
- Pre-launch env audit: before running, list all env vars being passed in so the user can review for secrets. Proceed on confirmation, abort on rejection
--yes/-yflag to skip the env audit and launch immediately- Filesystem isolation: only CWD mounted read-write, plus
~/.claudeboxmapped to~/.claudeinside the sandbox - Secret paths hidden:
~/.ssh,~/.gnupg,~/.config/gcloud,~/.aws, Tailscale state, age keys — none of these visible inside the sandbox - Minimal PATH: Nix store paths only — coreutils, git, curl, jq, ripgrep, fd, nix, comma
- Claude can self-install tools via
nix shellor, <tool>(comma) inside the sandbox - Default prompt/instructions injected so Claude knows how to use nix/comma to get dev tools
- Works on endurance (NixOS desktop)
Out of Scope
- Network isolation — trusting Claude Code's built-in proxy for domain allowlisting
- NixOS module form — this is a wrapper script derivation, not a services/programs module
- Configurable per-project profiles — v1 is one tool set, profiles come later
- Shareability — personal tool first, not designed for others yet
Context
- Target machine: endurance (NixOS desktop)
- Claude Code already has bubblewrap sandboxing (
--sandbox) but it doesn't control env vars or secret file visibility — that's claudebox's job - bwrap is in nixpkgs, so the derivation uses
writeShellApplicationwrapping a bwrap invocation ~/.claudebox/is the persistent config directory that gets bind-mounted as~/.claudeinside the sandbox, keeping real~/.claudeoutside- comma (
,) is a tool that runsnix shell nixpkgs#<pkg> -c <pkg>— lets Claude pull in any tool on demand without pre-declaring it - The Nix store needs to be mounted read-only inside the sandbox for nix/comma to work
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
--sandboxor Nix's build sandbox - Env model: Allowlist, not denylist — start empty, add explicitly
Key Decisions
| Decision | Rationale | Outcome |
|---|---|---|
| Own bwrap over Claude's --sandbox | Full control over mounts, env, namespaces | — Pending |
| Env allowlist over denylist | Denylist misses unknown vars; allowlist is secure by default | — Pending |
| comma for tool access | Claude can pull any tool on demand without pre-declaring PATH entries | — Pending |
| --dangerously-skip-permissions always | The bwrap sandbox IS the permission layer — Claude's prompts are redundant | — Pending |
| Pre-launch env audit | User reviews exactly what enters the sandbox, catches leaks before they happen | — Pending |
Evolution
This document evolves at phase transitions and milestone boundaries.
After each phase transition (via /gsd-transition):
- Requirements invalidated? → Move to Out of Scope with reason
- Requirements validated? → Move to Validated with phase reference
- New requirements emerged? → Add to Active
- Decisions to log? → Add to Key Decisions
- "What This Is" still accurate? → Update if drifted
After each milestone (via /gsd-complete-milestone):
- Full review of all sections
- Core Value check — still the right priority?
- Audit Out of Scope — reasons still valid?
- Update Context with current state
Last updated: 2026-04-09 after initialization