2026-06-28
Claude Code Security Best Practices for Teams in 2026
A practical security guide for teams running Claude Code: permission modes, allowlists, MCP vetting, secrets handling, and least-privilege CI runs.

Last updated: June 28, 2026
An AI coding agent that can read your repo, run shell commands, and call external services is useful exactly because it has reach. That same reach is the risk. A misread prompt, a sloppy allowlist, or one untrusted MCP server can leak a token or wipe a branch. This guide is for the developer or platform lead who wants Claude Code in daily work and in CI without handing it the keys to production.
Quick answer: how do teams keep Claude Code secure?
Run the agent with least privilege and review what it does. In practice that means five things:
- Start in a restrictive permission mode and grant tools through a narrow allowlist, not a blanket "always allow."
- Keep secrets out of the model's context: no pasted keys, and a
denyrule on.envand secret paths. - Vet every MCP server before connecting it, since an untrusted server can read data and act on your behalf.
- Treat fetched web content as untrusted input that may carry prompt-injection instructions.
- In CI, give the agent a short-lived, read-scoped token and never expose production credentials.
The rest of this article turns each of those into concrete settings, with a risk table, a permissions reference, and a CI scenario you can copy.
How do permission modes and allowlists actually work?
Claude Code asks before it runs a tool the first time. You decide whether that decision is remembered, scoped, or skipped. The permission mode sets the baseline:
defaultprompts on the first use of each tool or command.planis read-only: the agent can read files and propose a plan but cannot edit or run commands. Use it for review.acceptEditsauto-accepts file edits but still prompts for shell commands.bypassPermissionsskips every prompt. Treat it as sandbox-only.
The durable controls live in .claude/settings.json under permissions, with allow, ask, and deny rules. Rules are scoped by tool and pattern, so you grant exactly what a task needs:
{
"permissions": {
"allow": ["Read", "Edit", "Bash(npm test:*)", "Bash(git diff:*)"],
"ask": ["Bash(git push:*)", "WebFetch"],
"deny": ["Read(./.env)", "Read(./secrets/**)", "Bash(curl:*)", "Bash(rm -rf:*)"]
}
}
A deny rule always wins over allow, which is why the secret paths above stay unreadable even if a broad Read rule exists. Anthropic documents the full rule syntax and precedence in the Claude Code identity and access management docs.

Avoid --dangerously-skip-permissions outside a disposable container. It removes the one human checkpoint that catches a bad rm or an unexpected network call. If you want speed without that risk, prefer a tight allowlist so routine commands run unattended while anything new still pauses for you.
Risk and mitigation reference
Most incidents trace back to a handful of patterns. Map each to a control before you scale the agent across a team.
| Risk | Why it happens | Mitigation |
|---|---|---|
| Secret exposure | Keys pasted into chat or read from .env |
deny secret paths; pass creds via environment, never the prompt |
| Destructive command | Broad allow or bypassPermissions on rm/git reset |
Keep rm -rf and force-push in ask or deny; review diffs |
| Prompt injection | Fetched page or issue text carries hidden instructions | Treat web/issue content as untrusted; scope WebFetch to known domains |
| Untrusted MCP server | A server with write/network scope acts on your behalf | Vet author and permissions; pin versions; least scope |
| Over-broad file access | Agent reads or edits outside the project | Scope to the repo; avoid extra additionalDirectories |
| History rewrite | Force-push or hard reset loses work | Branch protection; ask on git push --force |
| CI credential leak | Production tokens placed in the runner env | Short-lived, read-scoped tokens; no prod creds in review jobs |
The framing here follows the OWASP Top 10 for LLM Applications, which calls out prompt injection, insecure output handling, and excessive agency as the leading agent risks.
Permissions and scope reference
This table is the cheat sheet I hand new team members. It covers the settings that change the blast radius of a single run.
| Setting / flag | What it controls | Recommended default |
|---|---|---|
permissions.allow |
Tool calls that run without a prompt | Narrow list, e.g. Read, Bash(npm test:*) |
permissions.ask |
Calls that always prompt first | Writes, network, package installs |
permissions.deny |
Calls blocked outright | Read(./.env), Bash(curl:*), secret paths |
--permission-mode plan |
Read-only planning, no edits or commands | Code review and audits |
acceptEdits mode |
Auto-accept edits, still prompt for shell | Trusted local refactors |
--dangerously-skip-permissions |
Skips every prompt | Disposable sandbox only |
additionalDirectories |
Extra folders the agent may read | Leave unset; scope to the repo |
Vetting MCP servers before you connect them
MCP servers extend the agent with new tools: a database client, a ticketing integration, a browser. Each one you add is code that can read context and take actions. An untrusted server is the fastest way to turn a helpful agent into a data exfiltration path, so the bar for connecting one should be the same bar you'd apply to any dependency with network access.
Before you add a server, answer five questions:
- Who publishes it, and is the source public and maintained?
- What scopes does it request: read-only, or write and network?
- What data can it see once connected: just this repo, or your whole machine?
- Are credentials scoped and short-lived, or is it a long-lived admin token?
- Can you pin a version so an auto-update can't silently widen its access?
Connect servers with the least scope that does the job, and keep write-capable or production-facing servers out of shared or CI configs. For setup mechanics and a deeper walkthrough, see our Claude Code MCP integration guide. The Claude Code productivity tips post covers how to keep that footprint small without slowing yourself down.
Keeping secrets out of the model's reach
The cleanest secret is the one the model never sees. Don't paste API keys into the prompt, and don't ask the agent to "read the key from config and use it." Let credentials live in the environment and reference them by name so the value stays out of the transcript.

Three habits cover most of the risk:
- Add a
denyrule for.env,*.pem, and anysecrets/directory so the agent can't read them even by accident. - Use a pre-commit secret scanner (such as gitleaks or
git secrets) so a slipped key fails the commit, not the audit. - Rotate anything that does get exposed immediately, then check logs and history. Rotation is the only fix that actually closes the window.
If a key already reached a transcript or a commit, assume it is compromised and rotate it. Searching git history with git log -S helps you find where it landed.
Scenario: enabling Claude Code in CI without production credentials
A team wants Claude Code to review pull requests in GitHub Actions. The goal is automated review comments, with zero ability to deploy, write to main, or touch the production database.

Here is the setup that keeps the job useful but boxed in:
- Run headless with
claude -pinplanmode so the agent reads the diff and writes a comment, but never edits files or runs build commands. - Grant the workflow
contents: readandpull-requests: writeonly. No deploy job, no infrastructure scope. - Use the job's short-lived
GITHUB_TOKEN, not a personal token, and never put database or cloud production keys in that job's environment. - Add a
denylist for secret paths and outboundcurl, so a prompt-injection attempt inside the PR diff cannot exfiltrate anything. - Pin the action and Claude Code version, and gate any deploy step behind a separate, human-approved environment.
permissions:
contents: read
pull-requests: write
steps:
- run: claude -p "Review the diff for security issues" --permission-mode plan
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
The review job sees code and posts feedback. It cannot reach production because production credentials are never in scope. Anthropic's Claude Code security overview describes this least-privilege posture for automated and headless runs.
What should you never paste into an AI coding agent?
Some inputs belong nowhere near a transcript, because anything in the context window can be echoed back, logged, or acted on:
- Live API keys, database URLs with passwords, or cloud root credentials.
- Customer PII or regulated data you would not put in a support ticket.
- Private signing keys, certificates, or
.pemfiles. - Full production connection strings when a read replica or local fixture would do.
When the agent needs access, give it a path to a scoped credential through the environment rather than the secret itself. Same outcome, far smaller blast radius.
Auditing, hooks, and ongoing review
Least privilege sets the floor; review keeps you there. Read the agent's plan before you approve a risky step, and read the diff before you commit. For larger changes, the same discipline that makes AI-assisted refactoring safe applies here: small, reviewable steps beat one giant unattended run.
Add deterministic guardrails with hooks. A PreToolUse hook can inspect a command and block it before it runs, which is how you enforce rules the model should never override, like refusing any write to a protected path. Pair that with an audit trail so you can answer what the agent did, when, and on whose behalf.
A quick recurring checklist for the team:
- Review
.claude/settings.jsonallow and deny lists on a schedule, not just at setup. - Re-vet MCP servers after major version bumps.
- Confirm CI jobs still run in
planmode and carry no production secrets. - Rotate tokens on a cadence and after any suspected exposure.
- Keep a
CLAUDE.mdthat states the non-negotiables: no force-push to main, no direct prod DB access, no secrets in prompts.
For the broader workflow around all of this, the Claude Code ultimate guide walks through configuration end to end.
Key takeaway
Security for AI coding agents is the same least-privilege thinking you already apply to service accounts, written down as permission rules. Start restrictive, widen with a narrow allowlist, deny secret paths, vet MCP servers like dependencies, treat fetched content as untrusted, and keep production credentials out of any job the agent can reach. Do that and Claude Code stays a fast pair of hands, not an open door.
Use the free tools while you follow the guide.
Keep reading

2026-07-18
How to Add Text to Photos Without Losing Readability
Add clean text overlays to photos for social posts, product images, banners, and watermarks. Includes contrast checks, layout rules, tools, and batch options.

2026-07-18
Add a Watermark to an Image Free: Practical Photo Guide
Add a readable text or logo watermark to photos for free. Pick placement, opacity, export size, and batch settings without ruining the image.

2026-07-18
AI Face Restoration: GFPGAN vs CodeFormer Compared
GFPGAN and CodeFormer both repair damaged faces, but they trade accuracy for polish differently. Which one to use, how they actually work, and where both can quietly invent a face that isn't the real person.