# Cursor Guardrails

> Set up or audit the safety/steering layer for Claude Code in a repo: a CLAUDE.md baseline, a permissions allowlist, and PreToolUse hooks that hard- block dangerous shell commands and writes to sensitive paths. Use this whenever the user wants to "lock down", "secure", "set guardrails", "set safe defaults", or configure permissions/hooks/auto-run safety for Claude Code, especially in an MSP or client-data environment. Invokable as /cursor-guardrails.

- Skill: `jambot24/cursor-guardrails` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add jambot24/cursor-guardrails`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jambot24/cursor-guardrails/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: jambot24 (https://skillmd.com/u/jambot24)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/jambot24/cursor-guardrails

---


# 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:

1. **CLAUDE.md** - guidance Claude reads every session. Advisory only; Claude
   treats it as context, not enforced configuration.
2. **Permissions** (`settings.json`) - an allow/ask/deny policy applied before
   tools run.
3. **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 `ask`
- deny reads/writes of secrets (`.env`, key material)

- macOS / Linux: `assets/settings.json.template` (wires the `.sh` hooks)
- Windows: `assets/settings.windows.json.template` (wires the `.ps1` hooks)

### 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 on `Bash`; denies destructive or
  exfiltration patterns.
- `guard-sensitive-writes.sh` - PreToolUse on `Write|Edit`; denies writes to
  `.env`, credential files, and paths outside the project.

Make them executable:

```bash
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|iex` download-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:

```json
{
  "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.

