Cursor Guardrails
The steering analog to Cursor's Rules + Auto-Run safety, built on the three Claude Code mechanisms that actually matter, in increasing order of strength:
- CLAUDE.md - guidance Claude reads every session. Advisory only; Claude treats it as context, not enforced configuration.
- Permissions (
settings.json) - an allow/ask/deny policy applied before tools run. - PreToolUse hooks - deterministic scripts that can hard-block a tool call regardless of what the model decides. This is the only real enforcement layer.
Rules and memory steer; hooks enforce. For anything that must never happen (secret exfiltration, destructive commands), use a hook.
Setup workflow
Bundled templates live in this skill's assets/ directory. Copy and adapt them
into the target repo's .claude/ directory.
1. CLAUDE.md baseline
If the repo has no CLAUDE.md, create one from assets/CLAUDE.md.template,
filling in real build/lint/test commands and conventions. If one exists, audit
it and append a "Safety" section rather than overwriting.
2. Permissions
Merge the settings template for the target platform into .claude/settings.json
(project) or the personal settings file. Both templates:
allow safe read/inspect commands (
git diff,git status, lint, tests)route anything destructive to
askdeny reads/writes of secrets (
.env, key material)macOS / Linux:
assets/settings.json.template(wires the.shhooks)Windows:
assets/settings.windows.json.template(wires the.ps1hooks)
3. Enforcement hooks
Copy the matching hook scripts from assets/hooks/ into .claude/hooks/. Both
hooks read the tool call as JSON on stdin and emit a deny decision when a
denied pattern matches; the settings template already registers them.
macOS / Linux (bash, requires jq - verify with jq --version):
block-dangerous-bash.sh- PreToolUse onBash; denies destructive or exfiltration patterns.guard-sensitive-writes.sh- PreToolUse onWrite|Edit; denies writes to.env, credential files, and paths outside the project.
Make them executable:
chmod +x .claude/hooks/*.sh
Windows (PowerShell, no jq or Git Bash required):
block-dangerous-bash.ps1- same Bash denylist plus Windows/PowerShell patterns (Remove-Item -Recurse -Force,rd /s,del /f /s /q,format,irm|iexdownload-and-execute).guard-sensitive-writes.ps1- same secret-file and project-root checks.
No execute bit is needed on Windows; the settings template invokes them via
powershell -ExecutionPolicy Bypass -File.
Pick one platform's pair of hooks per machine. The scripts are independent, so a mixed team can commit all four and each settings file references only its own.
4. Verify
After install, confirm the hooks fire by asking Claude Code to attempt a denied
action (e.g. rm -rf on a scratch path, or Remove-Item -Recurse -Force on
Windows) and checking that it is blocked with the hook's reason.
How the hook block contract works
A PreToolUse hook reads the tool call as JSON on stdin and blocks by printing:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "<why>"
}
}
permissionDecision is one of allow, deny, ask. Exiting with code 2 and
writing the reason to stderr is an equivalent way to block. A hook decision
never overrides an existing deny/ask permission rule, hooks tighten, they
do not loosen.
MSP / client-data posture
- Secrets never enter the repo or logs.
- Least privilege: scope permissions to what the task needs.
- For autonomous / long-running sessions, run in a sandboxed or containerized environment, prompt injection via fetched content or tool output can attempt to trigger commands; the hooks are the backstop.
Caveats
- Denylists are not exhaustive. Treat them as a backstop, not a guarantee; keep the permission allowlist tight as the primary control.
- Review and tune the denied patterns for the specific repo before relying on them.