Claude Code security: a checklist before running the agent on a project
The agent reads files and runs commands, so security settings belong before the first launch. A checklist: permissions, secrets, sandbox, a separate key with a limit.
6 min · · development · API keys
Claude Code reads project files, runs commands and edits code. That is convenient, but it means the agent acts with your rights on your machine. Claude Code security boils down to three questions: what it can see, what it can execute and how much money it can spend. Below is a checklist worth going through before the first launch on a real project. It relies on Anthropic's documentation (Security, Permissions and Sandboxing sections) and Zukko's documentation; Claude Code features change between versions, so check parameter names against your version.
1. Start in a mode where the agent asks
According to the documentation, in manual mode Claude Code starts with read-only permissions: when it needs to edit files or run commands, it asks, and you choose to allow once or always. A set of harmless commands such as ls, cat and git status runs without prompts.
Do not lift this restriction "to stop clicking" on day one. Work in the normal mode first and see which confirmations you press most often: those are the ones worth turning into targeted permissions (step 3), instead of switching protection off entirely.
2. Yolo mode: where it is acceptable and where it is not
The --dangerously-skip-permissions flag (known in the community as yolo) turns off confirmation prompts. Anthropic's documentation says plainly that this mode should be used only in isolated environments such as a container or a virtual machine, where Claude Code cannot cause damage. A practical rule:
- on a work laptop with SSH keys, cloud credentials and production access, do not enable yolo;
- in a disposable container with a copy of the repository, no secrets and no access to the production network, it is acceptable;
- in CI, run the agent on an isolated runner with minimal rights.
If you administer a team, there is a permissions.disableBypassPermissionsMode setting: the value "disable" forbids this mode. It is most useful in managed settings, which users cannot override.
3. Allow narrowly, deny explicitly
Permission rules are written in settings.json. By the documentation, the evaluation order is: deny first, then ask, then allow, and the first match decides. An allow rule does not override a deny. An example for the user-level ~/.claude/settings.json:
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
}
}Allow narrow, repeatable and reversible commands: the linter, tests, git status. Do not add broad patterns like "any Bash". Commands that change the outside world (git push, deploys, curl with writes, rm) are better left on confirmation or denied.
4. Close off .env and secrets
The Read(./.env) and Read(./.env.*) rules above exist so the agent does not read files with secrets and does not send their contents to the model. According to the documentation, Read and Edit rules apply to the built-in file tools and to file commands Claude Code recognizes in Bash (for example cat, head, tail). But this is not a watertight boundary: an arbitrary shell command can reach a file another way. So additionally:
- do not keep production secrets in the project directory where the agent works;
- keep separate development
.envfiles with test values; - do not put secrets in
CLAUDE.mdor in messages to the agent; - check
git statusand.gitignore: secret files must not end up in commits the agent creates.
5. Turn on the sandbox for commands
Anthropic's documentation describes a built-in Bash sandbox: the operating system restricts which files and network domains the agent's commands can reach. It is enabled with the /sandbox command or the sandbox.enabled setting and is off by default. Important details from the documentation:
- the sandbox covers only shell commands, while the built-in file tools work under permission rules;
- by default sandboxed commands write to the working directory but can read most of the machine, including directories like
~/.sshand~/.aws: reading sensitive paths needs separate restrictions (filesystem.denyReadand others); - network connections go through a proxy, and the allowed domain list starts empty;
- the sandbox is unavailable on native Windows, so you need WSL2.
6. Work on a branch and commit often
Rolling back is cheaper than preventing. Create a separate branch for the task, commit before big edits and review the diff before merging. Claude Code itself has state rollback (/rewind or double Esc), but it does not replace git.
7. Do not trust foreign content
The agent reads text from files, READMEs, web pages and MCP server responses. That text may contain an instruction written by an attacker (prompt injection). The precautions the documentation advises: review commands before approving, do not pipe untrusted content straight to the agent, verify changes to critical files, and use isolated environments for work with external services.
On MCP servers specifically: connect only ones you trust, and check the .mcp.json file in a repository you have cloned. A server from someone else's repository executes code on your machine.
8. A separate Zukko key with a limit
Here the gateway-specific part comes in. The Claude Code key sits in ~/.claude/settings.json or in an environment variable and is available to the processes the agent starts. So:
- Create a separate key just for Claude Code in the dashboard. The full key is shown once, at creation.
- Set a daily and monthly limit in $. If the agent loops or the key leaks, the ceiling triggers before the balance runs dry. Exceeding it returns 429 with the code
key_daily_limit_reachedorkey_monthly_limit_reached. Limits are soft: requests started before the ceiling is reached will complete, so leave a margin. - Restrict
allowed_models. If you remapped the Claude Code model slots toclaude-opus-5-5andclaude-sonnet-5-5, put exactly those in the list. An extra model widens what an attacker can do, while a missing one causes a 403model_not_allowed_for_keywhen Claude Code calls its slot. - Keep the key in user-level configuration,
~/.claude/settings.json, not in a project file that ends up in the repository. The valuesANTHROPIC_BASE_URL=https://api.zukko.proandANTHROPIC_AUTH_TOKENare described in the Claude Code documentation. - Know how to revoke a key. A leaked key is deleted in the dashboard, and the other account keys keep working. A step-by-step guide is in A leaked API key: what to do.
More on limits and the model list is in the documentation.
9. Production access: do not give it at all
The simplest rule: the agent should have no path to production. Do not run it in a session with live kubectl, psql or a cloud CLI with admin rights connected. Need data access for debugging? Create a separate database user with read-only rights on a copy of the data. Keep deploys for yourself or the CI pipeline.
A short summary before launch
- The confirmation mode is on, yolo only in an isolated environment.
- Narrow allow rules, explicit deny rules for
.envand secrets. - The sandbox is on if your platform supports it.
- Work on a branch, commit before big edits.
- Foreign repositories and MCP servers are checked.
- A separate Zukko key with a daily limit and
allowed_models. - No production access in the agent's environment.
FAQ
Is a deny rule on .env enough?
It is a good first line but not the only one. The rule covers built-in tools and recognized file commands, while an arbitrary shell command may reach the file another way. Add the sandbox and do not keep production secrets next to the project.
Can I use --dangerously-skip-permissions for automation?
In an isolated container or runner with no secrets and no production access it is acceptable, as Anthropic's documentation says. On your own work computer with keys and access to infrastructure, better not.
How does a key limit help with security?
It caps the damage in money if the agent loops or the key lands in the wrong hands. It is not a replacement for file access rights but a last safeguard. The limit applies to the key, not to the entire balance.
What if the key leaked anyway?
Delete it in the dashboard and create a new one with a limit. Look at the spend history on the Usage page to judge whether there was foreign traffic.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- Your Own Neural Network Proxy on Node.js: Keep the API Key Off the FrontendA small Express server between your frontend and the model API: the key stays on the server, and models, request size and rate are capped.
- DeepSeek API in Python: Requests, Streaming, JSON and Error HandlingReady code for DeepSeek V4.1 Flash and V4 Pro on the OpenAI SDK: a request, streaming, JSON parsing and careful error handling.
- Gemini API in Python: requests via the OpenAI SDK and OpenAI formatA working Gemini API example in Python with no extra library: change base_url in the OpenAI SDK, add streaming and JSON, and compare with google-genai.
- Anthropic SDK for Python: base_url, key and a first request via a gatewayThe official anthropic package for Python just needs a different address. We cover base_url, the key, streaming, token counting, caching and errors.