Back to Plugins

Trail of Bits Security

Opinionated security-first Claude Code configuration with sandboxing, permission rules, hooks, and security audit skills from professional security researchers

securityaudithardeningconfigurationcommunity
By Trail of Bits
2.0k151Updated 2 months agoShell

Installation

/plugin install trail-of-bits-security

Commands

security:auditRun a security audit on the current codebase
security:hardenApply security hardening to Claude Code settings
security:reviewSecurity-focused code review of recent changes

How to install

  1. Open Claude Code in your terminal
  2. Run the installation command above
  3. The plugin will be enabled automatically
  4. Use the plugin's features in your Claude Code sessions

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
claude

Then 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

Getting Started

Configuration

Usage

Getting Started

Read These First

Before configuring anything, read these to understand the context for why this setup works the way it does:

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 ghostty

macOS 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 uv

Python tools (via uv):

uv tool install ruff
uv tool install ty
uv tool install pip-audit

Rust toolchain:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install prek worktrunk cargo-deny cargo-careful

Node tools:

npm install -g oxlint agent-browser

LM Studio (for local models):

curl -fsSL https://lmstudio.ai/install.sh | bash

This 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 umbrella CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC -- it also disables auto-updates.
  • env (agent teams) -- CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS enables 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.json files live in git, so a compromised repo could ship malicious MCP servers.
  • alwaysThinkingEnabled: true -- persists extended thinking across sessions. Toggle per-session with Option+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 /insights has more data
  • hooks -- two PreToolUse hooks on Bash that block rm -rf and 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.sh

The 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.md

Review 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.

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

View source on GitHub