| name | claude-code-config-trailofbits |
| description | Configure Claude Code with Trail of Bits opinionated defaults for sandboxing, permissions, hooks, skills, and MCP servers |
| triggers | ["set up claude code with trail of bits config","configure claude code sandboxing and permissions","install trail of bits claude code defaults","add claude code hooks and statusline","configure claude code global CLAUDE.md","set up claude code with privacy and security settings","configure claude code for security audits","set up ghostty terminal for claude code"] |
Claude Code Config (Trail of Bits)
Skill by ara.so — Claude Code Skills collection.
Trail of Bits' opinionated configuration for Claude Code covering sandboxing, permission deny rules, lifecycle hooks, statusline, global CLAUDE.md, and recommended tooling. This skill helps you install and configure the Trail of Bits defaults for secure, high-throughput AI-assisted development.
What It Does
This project provides:
- Privacy-first settings — disables telemetry, error reporting, and feedback surveys
- Security hardening — permission deny rules blocking SSH keys, cloud credentials, shell config, crypto wallets
- Lifecycle hooks —
PreToolUse blocks on rm -rf and direct push to main
- Statusline — two-line terminal status bar showing model, context usage, cost, cache hit rate
- Global CLAUDE.md — development philosophy, code quality limits, language-specific toolchains
- Sandboxing guide — built-in
/sandbox, devcontainer, and remote droplet options
- Recommended tools — Ghostty terminal,
ruff, ast-grep, oxlint, cargo-deny, etc.
Installation
Prerequisites
Install Ghostty (macOS):
brew install --cask ghostty
Install core tools:
brew install jq ripgrep fd ast-grep shellcheck shfmt \
actionlint zizmor macos-trash node@22 pnpm uv
uv tool install ruff
uv tool install ty
uv tool install pip-audit
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install prek worktrunk cargo-deny cargo-careful
npm install -g oxlint agent-browser
Clone and Run Setup
git clone https://github.com/trailofbits/claude-code-config.git
cd claude-code-config
claude
Inside the Claude Code session:
/trailofbits:config
This walks through installing each component, detects existing config, and self-installs the command for future runs.
Manual Installation
If you prefer manual setup:
cp settings.json ~/.claude/settings.json
cp claude-md-template.md ~/.claude/CLAUDE.md
mkdir -p ~/.claude
cp scripts/statusline.sh ~/.claude/statusline.sh
chmod +x ~/.claude/statusline.sh
echo 'alias claude-yolo="claude --dangerously-skip-permissions"' >> ~/.zshrc
Settings Configuration
The settings.json includes:
Privacy Environment Variables
{
"env": {
"DISABLE_TELEMETRY": "1",
"DISABLE_ERROR_REPORTING": "1",
"CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY": "1"
}
}
Agent Teams (Experimental)
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
Permission Deny Rules
{
"permissions": [
{
"action": "Read",
"denied": true,
"patterns": [
"~/.ssh/**",
"~/.gnupg/**",
"~/.aws/**",
"~/.azure/**",
"~/.kube/**",
"~/.docker/config.json",
"~/.npmrc",
"~/.npm/**",
"~/.pypirc",
"~/.gem/credentials",
"~/.git-credentials",
"~/.config/gh/**",
"~/Library/Keychains/**",
"~/Library/Application Support/Google/Chrome/Default/Login Data*",
"~/Library/Application Support/Google/Chrome/Default/Cookies*"
]
},
{
"action": "Edit",
"denied": true,
"patterns": [
"~/.bashrc",
"~/.zshrc",
"~/.bash_profile",
"~/.zprofile"
]
}
]
}
Hooks
{
"hooks": [
{
"type": "PreToolUse",
"tool": "Bash",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm\\s+(-[^\\s]*r[^\\s]*f|[^\\s]*-[^\\s]*f[^\\s]*r)'; then echo 'Blocked: rm -rf detected. Use trash instead.'; exit 1; fi"
},
{
"type": "PreToolUse",
"tool": "Bash",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'git\\s+push.*\\s+(origin\\s+)?(main|master)'; then echo 'Blocked: Direct push to main/master. Use a branch and PR.'; exit 1; fi"
}
]
}
Other Settings
{
"enableAllProjectMcpServers": false,
"alwaysThinkingEnabled": true,
"cleanupPeriodDays": 365,
"statusLine": "~/.claude/statusline.sh"
}
Statusline Script
The statusline script (~/.claude/statusline.sh) generates a two-line status bar:
[Opus 4.6] 📁 claude-code-config │ 🌿 main
████⣿⣿⣿⣿⣿⣿⣿⣿ 28% │ $0.83 │ ⏱ 12m 34s ↻89%
Requirements: jq must be installed.
Example script structure:
#!/bin/bash
SESSION_FILE="$HOME/.claude/session-info.json"
if [[ ! -f "$SESSION_FILE" ]]; then
echo ""
echo ""
exit 0
fi
MODEL=$(jq -r '.model // "Unknown"' "$SESSION_FILE")
FOLDER=$(basename "$(pwd)")
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "no-git")
echo " [$MODEL] 📁 $FOLDER │ 🌿 $BRANCH"
echo " ████⣿⣿⣿⣿⣿⣿⣿⣿ 28% │ \$0.83 │ ⏱ 12m 34s ↻89%"
Global CLAUDE.md
The global ~/.claude/CLAUDE.md sets default instructions for all sessions. Key sections:
Development Philosophy
## Philosophy
- **No speculative features** — build what's asked, not what might be needed
- **No premature abstraction** — repeat yourself until the pattern is clear
- **Replace don't deprecate** — cut old code instead of maintaining compatibility layers
- **One entry point per decision** — DRY for logic, not for structure
Code Quality Hard Limits
## Hard Limits
- Function length: 50 lines (excluding tests)
- Cyclomatic complexity: 10
- Line width: 100 characters
- Function parameters: 5
- Nesting depth: 4
Language Toolchains
Python:
## Python
- Package manager: `uv` (not pip, not poetry)
- Linter: `ruff check` (not pylint, not flake8)
- Formatter: `ruff format` (not black)
- Type checker: `ty` (not mypy)
- Security: `pip-audit`
- Test runner: `pytest`
Node/TypeScript:
## Node/TypeScript
- Package manager: `pnpm` (not npm, not yarn)
- Linter: `oxlint` (not eslint)
- Formatter: `prettier`
- Type checker: `tsc`
- Test runner: `vitest` (not jest)
Rust:
## Rust
- Linter: `cargo clippy`
- Formatter: `cargo fmt`
- Security: `cargo deny`, `cargo audit`
- Test runner: `cargo test`, `cargo careful`
Bash:
## Bash
- Linter: `shellcheck`
- Formatter: `shfmt`
- Always use `set -euo pipefail`
- Quote all variables: `"$var"` not `$var`
Sandboxing
Built-in Sandbox
Enable the built-in sandbox:
/sandbox
This provides:
- Filesystem isolation — writes restricted to current directory
- Network isolation — limited to allowed domains
- OS-level enforcement — Seatbelt (macOS) or bubblewrap (Linux)
With /sandbox enabled + permission deny rules, Bash commands are blocked from reading SSH keys, cloud credentials, etc.
Devcontainer
For full read/write isolation:
git clone https://github.com/trailofbits/claude-code-devcontainer.git
cd claude-code-devcontainer
The agent runs in a container with only project files mounted — zero host filesystem access.
Remote Droplet
For complete machine-level isolation:
git clone https://github.com/trailofbits/dropkit.git
cd dropkit
./dropkit create my-dev-box
./dropkit ssh my-dev-box
claude
./dropkit destroy my-dev-box
Shell Aliases
Bypass Permissions (Recommended)
alias claude-yolo="claude --dangerously-skip-permissions"
Use claude-yolo instead of claude for maximum throughput. Requires sandboxing.
Local Models
claude-local() {
ANTHROPIC_BASE_URL=http://localhost:1234 \
ANTHROPIC_AUTH_TOKEN=lmstudio \
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
claude --model qwen/qwen3-coder-next "$@"
}
Requires LM Studio running locally:
curl -fsSL https://lmstudio.ai/install.sh | bash
Hooks Deep Dive
Hooks fire at lifecycle decision points. Three types:
PreToolUse
Fires before Claude executes a tool. Can block execution.
Example: Block rm -rf
if echo "$CLAUDE_TOOL_INPUT" | grep -qE 'rm\s+(-[^\s]*r[^\s]*f|-[^\s]*f[^\s]*r)'; then
echo 'Blocked: rm -rf detected. Use trash instead.'
exit 1
fi
Example: Block direct push to main
if echo "$CLAUDE_TOOL_INPUT" | grep -qE 'git\s+push.*(origin\s+)?(main|master)'; then
echo 'Blocked: Direct push to main/master. Use a branch and PR.'
exit 1
fi
Example: LLM prompt hook (check test coverage)
{
"type": "PreToolUse",
"tool": "Bash",
"prompt": "If this command runs tests, confirm that it includes coverage reporting and that coverage is above 80%. If not, suggest adding coverage flags."
}
PostToolUse
Fires after Claude executes a tool. Can inject context.
Example: Remind about commit message format
{
"type": "PostToolUse",
"tool": "Bash",
"prompt": "If the command was 'git commit', remind the user that commit messages should follow Conventional Commits format: type(scope): subject"
}
Stop
Fires when Claude thinks the task is complete.
Example: Check for todos before finishing
if grep -r "TODO\\|FIXME\\|XXX" .; then
echo 'Found TODOs in code. Review before marking complete.'
exit 1
fi
Project-Level CLAUDE.md
Projects can have their own CLAUDE.md that overrides or extends global rules:
cat > CLAUDE.md << 'EOF'
This is a security auditing tool for smart contracts. Prioritize:
- No dependencies outside stdlib where possible
- All inputs treated as untrusted
- Detailed logging for audit trails
- Use `slither` for Solidity analysis
- Use `mythril` for symbolic execution
- Generate reports in Markdown format
- All findings must be reproducible with test cases
- Include proof-of-concept exploits in `tests/exploits/`
EOF
Global ~/.claude/CLAUDE.md still applies — project file adds to it.
Commands
Inside a Claude Code session:
/trailofbits:config # Run setup wizard
/sandbox # Enable built-in sandbox
/thinking # Toggle extended thinking (or Option+T)
/insights # Show productivity insights (requires >30 days history)
/terminal-setup # Configure terminal key bindings (not needed for Ghostty)
Skills and MCP Servers
Installing Skills
Trail of Bits maintains curated skill collections:
git clone https://github.com/trailofbits/skills.git ~/.claude/skills
git clone https://github.com/trailofbits/skills-curated.git ~/.claude/skills
Skills auto-load when Claude Code starts. Reference in global CLAUDE.md:
## Skills
Load skills from ~/.claude/skills/ for:
- Security auditing workflows
- Rust development patterns
- Smart contract analysis
MCP Servers
Security note: Set enableAllProjectMcpServers: false in settings. Project .mcp.json files can ship malicious servers.
Recommended global MCP servers (add to ~/.mcp.json):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
Only install MCP servers you trust. They run with full Claude Code permissions.
Troubleshooting
Statusline not showing
Check that jq is installed:
which jq || brew install jq
Verify script is executable:
chmod +x ~/.claude/statusline.sh
Permission deny rules not working
Deny rules only block Claude's built-in tools. To enforce at OS level:
/sandbox
Hooks not firing
Check hook syntax in ~/.claude/settings.json:
jq '.hooks' ~/.claude/settings.json
Test hook command manually:
CLAUDE_TOOL_INPUT="rm -rf /tmp/test" bash -c 'if echo "$CLAUDE_TOOL_INPUT" | grep -qE "rm\\s+(-[^\\s]*r[^\\s]*f|-[^\\s]*f[^\\s]*r)"; then echo "Blocked"; exit 1; fi'
Global CLAUDE.md ignored
Check file exists:
cat ~/.claude/CLAUDE.md
Restart Claude Code session to reload.
Ghostty Shift+Enter not working
Ghostty supports Shift+Enter out of the box — no /terminal-setup needed. If it's not working, check Ghostty version:
ghostty --version
Update to latest:
brew upgrade ghostty
Best Practices
- Always use sandboxing — either
/sandbox, devcontainer, or remote droplet
- Run in bypass mode —
claude-yolo for maximum throughput (requires sandboxing)
- Review global CLAUDE.md monthly — update toolchain, limits, and patterns as your workflow evolves
- Add project-specific CLAUDE.md — don't put project rules in global file
- Test hooks before deploying — a bad hook can block all Bash commands
- Use Ghostty — prevents memory bloat and lag in long sessions
- Keep history long — set
cleanupPeriodDays: 365 for better /insights
- Don't bypass deny rules — if Claude asks to read
~/.ssh, it's a red flag
Real-World Examples
Security Audit Workflow
dropkit create audit-project-x
dropkit ssh audit-project-x
git clone https://github.com/target/repo.git
cd repo
cat > CLAUDE.md << 'EOF'
Run these tools in order:
1. `slither .` for Solidity analysis
2. `mythril analyze contracts/*.sol` for symbolic execution
3. `cargo clippy` for Rust components
4. Generate findings report in `audit-report.md`
EOF
claude-yolo
/sandbox
Python Library Development
git clone https://github.com/trailofbits/claude-code-devcontainer.git my-lib
cd my-lib
cat > CLAUDE.md << 'EOF'
- `uv` for package management
- `ruff` for linting and formatting
- `ty` for type checking
- `pytest` with coverage >90%
- `src/my_lib/` for code
- `tests/` for tests (mirror src structure)
- `examples/` for usage examples
EOF
claude-yolo
Rust CLI Tool
cat > CLAUDE.md << 'EOF'
- `clap` for arg parsing
- `anyhow` for error handling
- `tokio` for async runtime
- All deps pass `cargo deny` (no GPL, no vulnerabilities)
- Unit tests for all logic
- Integration tests in `tests/`
- `cargo careful` for unsafe code checks
EOF
Additional Resources