Claude Code in production: the 30-point audit no one publishes
There is a standard security checklist for deploying a web app. There is no equivalent for deploying Claude Code. That gap has a cost: over the last 90 days, five teams that came to us for post-incident work had Claude Code running in their CI pipelines or on developer machines with configurations that exposed credentials, removed budget constraints, or created exploitable tool chains. None of them had done anything unusual. They had followed the official docs.
This checklist covers the 30 items we walk through on every Septim Audit engagement. The list is free. The audit is $99 and includes a written report, a prioritized fix list, and a 30-minute walkthrough call. If you can work through all 30 items yourself and score clean, you don't need the audit. Most teams find at least 6 problems they didn't know existed.
How to use this checklist
الأعمال through each section in order. Mark each item as Pass, Fail, or N/A. Any item marked Fail in sections 1, 2, or 3 is a blocking issue — stop and fix it before continuing. Items in sections 4 and 5 are important but not immediately dangerous.
The checklist is organized into five areas: Credential handling, Cost gates, Context hygiene, Hook configuration, and MCP exposure. Each area has a score breakdown at the end.
Section 1: Credential handling
Claude Code's default behavior is to read from the environment, which means it inherits whatever secrets are loaded in your shell at startup. On a developer machine, that can include AWS credentials, GitHub tokens, database connection strings, and Stripe API keys — all in the same environment that a BashTool call has access to. The pattern is not a bug in Claude Code; it is standard Unix process inheritance. The audit item is whether you have made that inheritance intentional rather than accidental.
Items 1 through 7
ANTHROPIC_API_KEY is set to a key scoped to a dedicated workspace, not your personal or org-root key. If the key leaks through a tool call, blast radius is bounded.~/.zshrc, ~/.bashrc, and ~/.profile do not export database URIs, Stripe live keys, or AWS credentials that have write permissions to production resources.CLAUDE.md files are often committed to version control. Confirm no API key, token, or password appears in any CLAUDE.md in the repo or home directory.BashTool calls, those calls execute as your current user. Confirm the user running Claude Code does not have write access to production infrastructure.AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY, if present, are scoped to read-only or dev-only IAM policies.git log --all -S "ANTHROPIC_API_KEY" -- CLAUDE.md and variants for your other secrets. Keys committed and then removed from HEAD are still exposed in history.secrets: inherit.Section 2: Cost gates
The April 2026 Tokenocalypse incidents — documented in GitHub issue anthropics/claude-code#41930 — had one structural cause: Claude Code subagents running unattended with no per-session or per-run spending ceiling. The existing tools (ccusage, workspace monthly caps, billing email alerts) operate at the observation layer; they report what happened. A cost gate operates at the enforcement layer; it halts what is about to happen. These 8 items check whether your setup has enforcement, not just observation.
Items 8 through 15
PreToolUse hook reads cumulative session cost from ~/.claude/projects/**/*.jsonl and exits the agent when the session exceeds a configured dollar ceiling. If this hook is absent, a single runaway session has no hard stop.cache_control breakpoints reduce that cost by approximately 90%. Verify caching is active for any context over 2,048 tokens that repeats across turns.PreToolUse hook fails silently.Section 3: Context hygiene
Context size is the single largest cost lever for day-to-day Claude Code use. A session that loads a 200KB codebase into every tool turn burns approximately 12 cents per turn at Sonnet 4.5 pricing. Over a 40-turn session, that is $4.80 in context cost alone, before any actual output. These items check whether what gets loaded into context on each turn is intentional.
Items 16 through 21
.claudeignore file present. The equivalent of .gitignore for what Claude Code loads. Without it, ReadFileTool will happily pull in node_modules, build artifacts, and binary assets into context. Minimum entries: node_modules/, .next/, dist/, *.lock, *.png, *.jpg, *.pdf.CLAUDE.md that runs 3,000 lines loads 3,000 lines on every session start. The 3,000-line CLAUDE.md problem is well-documented: it creates a context tax that compounds across every agent turn. Keep project-level CLAUDE.md under 500 lines; use sub-agent-specific files for domain detail./compact is run periodically by the operator, or the agent's system prompt instructs it to self-compact when the session approaches a token threshold. Sessions that run to 33MB+ become unstable and crash.Read("**/*.ts") in an agent's tool chain load the entire TypeScript surface of the repo on every invocation. These should be replaced with targeted reads of specific files identified by a prior search step.~/.claude/ memory files grow indefinitely if not managed. Stale project memory loads on every relevant session. Run a monthly audit of project memory files and remove anything that refers to closed work.Section 4: Hook configuration
Claude Code's hook system (PreToolUse, PostToolUse, Stop, Notification) is the main surface for enforcing organizational policy without modifying the model. A hook that exits with code 1 and a JSON reason blocks the tool call before it executes. Most teams either have no hooks configured, or have hooks copied from tutorials without understanding what they do. These 5 items check whether your hooks are doing what you think they are.
Items 22 through 26
{"decision": "block", "reason": "..."} on failure rather than exiting with code 2 silently.PreToolUse hook on BashTool checks for patterns like rm -rf, curl | sh, git push --force, and DROP TABLE in the command string before execution. This is a belt-and-suspenders check, not a substitute for proper permissions..claude/settings.json reference scripts that live in the repo (or a dedicated dotfiles repo). Hooks that only exist on one developer's machine are not auditable and will not propagate to CI.Stop hook writes a line to a centralized log: timestamp, session ID, total cost, turn count, exit reason. Without this, reconstructing what an unattended agent did requires manual JSON parsing of the session files.Notification hook posts to a Slack channel or sends a webhook. An agent that finishes at 3am and nobody sees the result until morning has a 6-hour blast radius on any error it introduced.Section 5: MCP exposure
The Model Context Protocol expanded Claude Code's reach significantly. An MCP server that exposes a database connection, a file system, or an HTTP client to the model creates a new attack surface: prompt injection through any text content the model reads during a session. A crafted commit message, a malicious README in a cloned repo, or a database row containing injected instructions can redirect an in-progress agent. These items check the MCP surface specifically.
Items 27 through 30
npx without a version pin (npx @modelcontextprotocol/server-filesystem) will pull the latest version on each run. A supply chain compromise in an upstream package propagates silently. Pin with @x.y.z..claude/settings.json is reviewed on a schedule. MCP servers added for a specific project and never removed accumulate over time. Each additional server is additional attack surface and additional context overhead on session start.Interpreting your score
If you worked through all 30 items honestly, you have one of three situations.
0 failures in sections 1–3: Your setup is in reasonable shape. الأعمال through sections 4 and 5 at your own pace. The remaining items are important but unlikely to produce an incident this week.
Any failure in items 02, 04, 07, 09, 13, 22, 23, 27, or 28: These are the items with documented incident histories. Prioritize them before anything else. A failure on item 09 (no per-session cost gate) combined with item 13 (no subagent depth limit) is the exact configuration that produced the April 2026 Tokenocalypse incidents.
6 or more failures total: The configuration needs a structured review, not a line-by-line fix. Trying to patch individual items without understanding how they interact often introduces new gaps while closing old ones. This is the situation where the productized audit makes sense: a single 90-minute session that produces a written report, a prioritized fix order, and a confirmation call.
The Septim Agents Pack ($49) includes pre-built hook scripts for items 09, 10, 23, 25, and 26 — tested, version-controlled, and ready to drop into .claude/settings.json. If you found failures in those items specifically, the pack covers them without requiring you to build the hooks from scratch.
Want the audit done for you
The Septim Audit is the productized version of this checklist. One flat fee, no subscription. You get a written findings report covering all 30 items, a prioritized fix list ordered by incident risk, and a 30-minute call to walk through the results. Teams typically find 6–12 failures they did not know existed.
Septim Audit — $99, pay once →What's next
If you are starting from scratch with Claude Code production hardening, the sequence that produces the most coverage per hour of work is: items 02 and 04 first (credential scoping), then item 09 (per-session cost gate), then item 16 (claudeignore), then item 22 (hook failure testing). Those four items close the four highest-frequency incident patterns we have seen across the last 90 days of audit work.
The full checklist, the hook scripts, and the CLAUDE.md templates are all included in the Septim Audit report. If you want the hooks without the audit, they are in the Agents Pack. Both are pay-once.