diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md new file mode 100644 index 0000000..0d4fb1a --- /dev/null +++ b/.planning/REQUIREMENTS.md @@ -0,0 +1,131 @@ +# Requirements: claudebox + +**Defined:** 2026-04-09 +**Core Value:** Secrets never enter the Claude Code environment + +## v1 Requirements + +### Sandbox Core + +- [ ] **SAND-01**: Wrapper script produces a `claudebox` binary via Nix `writeShellApplication` +- [ ] **SAND-02**: bwrap sandbox starts with `--clearenv` — empty environment, only explicitly allowed vars pass through +- [ ] **SAND-03**: Environment allowlist includes only: HOME, PATH, TERM, EDITOR, LANG, LC_ALL, NIX_SSL_CERT_FILE, SSL_CERT_FILE, ANTHROPIC_API_KEY, USER, SHELL, XDG_RUNTIME_DIR +- [ ] **SAND-04**: Filesystem starts as tmpfs root — nothing from host is visible unless explicitly mounted +- [ ] **SAND-05**: CWD is bind-mounted read-write inside the sandbox +- [ ] **SAND-06**: `/nix/store` is mounted read-only inside the sandbox +- [ ] **SAND-07**: Nix daemon socket (`/nix/var/nix/daemon-socket`) is bind-mounted for `nix shell` / comma to work +- [ ] **SAND-08**: `~/.claudebox` on host is bind-mounted as `~/.claude` inside the sandbox +- [ ] **SAND-09**: Secret paths are never mounted: `~/.ssh`, `~/.gnupg`, `~/.aws`, `~/.config/gcloud`, age key paths, `/var/lib/tailscale` +- [ ] **SAND-10**: PATH inside sandbox contains only Nix store paths: coreutils, git, curl, jq, ripgrep, fd, nix, comma, bash +- [ ] **SAND-11**: Working `/tmp` (tmpfs), `/dev` (bwrap `--dev`), `/proc` (bwrap `--proc`) +- [ ] **SAND-12**: DNS resolution works inside sandbox (`/etc/resolv.conf` and its symlink targets mounted) +- [ ] **SAND-13**: SSL/TLS works inside sandbox (cert bundle mounted, `NIX_SSL_CERT_FILE` set) +- [ ] **SAND-14**: Exit code from Claude Code passes through to the wrapper's caller +- [ ] **SAND-15**: Signals (Ctrl+C) reach Claude Code via `exec` — no intermediate shell + +### Tool Provisioning + +- [ ] **TOOL-01**: comma (`,`) is available in sandbox PATH for on-demand tool installation +- [ ] **TOOL-02**: `nix shell` works inside the sandbox for installing arbitrary packages +- [ ] **TOOL-03**: Newly installed Nix store paths are visible inside sandbox (live bind mount) + +### User Experience + +- [ ] **UX-01**: Pre-launch env audit displays all env vars being passed into the sandbox on stderr +- [ ] **UX-02**: Pre-launch env audit prompts for confirmation before proceeding +- [ ] **UX-03**: `--yes` / `-y` flag skips the env audit confirmation +- [ ] **UX-04**: `--dry-run` flag prints the full bwrap command without executing +- [ ] **UX-05**: `--check` flag verifies bwrap exists, required Nix packages are available, and `~/.claudebox` exists +- [ ] **UX-06**: `claude --dangerously-skip-permissions` is always passed — the sandbox is the permission layer + +### Claude Awareness + +- [ ] **AWARE-01**: Default `CLAUDE.md` is created in `~/.claudebox/` on first run if not present +- [ ] **AWARE-02**: Injected CLAUDE.md tells Claude it's in a sandbox, how to use comma/nix for tools, and what's not available + +### Git Support + +- [ ] **GIT-01**: Git works inside the sandbox with a minimal `.gitconfig` (user name/email) +- [ ] **GIT-02**: `safe.directory` is configured to trust the mounted CWD + +### Nix Packaging + +- [ ] **NIX-01**: Project is a Nix flake with `claudebox` as default package +- [ ] **NIX-02**: All runtime dependencies are pinned via flake inputs +- [ ] **NIX-03**: `nix run` or `nix profile install` produces a working `claudebox` command + +## v2 Requirements + +### Network Isolation + +- **NET-01**: Block LAN/Tailscale access (RFC1918 + 100.64.0.0/10) while allowing internet egress +- **NET-02**: Network namespace with controlled outbound via slirp4netns or veth pair + +### Enhanced Security + +- **SEC-01**: Env var leak detection — regex scan for patterns like `*KEY*`, `*TOKEN*`, `*SECRET*` +- **SEC-02**: PID namespace isolation (`--unshare-pid`) +- **SEC-03**: Git credential isolation — sandbox-specific `.gitconfig` with HTTPS-only credential helpers + +### Extensibility + +- **EXT-01**: Project-local tool declarations via `.claudebox.toml` or `.claudebox/tools.txt` +- **EXT-02**: Additional mount paths via `--mount-ro` / `--mount-rw` flags +- **EXT-03**: Configurable security profiles (different postures for different projects) + +## Out of Scope + +| Feature | Reason | +|---------|--------| +| GUI/X11/Wayland passthrough | CLI tool, no desktop integration needed | +| Audio/PulseAudio/PipeWire | No audio needed for coding agent | +| DBus access | Common sandbox escape vector, not needed | +| Seccomp syscall filtering | Threat model is data exfiltration, not privilege escalation | +| Docker/OCI wrapping | Nix+bwrap is lighter and daemonless | +| NixOS module (services/programs) | Wrapper script derivation is sufficient | +| Multi-user / shareability | Personal tool for endurance | + +## Traceability + +| Requirement | Phase | Status | +|-------------|-------|--------| +| SAND-01 | — | Pending | +| SAND-02 | — | Pending | +| SAND-03 | — | Pending | +| SAND-04 | — | Pending | +| SAND-05 | — | Pending | +| SAND-06 | — | Pending | +| SAND-07 | — | Pending | +| SAND-08 | — | Pending | +| SAND-09 | — | Pending | +| SAND-10 | — | Pending | +| SAND-11 | — | Pending | +| SAND-12 | — | Pending | +| SAND-13 | — | Pending | +| SAND-14 | — | Pending | +| SAND-15 | — | Pending | +| TOOL-01 | — | Pending | +| TOOL-02 | — | Pending | +| TOOL-03 | — | Pending | +| UX-01 | — | Pending | +| UX-02 | — | Pending | +| UX-03 | — | Pending | +| UX-04 | — | Pending | +| UX-05 | — | Pending | +| UX-06 | — | Pending | +| AWARE-01 | — | Pending | +| AWARE-02 | — | Pending | +| GIT-01 | — | Pending | +| GIT-02 | — | Pending | +| NIX-01 | — | Pending | +| NIX-02 | — | Pending | +| NIX-03 | — | Pending | + +**Coverage:** +- v1 requirements: 31 total +- Mapped to phases: 0 +- Unmapped: 31 ⚠️ + +--- +*Requirements defined: 2026-04-09* +*Last updated: 2026-04-09 after initial definition*