cd /news/ai-safety/how-to-secure-ai-coding-agents · home topics ai-safety article
[ARTICLE · art-123146] src=augmentedswe.com ↗ pub= topic=ai-safety verified=true sentiment=· neutral

How to secure AI coding agents

A new analysis by security researcher ToxSec warns that instructions in AI coding agents' configuration files like CLAUDE.md, AGENTS.md, or Cursor Rules are not enforced security boundaries, citing Anthropic's own documentation that settings rules are the only enforced layer. Citing a Kiteworks 2026 survey of 459 professionals, the piece reports 74% of organizations lack purpose binding for AI agents and 79% lack automated termination mechanisms, urging developers to treat agents like service accounts with scoped credentials rather than relying on behavioral prompts.

read12 min views1 publishedSep 8, 2026
How to secure AI coding agents
Image: Augmentedswe (auto-discovered)

What if one of the most interesting and dangerous lines in your Claude Code setup is the one that says, “Never touch production”?

“Never touch production” is perfectly good advice. But when that instruction lives in CLAUDE.md, it still depends on the agent choosing to follow it. It’s guidance, not an enforced boundary.

And this is not really a Claude-specific problem. Codex has AGENTS.md. Cursor has project Rules. Pretty much every modern coding agent gives us some way to tell the model how we want it to behave.

The distinction between telling an AI what it should do and actually controlling what it can do is becoming one of the most important parts of working safely with coding agents.

Today, I brought in ToxSec, who writes a security-focused newsletter. He’ll to walk us through secure tooling. If you like today’s deep dive, check out ToxSec!

Your instructions are not a security boundary #

A lot of us configure Claude Code just like we’re onboarding a very fast new engineer. We tell it to use this framework, always run these tests, never commit secrets, do not modify production infrastructure, and ask me before pushing anything.

CLAUDE.md is fantastic for this. Anthropic specifically designed it to carry project instructions, coding conventions, workflows, and general behavioral guidance.

Related: ToxSec previously broke down how security rules files behave across Claude Code, Cursor, and Copilot.

But Anthropic’s own documentation draws a much harder line around security.

Settings rules are enforced by the client regardless of what Claude decides to do. CLAUDE.md shapes behavior, but it’s not a hard enforcement layer. Claude can read those instructions and try to follow them, but there’s no guarantee of strict compliance.

And as we’ve been seeing a lot lately, even aligned agents can take unexpected paths while trying to complete a task. Anthropic itself has described more capable models finding creative routes toward a goal that developers did not necessarily anticipate.

This all goes to say that there’s a pretty large security difference between “Claude, please never read my .env file” and a settings rule that denies Claude access to that .env file.

Even though they sound similar, they’re absolutely not the same thing.

Kiteworks’ latest 2026 survey of 459 security, compliance, and technology professionals found that 74 percent of organizations lacked purpose binding for AI agents, while 79 percent lacked an automated mechanism to terminate a misbehaving agent.

In other words, a lot of companies can tell an agent what its job is, but most still lack technical controls to stop it from going outside that job.

And that’s the problem we are trying to avoid on a much smaller scale with our own agents.

Think of Claude like a developer with a service account #

For me, the easiest mental model here is to stop thinking about Claude Code or Codex like a chatbot.

Think of it more like a developer with a service account.

You’d never create a service account and say something like, “Here are administrator credentials, but please only use the permissions you really need.”

We’ve already learned our lessons from that.

Instead, you scope the credentials. Claude should work the same way.

If Claude really needs to read the repository, let it read the repository. If the task requires modifying the source, that’s fine.

If it needs to run your tests 50 times while debugging something, there’s probably no reason we should be sitting there approving that test 50 times. That’s something we should allow.

But here’s the thing. Does fixing a CSS bug really require access to your AWS credentials?

Probably not.

Does running unit tests require permission to git push?

Definitely not.

Does debugging an API require unrestricted network access to every domain on the internet?

That would be a pretty weird API.

So really, this is where the security concept of least privilege becomes extremely useful for AI coding agents.

In May 2026, a Microsoft Research paper examining tool-enabled cloud agents found that many of the security problems around these systems did not require some new exotic class of AI vulnerability.

They came from much more familiar problems that we already have patterns to secure against.

Over-privileged tools. Mismatches between what the agent was supposed to do and what it was capable of doing. Ambient authority already sitting inside an execution environment.

Your development environment is already powerful. It may have Git credentials, cloud credentials, a package manager, SSH configurations, database tooling, environment variables, internal endpoints, and MCP servers that connect the agent to even more tools and systems.

So despite what we’re reading in the news lately, the agent doesn’t need Skynet hacking powers if the environment already contains everything it needs.

So really, from what I’ve seen, the question becomes much simpler.

What does the task actually require?

That’s what you give Claude.

This post is sponsored by Cosmos, the agent orchestration platform for AI-native engineering teams.

Cosmos is a shared system where agents work across triage, spec, implementation, review, testing, deployment, and feedback with the context, memory, and controls teams need. Humans steer, agents do the implementation, and the system gets better as the team uses it.

Allow, ask, deny #

Claude Code gives you a pretty nice way to build this boundary because permission rules can essentially fall into those three buckets.

You can allow it, you can have it ask, or you can deny it.

And Claude Code evaluates those rules in a security-friendly order: deny rules first, then ask rules, then allow rules.

So let’s imagine a normal development project for a minute.

Should Claude be running tests? Allow.

Running a linter? Allow.

git status and git diff? Same thing.

Currently, Claude Code already recognizes read-only forms of Git as read-only Bash commands, so you generally do not need to create explicit allow rules just for things like git status and git diff.

Now, installing a new package? Ask me.

Slopsquatting is real, and LLMs really do hallucinate package names.

Pushing code? Definitely ask me.

Reading .env? Instant deny.

Running some production deployment command? Also deny. Or at minimum, force an approval depending on how your environment works.

Example .claude/settings.json for macOS, Linux, or WSL2:

{
  "permissions": {
    "allow": ["Bash(npm test *)", "Bash(npm run lint *)"],
    "ask": ["Bash(npm install *)", "Bash(npm i *)", "Bash(git push *)"],
    "deny": ["Read(/.env)", "Read(/.env.*)", "Read(~/.aws/**)", "Read(~/.ssh/**)"]
  },
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": false,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false
  }
}

This example deliberately sets autoAllowBashIfSandboxed to false so the allow and ask rules remain visible in the workflow. If you later switch it to true, sandboxed Bash commands can run without prompting, while scoped ask rules such as Bash(git push *) still force an approval.

The npm rules are just an example. If your project uses pnpm, Yarn, pip, uv, or another package manager, you would build equivalent rules around the commands your project actually uses.

And keep those Bash patterns narrow. A rule like Bash(git *) is dramatically broader than Bash(git push *). Claude Code’s own documentation warns that trying to express complicated security policy purely through Bash command patterns can get fragile.

There is no silver bullet answer here.

You’re going to have to tailor this to your workflows.

The point is, we want to give the agent room to move around inside the area where it’s actually useful. And the alternative is permission fatigue, which I’ve experienced firsthand.

Anthropic says Claude Code users approve roughly 93 percent of permission prompts, and that to me is an incredibly human number.

If something interrupts you over and over again, eventually your security review process becomes clicking yes so the computer stops bothering you.

Claude Code also has Auto mode now, which can use a classifier to make some of these approval decisions automatically. That can reduce the human-review problem, but it is still a probabilistic decision layer. For something that absolutely cannot happen, an explicit deny rule or a lower-level environment restriction is still the stronger boundary.

This is the difference between maximum prompting and meaningful prompting.

We should let Claude freely perform the boring, reversible actions we already know are safe, and save the interruptions for something that actually deserves our attention.

That would be something like a package installation, pushing code, accessing a sensitive file, or making a change to infrastructure.

When Claude asks you something, the question means something.

Permissions still aren’t the boundary #

This is where things get a little weird, because even a beautiful permissions file does not automatically solve all our problems.

Claude Code has several different layers that do different jobs.

CLAUDE.md gives Claude its behavioral instructions.

Permissions decide which tool actions should be allowed, denied, or sent to you for approval.

Hooks can make certain workflows deterministic. If something absolutely needs to happen at a particular lifecycle event, like running a check or recording an action, that is much better suited to a hook than hoping Claude remembers to do it every time.

Anthropic describes hooks exactly this way: they run automatically at specific points in Claude Code’s lifecycle, giving you deterministic control instead of relying on the model to decide whether something should happen.

But even hooks have boundaries. The hook if field is a filter that decides whether a handler should run. The actual enforcement comes from what that hook returns or how it exits. For simple static decisions like “always deny this command” or “always ask before this tool call,” the permission system is usually the cleaner place to put the rule.

And then underneath all this sits the sandbox.

This is the layer I think security people are usually most interested in.

A Read deny rule blocks Claude’s built-in file tools and current Claude Code also applies those restrictions to file-reading Bash commands it recognizes, such as cat, head, tail, and sed.

But arbitrary subprocesses are a different story.

A Python script can open a file.

Node can open a file.

Some random binary can open a file.

Without the sandbox, those processes are not necessarily stopped by a Read rule simply because they eventually touch the same file.

Want to try it yourself?

Put DEMO_SECRET=not-a-real-secret in a local .env and deny Read(/.env).

With sandboxing disabled, verify that Claude’s Read tool and a direct cat .env are blocked. Then have a tiny local Python process attempt to open .env. Enable the sandbox and repeat the Python test. With the Read deny merged into the sandbox boundary, the subprocess should now be blocked at the operating-system level too.

That distinction matters because Claude does not only interact with files through a neat little Read button. It can run programs.

Python can read files.

Node can read files.

Terraform can touch infrastructure.

kubectl can have a very exciting afternoon.

The sandbox applies filesystem and network restrictions to Bash commands and the processes they spawn, which gives you a much stronger containment boundary around what that execution environment can actually reach.

The important caveat is that Claude Code’s native sandbox covers Bash and its child processes. Built-in tools like Read, Edit, and Write use the permission system directly rather than executing inside that sandbox.

And there are two settings I really care about if you are treating the sandbox as a meaningful security boundary.

failIfUnavailable makes Claude Code stop instead of quietly running unsandboxed if the sandbox cannot start.

allowUnsandboxedCommands: false disables the escape hatch that can otherwise retry a failed command outside the sandbox.

The native sandbox currently supports macOS, Linux, and WSL2. It does not run on native Windows, so a mixed-platform team should not blindly commit the strict sandbox block above without accounting for that.

With sandboxes, we’re actually getting somewhere.

More restrictions can actually mean more autonomy #

We normally think about security controls as the thing that slows agents down. We add more restrictions, more approvals, which means more friction.

But we can actually flip that around.

Anthropic says that in its internal usage, enabling sandboxing reduced permission prompts by 84 percent. Once the working area was clearly defined, Claude Code could simply operate inside it without constantly asking for permission.

I think that’s a much better model for AI agents.

Instead of standing behind Claude watching its every move, create a workspace where most of the moves it can make are acceptable, and then let it get to work.

This is essentially the same approach we take to securing people and software.

We don’t give every employee admin access and compensate by standing behind them all day.

We build roles. We scope credentials. We separate environments. We restrict networks.

And when something does cross a security boundary, we require approval.

AI coding agents should inherit those same ideas.

I think you should keep your CLAUDE.md.

Put your architecture guidance in there.

Tell Claude how you like tests written.

Tell it not to push directly to main.

All these instructions are still useful.

But anytime it comes to something that absolutely cannot happen, never rely on Claude remembering that sentence.

Move that requirement down into permissions.

And anytime the consequences get high enough, move it farther down into the sandbox and the actual environment.

And I’d take that last part literally.

If Claude absolutely cannot push directly to main, don’t make a Claude Code rule your final control. Protect the branch.

If it absolutely cannot deploy production, scope the cloud identity or deployment credentials so the environment itself refuses the action.

The agent-side rule is useful. The downstream authorization boundary is stronger.

My takeaway for this article is this: good agent security starts by assuming the model will occasionally misunderstand something.

Then you design the system so that misunderstanding is boring.

And interestingly, once you do that, you actually start to get very comfortable letting your agent do more.

Steal This: Least-Agency Review #

Before giving a coding agent more access, fill this out for the task:

  • Task: What is the agent actually being asked to accomplish?
  • Allow: Which reversible reads, edits, tests, and commands should run without interruption?
  • Ask: Which installs, pushes, infrastructure changes, or sensitive actions deserve explicit approval?
  • Deny: Which secrets, credentials, production resources, files, or commands should be unreachable?
  • Sandbox: Which filesystem paths and network destinations should subprocesses actually be able to reach?
  • Credentials: Can the task use scoped or short-lived credentials instead of whatever authority already exists in the developer environment?
  • Downstream enforcement: If the Claude Code rule disappeared completely, would Git, IAM, CI/CD, or the target service still block the action that absolutely cannot happen?
  • Failure test: If the agent misunderstands the task completely, what is the worst thing the environment still permits it to do?
── more in #ai-safety 4 stories · sorted by recency
── more on @toxsec 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-to-secure-ai-cod…] indexed:0 read:12min 2026-09-08 ·