2026-01-29 · Authensor

How to Run Claude Code Safely

To run Claude Code safely, install SafeClaw (npx @authensor/safeclaw) and define a policy that gates every shell_exec and file_write action Claude Code performs. Claude Code has direct access to your terminal — it runs shell commands, writes and edits files, and reads your filesystem. SafeClaw intercepts each action before execution, checks it against your deny-by-default policy, and blocks anything you haven't explicitly permitted.

Why This Matters

Claude Code is powerful precisely because it has real system access. It can run git push, modify your package.json, install npm packages, and read any file on your machine. This makes it productive — and dangerous if misdirected. A prompt injection embedded in a repository file could instruct Claude Code to read your ~/.ssh/id_rsa or your ~/.aws/credentials and send them to an external endpoint. Without action-level gating, there is no enforcement layer between Claude Code's decisions and your operating system.

Step-by-Step Instructions

Step 1: Install SafeClaw in Your Project

npx @authensor/safeclaw

The setup wizard detects Claude Code as your environment and generates a starter policy. SafeClaw has zero third-party dependencies and evaluates policies in sub-millisecond time, so Claude Code's responsiveness is unaffected.

Step 2: Get a Free API Key

Go to safeclaw.onrender.com. Sign up for the free tier — 7-day renewable key, no credit card. The dashboard provides a Claude Code-specific policy template.

Step 3: Create Your Claude Code Policy

Place safeclaw.yaml in your project root. The policy below is designed specifically for Claude Code workflows: it allows reading project files, writing to designated directories, running tests and linting, but blocks access to credentials and destructive commands.

Step 4: Run Simulation Mode First

SAFECLAW_MODE=simulation npx @authensor/safeclaw

Use Claude Code normally for a session. Review the simulation log to see every action it attempted. Adjust your policy to match your actual workflow, then switch to enforce mode.

Step 5: Enforce

SAFECLAW_MODE=enforce npx @authensor/safeclaw

Claude Code now operates within the boundaries you defined. Every action is logged to a tamper-proof SHA-256 hash chain audit trail.

Example Policy

version: "1.0"
default: deny

rules:
# File reading — project files only
- action: file_read
path: "./src/**"
decision: allow
reason: "Claude Code can read source files"

- action: file_read
path: "./tests/**"
decision: allow
reason: "Claude Code can read test files"

- action: file_read
path: "./package.json"
decision: allow
reason: "Claude Code can read package manifest"

# Block sensitive files explicitly
- action: file_read
path: "*/.env"
decision: deny
reason: "Never expose environment variables"

- action: file_read
path: "~/.ssh/**"
decision: deny
reason: "Never read SSH keys"

- action: file_read
path: "~/.aws/**"
decision: deny
reason: "Never read AWS credentials"

# File writing — project directories only
- action: file_write
path: "./src/**"
decision: allow
reason: "Claude Code can edit source files"

- action: file_write
path: "./tests/**"
decision: allow
reason: "Claude Code can edit tests"

# Shell commands — allowlist safe commands
- action: shell_exec
command: "npm test*"
decision: allow
reason: "Run tests"

- action: shell_exec
command: "npm run lint*"
decision: allow
reason: "Run linter"

- action: shell_exec
command: "git status"
decision: allow
reason: "Check git status"

- action: shell_exec
command: "git diff*"
decision: allow
reason: "View diffs"

# Dangerous shell commands
- action: shell_exec
command: "rm *"
decision: deny
reason: "Block file deletion"

- action: shell_exec
command: "curl *"
decision: require_approval
reason: "Outbound HTTP requires human approval"

# Network — only necessary APIs
- action: network
domain: "api.anthropic.com"
decision: allow
reason: "Claude API calls"

- action: network
domain: "*"
decision: deny
reason: "Block all other outbound network"

What Happens When It Works

ALLOW — Claude Code runs your test suite:

{
"action": "shell_exec",
"command": "npm test",
"decision": "ALLOW",
"rule": "Run tests",
"timestamp": "2026-02-13T14:22:01Z",
"hash": "b3c4d5e6..."
}

DENY — Claude Code tries to read your AWS credentials:

{
"action": "file_read",
"path": "/Users/dev/.aws/credentials",
"decision": "DENY",
"rule": "Never read AWS credentials",
"timestamp": "2026-02-13T14:22:03Z",
"hash": "f7g8h9i0..."
}

REQUIRE_APPROVAL — Claude Code wants to make an outbound curl request:

{
"action": "shell_exec",
"command": "curl https://registry.npmjs.org/lodash",
"decision": "REQUIRE_APPROVAL",
"rule": "Outbound HTTP requires human approval",
"timestamp": "2026-02-13T14:22:05Z",
"hash": "j1k2l3m4..."
}

Common Mistakes

  1. Trusting Claude Code's built-in permission prompts as sufficient. Claude Code asks before some actions, but this is a UX convenience, not a security boundary. If the model is manipulated via prompt injection, it may not prompt you at all. Action-level gating enforces policy regardless of what the model decides to do.
  1. Allowing shell_exec with wildcard patterns that are too broad. A rule like command: "npm *" allows npm test but also npm publish or npm exec -- malicious-script. Be specific: allowlist exact commands or narrow prefixes.
  1. Forgetting to gate file_read actions. Most people focus on blocking writes and shell commands but leave reads wide open. Reading ~/.ssh/id_rsa, ~/.gitconfig, or ~/.bash_history is how exfiltration attacks begin. Gate reads as aggressively as writes.

Cross-References

Try SafeClaw

Action-level gating for AI agents. Set it up in your browser in 60 seconds.

$ npx @authensor/safeclaw