Claude Code Security Best Practices: Action-Level Gating with SafeClaw
Claude Code is one of the most capable AI coding agents available. It can read your codebase, write files, execute shell commands, and make network requests. That capability is what makes it useful. It's also what makes it a security risk if you run it without guardrails.
This post covers concrete best practices for running Claude Code and Claude-based agents securely, including a practical walkthrough of layering SafeClaw on top for action-level gating.
No theoretical hand-waving. Specific configurations, real threat scenarios, and a working setup you can implement today.
What Claude Code Can Do (and Why That Matters)
Claude Code operates with the permissions of the user who launched it. That typically means:
- File read: Any file your user account can read, including
.env,~/.aws/credentials,~/.ssh/id_rsa, and every other credential file in your home directory. - File write: Any file your user account can write, including source code, configuration files, shell profiles, and build scripts.
- Shell execution: Any command your shell can run, including
curl,printenv,ssh,docker, and everything else in your PATH. - Network access: Any destination your machine can reach, including external APIs, unknown servers, and potential exfiltration endpoints.
For deterministic security, you need a policy layer that operates at the system level, independent of the model's behavior. That's what SafeClaw provides.
Best Practice 1: Don't Run Claude Code in Your Main User Session
Your main user account has access to everything: email credentials, cloud provider configs, SSH keys, browser data, password managers. Claude Code doesn't need access to any of this.
What to do: Create a separate user account or use a containerized environment for AI agent work. This limits the blast radius of any file access to the agent's working directory.
If containerization isn't practical (it often isn't for interactive development), SafeClaw provides the same boundary enforcement without the overhead of a separate environment.
Best Practice 2: Audit What Claude Code Accesses
Before you can write security policies, you need to know what the agent actually does during a typical session. Most developers have no visibility into the specific file reads, shell commands, and network requests their agent makes.
What to do: Install SafeClaw and enable simulation mode.
npx @authensor/safeclaw
Run Claude Code through a representative workflow — have it read your codebase, generate some code, run tests, create a commit. With simulation mode active, SafeClaw logs every action the agent attempts and what the policy decision would be, without blocking anything.
Review the logs. You'll likely be surprised by:
- Which files the agent reads beyond your source code
- Which shell commands it executes automatically
- Which network destinations it contacts
Best Practice 3: Block Credential File Access
This is the single highest-impact security configuration you can make. Prevent Claude Code from reading files that contain secrets.
Policy rules:
# Block environment files
DENY file_read path=**/.env
DENY file_read path=*/.env.
Block cloud credentials
DENY file_read path=~/.aws/**
DENY file_read path=~/.config/gcloud/**
DENY file_read path=~/.azure/**
Block SSH keys
DENY file_read path=~/.ssh/**
Block package manager tokens
DENY file_read path=~/.npmrc
DENY file_read path=~/.pypirc
Block git credentials
DENY file_read path=~/.git-credentials
DENY file_read path=~/.netrc
Block certificate private keys
DENY file_read path=*/.pem
DENY file_read path=*/.key
With these rules active, Claude Code can read your source code and project configuration but cannot access credential files. If the agent tries to read .env, the action is denied before the file content is returned.
Best Practice 4: Allowlist Shell Commands
Shell execution is the broadest access vector. A single shell command can read files, make network requests, install software, or modify system configuration.
Policy rules:
# Development commands
ALLOW shell_exec command="npm test*"
ALLOW shell_exec command="npm run*"
ALLOW shell_exec command="npx*"
ALLOW shell_exec command="node*"
ALLOW shell_exec command="tsc*"
ALLOW shell_exec command="eslint*"
ALLOW shell_exec command="prettier*"
Git commands (read-only operations)
ALLOW shell_exec command="git status*"
ALLOW shell_exec command="git diff*"
ALLOW shell_exec command="git log*"
ALLOW shell_exec command="git branch*"
ALLOW shell_exec command="git show*"
Git commands (write operations — enable selectively)
ALLOW shell_exec command="git add*"
ALLOW shell_exec command="git commit*"
Directory listing
ALLOW shell_exec command="ls*"
ALLOW shell_exec command="find*"
Deny everything else (implicit with deny-by-default,
but explicit for clarity)
DENY shell_exec command="*"
Notice what's not on the allowlist:
curl,wget(network exfiltration)printenv,env(credential enumeration)cat,less,headon unrestricted paths (credential file reads)ssh,scp(lateral movement)docker(container escape, privilege escalation)pip install,gem install(supply chain risk outside of npm context)
Best Practice 5: Restrict Network Destinations
Even with file read and shell restrictions, defense in depth requires network controls. If the agent somehow accesses a credential, network restrictions prevent exfiltration.
Policy rules:
# Package registries
ALLOW network destination="registry.npmjs.org"
ALLOW network destination="cdn.jsdelivr.net"
Code hosting
ALLOW network destination="api.github.com"
ALLOW network destination="github.com"
Documentation and references
ALLOW network destination="developer.mozilla.org"
ALLOW network destination="nodejs.org"
Deny all other destinations
DENY network destination="*"
Adjust based on your project's actual dependencies. If you use a private npm registry, add it. If your project calls specific APIs, add those endpoints.
The key principle: enumerate the good, block everything else. Don't try to enumerate the bad.
Best Practice 6: Restrict File Write Locations
Claude Code should write files in your project directory. It should not write files in your home directory, system directories, or other locations.
Policy rules:
# Allow writing to project directories
ALLOW file_write path=src/**
ALLOW file_write path=test/**
ALLOW file_write path=lib/**
ALLOW file_write path=docs/**
Allow writing project config files
ALLOW file_write path=package.json
ALLOW file_write path=tsconfig.json
ALLOW file_write path=.eslintrc*
Deny writing everywhere else
DENY file_write path=**
This prevents the agent from modifying shell profiles (.bashrc, .zshrc), CI/CD configurations, or any file outside the project scope.
Best Practice 7: Use the Tamper-Proof Audit Trail
SafeClaw logs every action attempt in a SHA-256 hash chain. Each entry is cryptographically linked to the previous one, making it impossible to modify past entries without detection.
What to review:
- Denied actions. These show you what the agent tried to do but was blocked from doing. Frequent denials on the same resource might indicate the agent is attempting to work around restrictions.
- Allowed actions. Verify that allowed actions are consistent with the agent's intended task. If you asked Claude Code to refactor a module and the logs show network requests to unfamiliar destinations, investigate.
- Action patterns over time. Build a baseline of normal agent behavior. Deviations from the baseline are worth investigating.
Best Practice 8: Test Policies with Simulation Mode Before Enforcement
Every time you modify your policy rules, run through a complete workflow in simulation mode first.
- Update the rules.
- Enable simulation mode.
- Run Claude Code through a representative task.
- Review the simulation logs.
- Verify all legitimate actions pass and all sensitive actions are blocked.
- Switch to enforcement mode.
Best Practice 9: Keep SafeClaw Updated
SafeClaw is built with zero third-party dependencies, which eliminates supply chain risk from dependency updates. The client is 100% open source, so you can audit every line of code.
The project runs 446 automated tests in TypeScript strict mode. Updates are thoroughly tested before release.
Stay current to get the latest policy evaluation capabilities and security fixes.
Practical Walkthrough: Full Setup
Here's the end-to-end setup for securing Claude Code with SafeClaw:
1. Install SafeClaw.
npx @authensor/safeclaw
2. Open the browser dashboard. The setup wizard walks you through initial configuration. No CLI expertise needed.
3. Enable simulation mode. Run Claude Code on a real task. Review the logs.
4. Write your policy rules. Use the deny rules for credential files, shell allowlists, and network destination allowlists from this post as starting templates. Customize for your project.
5. Run simulation again. Verify the rules work correctly with your specific workflow.
6. Switch to enforcement. Policies are now active. Sub-millisecond evaluation, local, no network round trips. Claude Code runs at the same speed with the policies active.
7. Monitor the audit trail. Review regularly. Adjust rules as your project evolves.
Free tier available with renewable 7-day keys. No credit card required. Works with Claude and OpenAI out of the box, plus LangChain.
The Layered Approach
Anthropic builds safety into Claude at the model level. That's a valuable first layer. But model-level safety is probabilistic. It guides the model's behavior but doesn't guarantee it.
SafeClaw adds a deterministic second layer. Policy rules are evaluated by code, not by a language model. A DENY rule means DENY — 100% of the time, regardless of the prompt, the model's reasoning, or any injection attempt.
Model-level safety plus system-level policy enforcement is the right architecture. Claude's built-in safety features handle the 99% case. SafeClaw's action-level gating handles the remaining 1% — and that 1% is where the 1.5 million leaked keys came from.
SafeClaw by Authensor. Action-level gating for AI agents. The security layer Claude Code deserves.
Try SafeClaw
Action-level gating for AI agents. Set it up in your browser in 60 seconds.
$ npx @authensor/safeclaw