← failproof.ai
guide·may 13, 2026·8 min read

how to stop claude code from running dangerous commands

install failproof ai, run failproofai policies --install, and 39 PreToolUse hooks land in ~/.claude/settings.json. from that point on, claude code asks failproof before running any shell call. destructive ones - rm -rf, sudo, curl | sh, git push --force, terraform destroy - get blocked at the hook layer before the harness ever executes them.

the incidents this is meant to stop

Every viral “ai coding agent catastrophic failure” clip has the same shape. an agent decides a destructive command is the right next step and the harness runs it without asking:

  • ai agent terraform destroy accident - a data-platform agent ran terraform destroy against the wrong workspace and took 2.5 years of infra with it.
  • drop table ai agent - the model decided the cleanest way to reset a dev schema was DROP TABLE users; on what turned out to be the prod connection.
  • cursor force pushed to main- a refactor hit a merge conflict and the agent took the “clean exit” out.
  • ai agent ran rm -rf - a cleanup that was supposed to delete node_modules ran one directory up and erased the working tree.

All four are runtime decisions, not prompt failures. None of them is stopped by a longer system prompt. Each is stopped by a single PreToolUse hook that reads the literal bash string and refuses it.

Why prompt-only rules don't stop claude code

The first instinct most teams have is to add a paragraph to CLAUDE.mdor the system prompt: “never run rm -rf,” “never force push.” That is praying in prompts. Prompts are advice. Hooks are enforcement. Once the model decides a destructive command is the right next step - usually because it misread the task - the only thing that prevents execution is a program that intercepts the call before the shell runs it.

Claude Code already exposes that interception point. The harness fires PreToolUse on every bash invocation. Anything you attach there can read the command, exit non-zero, and the call is aborted. failproof ai is the default policy layer on top of that contract.

Install failproof ai (60 seconds)

failproof ai is a free CLI on npm. One install, one register, and the hooks land in the same ~/.claude/settings.json claude code already reads.

After the second command, run failproofai policies to list every policy that is now active. Launch the dashboard with failproofai - it serves at http://localhost:8020 and shows every policy trigger in real time, with the exact command, agent session, and decision.

What gets blocked out of the box

The dangerous-commands category is on by default. Each policy is a single-purpose rule that matches a shell pattern and exits non-zero when it fires:

  • block-rm-rf - recursive deletion. Permits safe paths like /tmp and explicit allowlist entries. Detail: how to block rm -rf in claude code.
  • block-sudo - any sudo invocation. Allow a small set of command prefixes if you really need them (rare in a dev workflow).
  • block-curl-pipe-sh - denies the curl … | sh / wget … | bash pattern that hands an unknown script to your shell.
  • block-force-push - refuses git push --force and -f variants. Detail: prevent ai agent force push.
  • block-push-master & block-work-on-main - denies pushing to and committing on protected branches (configurable).
  • block-env-files & protect-env-vars - refuses reads of .env and the printenv/env/echo $VAR trio. Detail: prevent claude code from accessing .env.
  • block-failproofai-commands - keeps the agent from uninstalling or disabling the policy layer itself.

Cloud and infra blockers - block-terraform, block-kubectl, block-aws-cli, block-gcloud, block-az-cli, block-helm, block-gh-pipeline - are opt-in. Enable them if your agent has access to a production environment. See the built-in policies reference for the full list.

How the block actually happens

The flow is the same for every policy:

  1. Claude Code is about to run a bash tool call. The harness fires PreToolUse.
  2. The hook calls failproof ai's local handler. failproof reads the command and the surrounding session context.
  3. Each policy gets a chance to match. If one fires, failproof returns a deny payload and exits non-zero.
  4. Claude Code sees the non-zero exit and aborts the tool call. The agent receives a structured message explaining what was blocked and why - so the next reasoning step is informed, not stuck.

No data leaves the machine. failproof runs as a sibling local process to the harness, and the dashboard is served on localhost only.

a shell-command guardrails layer for ai agents

The category name for what failproof installs is ai agent shell command guardrails- a process that sits between the model and your terminal and limits which bash commands an agent can actually run. Most other tools in the guardrails space focus on the model's text output (the llm i/o layer). failproof ai is the action layer: an agent policy you install via npm, distributed as the failproofai package, that ships 39 ready-made policies and runs locally. There is no model-side filter, no cloud, no per-request fee.

Customizing what counts as dangerous

Defaults are aggressive on purpose, but every policy is tunable. From the dashboard you can:

  • Toggle a policy off if it conflicts with a known-safe workflow (e.g. block-rm-rf on a CI sandbox).
  • Add an allowlist entry - a path, a command prefix, a branch - so the policy keeps firing on everything else.
  • Promote a warn policy (like warn-destructive-sql or warn-git-amend) into a hard block.
  • Write a custom policy in JavaScript - allow / deny / instruct against the trace.

Get started

One npm install, one register command, the hooks are live. Free, local-only, open source on github.

book a demo →