Trail of Bits Claude Code Config
Opinionated defaults, documentation, and workflows for Claude Code at Trail of Bits. Covers sandboxing, permissions, hooks, skills, MCP servers, and usage patterns we've found effective across security audits, development, and research.
Also see: skills · skills-curated · claude-code-devcontainer · dropkit
First-time setup:
git clone https://github.com/trailofbits/claude-code-config.git
cd claude-code-config
claudeThen inside the session, run /trailofbits:config. It walks you through installing each component, detects what you already have, and self-installs the command so future runs work from any directory. Run /trailofbits:config again after updates.
Contents
- Continuous Improvement
- Project-level CLAUDE.md
- Context Management
- Web Browsing
- Fast Mode
- Commands
- Writing Skills and Agents
- Recommended Skills
- Recommended MCP Servers
Getting Started
Read These First
Before configuring anything, read these to understand the context for why this setup works the way it does:
- Best practices for Claude Code -- Anthropic's official guide to working effectively with Claude Code
- Here's how I use LLMs to help me write code -- Simon Willison on practical LLM-assisted coding techniques
- AI-assisted coding for teams that can't get away with vibes -- Nilenso's playbook for teams integrating AI tools with high standards
- My AI Skeptic Friends Are All Nuts -- Thomas Ptacek on why dismissing LLMs for coding is a mistake
- Harness engineering -- OpenAI on building a product with zero manually-written code
Prerequisites
Terminal: Ghostty
Use Ghostty. It's the best terminal for Claude Code because it uses native Metal GPU rendering, so it handles the high-volume text output from long AI sessions without lag or memory bloat (~500MB vs ~8GB for two VS Code terminal sessions). Shift+Enter and key bindings work out of the box with no /terminal-setup needed, built-in split panes (Cmd+D / Cmd+Shift+D) let you run Claude Code alongside a dev server without tmux, and it never crashes during extended autonomous runs.
brew install --cask ghosttymacOS only. On Linux, see the Ghostty install docs. No Windows support yet -- use WezTerm there.
Tools
Install core tools via Homebrew:
brew install jq ripgrep fd ast-grep shellcheck shfmt \
actionlint zizmor macos-trash node@22 pnpm uvPython tools (via uv):
uv tool install ruff
uv tool install ty
uv tool install pip-auditRust toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install prek worktrunk cargo-deny cargo-carefulNode tools:
npm install -g oxlint agent-browserLM Studio (for local models):
curl -fsSL https://lmstudio.ai/install.sh | bashThis installs lms (the CLI) and llmster (the headless daemon). Or install the LM Studio desktop app if you prefer a GUI.
Shell Setup
Add to ~/.zshrc:
alias claude-yolo="claude --dangerously-skip-permissions"--dangerously-skip-permissions bypasses all permission prompts. This is the recommended way to run Claude Code for maximum throughput -- pair it with sandboxing (below).
If you're using local models, also add:
claude-local() {
ANTHROPIC_BASE_URL=http://localhost:1234 \
ANTHROPIC_AUTH_TOKEN=lmstudio \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
claude --model qwen/qwen3-coder-next "$@"
}claude-local wraps claude with the local server env vars and disables telemetry pings that won't reach Anthropic anyway. Use it anywhere you'd normally run claude.
Settings
Copy settings.json to ~/.claude/settings.json (or merge entries into your existing file). The $schema key enables autocomplete and validation in editors that support JSON Schema. The template includes:
env(privacy) -- disables three non-essential outbound streams: Statsig telemetry (DISABLE_TELEMETRY), Sentry error reporting (DISABLE_ERROR_REPORTING), and feedback surveys (CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY). Avoid the umbrellaCLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC-- it also disables auto-updates.env(agent teams) --CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSenables multi-agent teams where one session coordinates multiple teammates with independent context windows. Experimental -- known limitations around session resumption and task coordination.enableAllProjectMcpServers: false-- this is the default, set explicitly so it doesn't get flipped by accident. Project.mcp.jsonfiles live in git, so a compromised repo could ship malicious MCP servers.alwaysThinkingEnabled: true-- persists extended thinking across sessions. Toggle per-session withOption+T. Adds latency and cost on simple tasks; worth it for complex reasoning.permissions-- deny rules that block reading credentials/secrets and editing shell config (see Sandboxing)cleanupPeriodDays: 365-- keeps conversation history for a year instead of the default 30 days, so/insightshas more datahooks-- twoPreToolUsehooks on Bash that blockrm -rfand direct push to main (see Hooks)statusLine-- points to the statusline script (see below)
Statusline
A two-line status bar at the bottom of the terminal:
[Opus 4.6] 📁 claude-code-config │ 🌿 main
████⣿⣿⣿⣿⣿⣿⣿⣿ 28% │ $0.83 │ ⏱ 12m 34s ↻89%Line 1 shows the model, current folder, and git branch. Line 2 shows a visual context usage bar (color-coded: green <50%, yellow 50-79%, red 80%+), session cost, elapsed time, and prompt cache hit rate.
Copy the script:
mkdir -p ~/.claude
cp scripts/statusline.sh ~/.claude/statusline.sh
chmod +x ~/.claude/statusline.shThe statusLine entry in settings.json points to this script. Requires jq.
Global CLAUDE.md
The global CLAUDE.md file at ~/.claude/CLAUDE.md sets default instructions for every Claude Code session. It covers development philosophy (no speculative features, no premature abstraction, replace don't deprecate), code quality hard limits (function length, complexity, line width), language-specific toolchains for Python (uv, ruff, ty), Node/TypeScript (oxlint, vitest), Rust (clippy, cargo deny), Bash, and GitHub Actions, plus testing methodology, code review order, and workflow conventions (commits, hooks, PRs).
Copy the template into place:
cp claude-md-template.md ~/.claude/CLAUDE.mdReview and customize it for your own preferences. The template is opinionated -- adjust the language sections, tool choices, and hard limits to match your stack. For background on how CLAUDE.md files work (hierarchy, auto memory, modular rules, imports), see Manage Claude's memory.
Configuration
Sandboxing
At Trail of Bits we run Claude Code in bypass-permissions mode (--dangerously-skip-permissions). This means you need to understand your sandboxing options -- the agent will execute commands without asking, so the sandbox is what keeps it from doing damage.
Built-in sandbox (/sandbox)
Claude Code has a native sandbox that provides filesystem and network isolation using OS-level primitives (Seatbelt on macOS, bubblewrap on Linux). Enable it by typing /sandbox in a session. In auto-allow mode, Bash commands that stay within sandbox boundaries run without permission prompts.
Default behavior: Writes are restricted to the current working directory and its subdirectories. Reads are unrestricted -- the agent can still read ~/.ssh, ~/.aws, etc. Network access is limited to explicitly allowed domains.
Hardening reads: The settings.json template includes Read and Edit deny rules that block access to credentials and secrets:
- SSH/GPG keys --
~/.ssh/**,~/.gnupg/** - Cloud credentials --
~/.aws/**,~/.azure/**,~/.kube/**,~/.docker/config.json - Package registry tokens --
~/.npmrc,~/.npm/**,~/.pypirc,~/.gem/credentials - Git credentials --
~/.git-credentials,~/.config/gh/** - Shell config --
~/.bashrc,~/.zshrc(edit denied, prevents backdoor planting) - macOS keychain --
~/Library/Keychains/** - Crypto wallets -- metamask, electrum, exodus, phantom, solflare app data
Without /sandbox, deny rules only block Claude's built-in tools -- Bash commands bypass them. With /sandbox enabled, the same rules are enforced at the OS level (Seatbelt/bubblewrap), so Bash commands are also blocked. Use both.
For the design rationale behind sandboxing, see Anthropic's engineering blog post. For the full configuration reference, see the sandboxing docs.
Devcontainer
For full read and write isolation, use a devcontainer. The agent runs in a container with only the project files mounted -- it has no access to your host filesystem, SSH keys, cloud credentials, or anything else outside the container.
- trailofbits/claude-code-devcontainer -- preconfigured devcontainer with VS Code integration, Claude Code pre-installed, and common development tools
Remote droplets
For complete isolation from your local machine, run the agent on a disposable cloud instance:
- trailofbits/dropkit -- CLI tool for managing DigitalOcean droplets with automated setup, SSH config, and Tailscale VPN. Create a droplet, SSH in, run Claude Code, destroy it when done.
Hooks
Hooks are shell commands (or LLM prompts) that fire at specific points in Claude Code's lifecycle. They are a way to talk to the LLM at decision points it wouldn't otherwise pause at. Every PreToolUse hook is a chance to say "stop, think about this" or "don't do that, do this instead." Every PostToolUse hook is a chance to say "now that you did that, here's what you should know." Every Stop hook is a chance to say "you're not done yet."
This is more powerful than system prompt instructions alone because hooks fire at specific, contextual moments. An instruction in your CLAUDE.md saying "never use rm -rf" can be forgotten or overridden by context pressure. A PreToolUse hook that blocks rm -rf fires every single time, with the error message right at the point of decision.
Hooks are not a security boundary -- a prompt injection can work around them. They are **structured prom
…