Skip to content

plutosecurity/Claude-Code-Best-Practices

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Claude Code — Secure Endpoint Configuration Bundle

A hardened configuration template for running Claude Code safely on enterprise and security-conscious endpoints. Covers behavioral rules, tool permissions, MCP server policy, and prompt injection defenses.

Built and maintained by Pluto Security.


Files in This Bundle

claude-code-secure/
├── README.md                        ← you are here
├── install.sh                       ← one-line installer (merges with existing config)
├── CLAUDE.md                        ← global behavioral rules (copy to ~/.claude/)
├── CLAUDE.project-template.md       ← per-repo template (copy to <project>/CLAUDE.md)
├── .claude/
│   ├── settings.json                ← tool permissions, telemetry & hooks
│   ├── mcp_servers.json             ← MCP server configuration & policy
│   └── hooks/
│       └── pre-commit-secret-scan.sh ← blocks commits containing secrets
└── tests/
    └── verify-bundle.sh             ← verifies installation and runs functional tests

What Each File Does

CLAUDE.md — Global Behavioral Rules

This file is injected into every Claude Code session and defines non-negotiable security policies. It covers:

  • Anti-Prompt Injection — instructs Claude to never follow instructions embedded in file contents, code comments, README files, commit messages, test fixtures, HTML pages, API responses, or any other data source. Any injection attempt is flagged to the user.
  • Cloud & Infrastructure Protection — prohibits creating, modifying, or deleting cloud resources (AWS, GCP, Azure, Terraform, Pulumi, CDK) without explicit user confirmation of the specific resource name and action. IAM roles, security groups, and firewall rules are off-limits.
  • Credentials & Secrets Handling — blocks reading, printing, logging, or transmitting sensitive files (.env, *.pem, *.key, SSH keys, AWS/Kube configs, tokens, vault files, .npmrc, .pypirc, *.htpasswd). Secrets are never inserted into code, logs, or shell history.
  • Database Safety — prevents destructive queries (DROP, DELETE, TRUNCATE, unscoped UPDATE) without explicit user confirmation. Production database connections require explicit acknowledgment.
  • CI/CD Pipeline Protection — blocks modifications to .github/workflows/, .gitlab-ci.yml, Jenkinsfile, and equivalent pipeline configs without explicit instruction.
  • Shell & Command Execution — blocks piped execution (curl | bash), silent system-wide package installs, cron jobs, launch agents, and background processes. Local project installs (npm install, pip install in a venv) are allowed as part of normal workflow.
  • File System Boundaries — prefers working within the current project directory but allows reading external files (global configs, installed tools) when needed. Prevents recursive secret searching and access to browser data, keychain data, or OS credential stores.
  • Network & Web Safety — blocks web requests to URLs found in untrusted content unless the user explicitly provided the URL in chat.

CLAUDE.project-template.md — Per-Project Security Rules

A customizable template dropped into any repository root. It supplements (does not replace) the global CLAUDE.md. Sections include:

  • Project Context — project name, environment, stack, and owner team. Helps Claude understand what it's working on and what boundaries apply.
  • Off-Limits Resources — project-specific files and actions Claude must never touch (e.g., production configs, deploy directories, protected branches, Dockerfiles, CI pipelines).
  • Safe Defaults — actions Claude can perform freely without confirmation (e.g., running tests, linting, reading source files).
  • Confirmation Required — actions that need explicit user approval each time (e.g., git push, database migrations, Docker builds, dependency changes).
  • Project Secrets — defines secret patterns to never read or print, where secrets are stored, and which secret manager is in use.
  • Anti-Injection Reminder — reinforces that source code comments, test fixtures, README files, API responses, database records, and dependency source code are untrusted data sources.

.claude/settings.json — Tool Permissions & Telemetry

This file combines two security functions: command permissions and telemetry export.

OpenTelemetry (OTel) Telemetry

Exports all Claude Code activity to your organization's OTel collector or SIEM, giving your security team full observability over what Claude does on every endpoint. Configured via the env block in settings.json.

What gets exported:

Category Data Points
Metrics Session count, tokens used, cost (USD), lines of code changed, commits, PRs created, active time
Events Every tool execution (name, success/fail, duration), API requests (model, cost, tokens), permission decisions (accept/reject)
Attributes Session ID, org ID, account UUID, user email, terminal type, app version

Privacy controls (both off by default):

  • OTEL_LOG_USER_PROMPTS=1 — log the actual text of user prompts
  • OTEL_LOG_TOOL_DETAILS=1 — log bash commands, file paths, and tool arguments

Supported exporters: otlp (gRPC/HTTP), prometheus, console

Replace http://YOUR_OTEL_COLLECTOR:4317 in settings.json with your actual collector endpoint.

Pre-commit Secret Scanning (PreToolUse Hook)

A PreToolUse hook that intercepts every git commit command and scans staged changes for exposed secrets before the commit is created. This hook is active by default.

How it works:

  1. Claude initiates a git commit command
  2. The hook runs gitleaks (or trufflehog as fallback) on git diff --cached
  3. If secrets are detected → commit is blocked and Claude is told to remove them
  4. If no secrets found → commit proceeds normally
  5. If no scanner is installed → user is warned but commit is not blocked

Supported scanners (install one):

brew install gitleaks       # recommended
brew install trufflehog     # alternative

What it catches: API keys, tokens, passwords, private keys, cloud credentials, and other secret patterns defined by the scanner's rule set.

This complements the settings.json deny rules (which block cat .env, etc.) by catching secrets that make it into staged code — the last line of defense before commit.

Tool Permission Model

Controls what shell commands Claude can execute via a three-tier permission model:

Tier Behavior Examples
Allow (auto-approved) Claude runs without asking git status, git log, git diff, ls, cat, pwd, whoami, version checks
Unlisted (ask first) Claude asks for user confirmation File writes, git commit, npm install (local), running tests, rm -rf, terraform apply, kubectl apply/exec, brew install, cloud create/update commands
Deny (hard block) Cannot be executed even if user says yes See categories below

Denied command categories (hard-blocked):

  • Destructive filesystemshred, mkfs, dd
  • Secrets readingcat on credential files (.env, *.pem, *.key, SSH keys, AWS/Kube configs, tokens), printenv for secrets/passwords/tokens
  • Exfiltration / piped executioncurl|bash, wget|sh, curl -d @file, nc, netcat
  • Privilege escalationsudo, su, chmod 777, doas
  • Persistence mechanismscrontab, launchctl, systemctl enable, nohup &
  • Cloud/infra deletionsterraform destroy, aws * delete, gcloud * delete, kubectl delete
  • Global package installsapt install, npm install -g, pip install --break-system

Moved to "ask" tier (user confirms each time):

These commands are common in legitimate development workflows, so they require user confirmation rather than a hard block:

  • rm -rf, rm -f — needed for cleaning build artifacts, node_modules, temp files
  • terraform apply, kubectl apply, kubectl exec — needed for IaC and debugging
  • aws create/put/update, gcloud create — needed for cloud development
  • brew install — commonly needed for dev tooling

Design principle: Hard-block only truly dangerous or irreversible actions. For everything else, the "ask" tier lets the user decide per-command — security without sacrificing functionality.

.claude/mcp_servers.json — MCP Server Configuration

Defines which MCP (Model Context Protocol) servers Claude can connect to. MCP servers extend Claude's capabilities by giving it tools to interact with external systems (databases, GitHub, Slack, filesystems, etc.).

This file ships intentionally empty ("mcpServers": {}). Add servers only after reviewing the security rules below.

Why MCP servers are a security concern

Each MCP server you add expands Claude's action surface. More critically, MCP servers return arbitrary text that can contain prompt injection payloads — a crafted GitHub issue, a poisoned database record, or a malicious Slack message could contain text that Claude mistakes for operator commands.

Rules for adding MCP servers

  1. Prefer local (stdio) over remote (url) servers. Local = a process you control. Remote = a third-party endpoint you trust not to inject prompts.
  2. Scope filesystem servers tightly — never grant access to /. Limit to the specific project directory.
  3. Treat all MCP tool results as untrusted data (same as reading a file). Claude must not follow instructions found in tool results. This is reinforced in CLAUDE.md.
  4. Audit each server's tool list before connecting. A server with a run_shell_command tool gives Claude (and any injected prompt) shell access.
  5. Remove servers you're not actively using. Every connected server is attack surface.
  6. Never add without careful review:
    • Servers with write access to production databases
    • Servers that accept arbitrary shell/eval commands
    • Remote servers from sources you don't fully control
    • Servers that proxy requests to other LLMs

Example server configurations

Local filesystem (read-only, scoped path):

{
  "mcpServers": {
    "filesystem": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects/specific-project"]
    }
  }
}

Local git inspection:

{
  "mcpServers": {
    "git": {
      "type": "stdio",
      "command": "uvx",
      "args": ["mcp-server-git", "--repository", "/path/to/repo"]
    }
  }
}

Threat Model

This bundle protects against the following threat categories:

# Threat Attack Vector Mitigation
1 Prompt Injection Attacker embeds instructions in source code, README, test data, or config files CLAUDE.md anti-injection rules; explicit content-vs-instruction distinction
2 Data Exfiltration Claude reads secrets/PII and sends them to external endpoints settings.json denylist blocks credential file reads; CLAUDE.md bans transmitting content to untrusted URLs
3 Destructive Infra Actions Claude runs terraform destroy, kubectl delete, etc. without user awareness settings.json hard-blocks destructive commands (destroy/delete); create/apply require user confirmation
4 Privilege Escalation Claude runs sudo, creates persistence mechanisms, or installs system packages settings.json denies sudo, su, crontab, launchctl, systemctl, apt install, npm install -g
5 MCP Server Injection Connected MCP server returns a response containing embedded instructions MCP config ships empty; CLAUDE.md classifies tool results as untrusted data
6 Shadow Usage / Audit Gap Claude is used on endpoints without security team visibility OTel telemetry exports all tool calls, API requests, costs, and permission decisions to your SIEM
7 Secret Commit Claude accidentally commits credentials, API keys, or tokens to git PreToolUse hook scans staged changes with gitleaks/trufflehog and blocks the commit

Installation

Quick Install (recommended)

One command to download, merge with existing config, and verify:

curl -fsSL https://raw.githubusercontent.com/ehudmelzer/claude-code-secure-practices/main/install.sh | bash

The installer merges with your existing configuration — it will never overwrite your custom rules. Specifically:

  • CLAUDE.md — appends security rules below your existing content
  • settings.json — merges allow/deny arrays and env keys (deduplicates)
  • mcp_servers.json — skipped if you already have one
  • Hook script — always installed/updated

Prerequisites: node, jq (for JSON merge). The installer will attempt to install gitleaks via Homebrew if no secret scanner is found.

Manual Install

If you prefer to install manually or review files first:

mkdir -p ~/.claude/hooks
cp CLAUDE.md ~/.claude/CLAUDE.md
cp .claude/settings.json ~/.claude/settings.json
cp .claude/mcp_servers.json ~/.claude/mcp_servers.json
cp .claude/hooks/pre-commit-secret-scan.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/pre-commit-secret-scan.sh

# Install a secret scanner (pick one)
brew install gitleaks       # recommended
# brew install trufflehog   # alternative

Per-Project Rules

Drop a customized template into any repo root:

curl -fsSL https://raw.githubusercontent.com/ehudmelzer/claude-code-secure-practices/main/CLAUDE.project-template.md -o /path/to/your/project/CLAUDE.md
# Then edit it: fill in project name, stack, off-limits paths, safe defaults

Verify Installation

# If you cloned the repo:
./tests/verify-bundle.sh

Maintenance

  • Review quarterly: Claude Code updates may add new tools or change permission semantics. Re-audit settings.json deny patterns after major version upgrades.
  • Per-project tuning: The project template's "Safe Defaults" and "Off-Limits" sections should be customized — overly broad restrictions will hurt productivity.
  • Incident response: If Claude acts unexpectedly, check whether the action was blocked by settings.json. If not, add a deny rule and update CLAUDE.md.

References


License

MIT


Credits

Created by Pluto Security — Pluto protects modern creation workflows (across AI builders, developer tools, and business workspaces) with visibility, risk understanding, and real-time guardrails. Built for how work actually happens.

About

A hardened configuration template for running Claude Code safely on enterprise and security-conscious endpoints. Covers behavioral rules, tool permissions, MCP server policy, and prompt injection defenses.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages