Why Sandbox Claude Code?
Claude Code operates includes its own sandbox mechanism, but the Agent is able to override the sandbox by callingdangerouslyOverrideSandbox: true and access any file and perform any operation on the system.
This creates several risks:
- It could read sensitive files outside your project (SSH keys, cloud credentials)
- A prompt injection in a dependency could trigger unintended file access
- Mistakes in file operations could affect directories outside your workspace
Quick Start
- Read+write access to the current working directory
- Read+write access to
~/.claude(agent state, debug logs, project config) - Read+write access to
~/.claude.json(settings file) - Read+write access to
~/.vscode(VS Code extensions directory) - Read+write access to
~/Library/Application Support/Code(VS Code app data, macOS) - Network access enabled (required for Anthropic API)
- Interactive mode enabled (preserves TTY for Claude’s terminal UI)
- Automatic hook installation for sandbox-aware error handling
Custom Profile
If you need different permissions, create a custom profile at~/.config/nono/profiles/claude-code.toml:
Custom profiles with the same name override the built-in. Remove or rename the file to revert to the built-in profile.
Security Tips
Use Secrets Management
Instead of keeping your API key in environment variable exports or shell config files, load it from the system keystore: macOS:Restrict to Specific Projects
The built-in profile grants access to the current working directory (wherever you run the command). To limit access to a specific directory regardless of where you invoke it:Read-Only Mode
For code review or exploration where Claude shouldn’t modify files:Block Network for Offline Work
If you want to prevent any outbound connections (e.g., for reviewing local code without API calls):Enabling LSPs, Linters, and Dev Tools
Claude Code’s LSP plugins (pyright, rust-analyzer, etc.) spawn language servers as child processes. These spawns useposix_spawnp() which searches your PATH for the binary. If any PATH directory is unreadable to the sandbox, posix_spawnp() receives EPERM from the kernel and stops searching immediately (unlike ENOENT, which continues to the next entry).
nono’s built-in system paths cover standard directories (/usr/bin, /opt, etc.), but version managers and dev tools install binaries under ~/ which requires explicit read access.
Common home-directory PATH entries that need read access:
| Tool | Path |
|---|---|
| Rust / cargo | ~/.cargo/bin |
| Go | ~/go/bin |
| Python / pyenv | ~/.pyenv/shims, ~/.pyenv/bin |
| Node / fnm | ~/.local/share/fnm, ~/.local/state/fnm_multishells |
| Node / nvm | ~/.nvm |
| Haskell / ghcup | ~/.ghcup/bin |
| Ruby / rbenv | ~/.rbenv/shims, ~/.rbenv/bin |
| Local binaries | ~/.local/bin |
~/ entry that appears before the directory containing your LSP binary:
You only need
--read (not --allow) for these directories. This permits PATH lookup without granting write access.VS Code Extension
Claude Code installs a VS Code extension on startup. The built-in profile already grants write access to both~/.vscode and ~/Library/Application Support/Code (macOS). No additional flags are needed for VS Code extension installation.
Git Configuration
Claude Code reads git configuration for repository operations. The built-in profile already grants read access to~/.gitconfig and ~/.gitignore_global. No additional flags are needed for git operations.
Secretive (SSH Keys in Secure Enclave)
If you use Secretive to store SSH keys in the macOS Secure Enclave, git commit signing (git commit -S) needs access to the Secretive agent socket. A community profile is provided at data/profiles/claude-code-secretive.toml.
Install the profile:
- Read access to
~/.gitconfigand~/.ssh/config(git signing configuration) - Read access to the Secretive agent socket (
~/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh) - Read+write access to
~/.ssh/known_hosts(SSH may append new host keys)
The Secretive socket is a Unix domain socket, not a regular file. nono v0.4+ supports granting capabilities on sockets directly, so only the socket itself is exposed — not the entire container directory.
Overriding Profile Settings
CLI flags always take precedence over profile settings:Automatic Hook Integration
When you first runnono run --profile claude-code, nono automatically installs a hook that helps Claude understand sandbox restrictions. You’ll see:
- Detects sandbox errors - When Claude’s file operations fail due to sandbox restrictions
- Injects context - Tells Claude exactly which paths are allowed and blocked
- Provides guidance - Instructs Claude to suggest restarting with
--allowflags instead of attempting workarounds
~/.claude/CLAUDE.md with upfront sandbox instructions, so Claude understands the security boundaries before encountering errors.
The hook installation is idempotent - it only installs once and updates automatically when nono is upgraded. The hook only activates when running inside a nono sandbox (detected via
$NONO_CAP_FILE).