claudebox/.planning/PROJECT.md

80 lines
4.2 KiB
Markdown

# 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-permissions` inside 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` / `-y` flag to skip the env audit and launch immediately
- [ ] Filesystem isolation: only CWD mounted read-write, plus `~/.claudebox` mapped to `~/.claude` inside 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 shell` or `, <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 `writeShellApplication` wrapping a bwrap invocation
- `~/.claudebox/` is the persistent config directory that gets bind-mounted as `~/.claude` inside the sandbox, keeping real `~/.claude` outside
- comma (`,`) is a tool that runs `nix 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 `--sandbox` or 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`):
1. Requirements invalidated? → Move to Out of Scope with reason
2. Requirements validated? → Move to Validated with phase reference
3. New requirements emerged? → Add to Active
4. Decisions to log? → Add to Key Decisions
5. "What This Is" still accurate? → Update if drifted
**After each milestone** (via `/gsd-complete-milestone`):
1. Full review of all sections
2. Core Value check — still the right priority?
3. Audit Out of Scope — reasons still valid?
4. Update Context with current state
---
*Last updated: 2026-04-09 after initialization*