
If you're using Claude Code, Cursor, or GitHub Copilot to actually run commands and browse the web, your existing security review process probably has gaps you haven't thought about yet.
This isn't abstract threat modeling. The security surface changes the moment an agent starts making decisions without waiting for your eyes. I went through this audit on my own projects recently, and three categories kept showing up. This post walks through each one concretely.
1. Why this matters now
The traditional development loop had a built-in safety net: a human at every handoff. You wrote code, reviewed it, committed it, and deployed it. Each step was a checkpoint where bad decisions could be caught.
AI coding agents break that loop on purpose. That's literally the value proposition — less friction, more autonomy. Claude Code reads files, calls external URLs, runs shell commands, and installs packages without pausing for confirmation. Cursor edits across your codebase in a single pass. The time savings are real, but so is what you're trading away.
The pain most developers feel is subtle at first. The agent does the right thing 95% of the time. Then one day it auto-installs a dependency you didn't vet, or writes a file to a path you didn't intend, and you only find out because something broke — not because your security tooling flagged it. By that point, the change is already in your repo history.
The same week Security Boulevard published analysis on this attack surface, Snyk announced Claude Enterprise and Claude Desktop integration — their Evo product embedding security scanning directly into agent workflows. Two separate organizations naming the same gap on the same day is a signal worth taking seriously.
2. The core idea
The real risk isn't what the model writes — it's the permission envelope the agent operates inside.
Think of traditional security as locking the front door. One entry point, one lock. An AI coding agent holds keys to the windows, the ventilation ducts, and the utility room, and it walks through all of them during normal operation. Locking the front door doesn't help.
The three zones where this concretely shows up:
| Risk Category | What the Agent Does | What Can Go Wrong |
|---|---|---|
| Filesystem permissions | Reads/writes files to complete tasks | Permission scope wider than the project folder |
| External dependencies | Auto-fetches npm packages, API endpoints | No validation step before code runs |
| Execution logging | Runs shell commands autonomously | No audit trail for post-incident review |
Each of these is an "intended feature." That's what makes them hard to catch — there's no bug to fix, just a boundary you haven't drawn yet.
3. How to implement it
Start with a permission audit. For each agent you're running, you want to know three things before you look at anything else.
Step 1: Check the permission scope
For Claude Code, the allowed tools and working directory are surfaced in your project's .claude/settings.json:
cat .claude/settings.json
Look for allowedTools and permissions. If you see broad filesystem access without path restrictions, that's your first fix:
{
"permissions": {
"allow": [
"Read(**)",
"Write(src/**)",
"Bash(npm run *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl *)",
"Write(../**)"
]
}
}
The deny list matters as much as the allow list. If you don't explicitly block outbound curl calls or writes outside the project root, the agent can make them.
Step 2: Audit auto-install behavior
Check whether your agent is configured to run package installs without confirmation. In a Claude Code setup, look for npm/pip/brew commands in your allowed Bash patterns:
grep -r "npm install\|pip install\|brew install" .claude/settings.json
If those appear in the allow array without a confirmation gate, the agent can pull in new dependencies autonomously. The safer pattern is to restrict installs to specific commands:
{
"permissions": {
"allow": [
"Bash(npm install --save-dev *)",
"Bash(npm ci)"
]
}
}
npm ci installs from the lockfile only — no version resolution, no surprise packages. If the agent needs something that's not in package-lock.json, it will fail and surface that as an error rather than silently resolving to a different version.
Step 3: Verify execution logging
Claude Code writes session transcripts by default. Confirm they're going somewhere you can actually find:
ls ~/.claude/projects/
Each project subdirectory contains .jsonl session files. A quick verification:
ls -lt ~/.claude/projects/$(basename $(pwd))/ | head -5
Expected output: timestamped .jsonl files, one per session. If that directory is empty or missing, logging is not working as expected. You can also enable more verbose logging:
CLAUDE_DEBUG=1 claude
This writes detailed tool-call records to stderr, which you can redirect to a log file for longer sessions.
Step 4: Run a dependency diff after any agent session
Make this a habit before committing agent-generated changes:
git diff HEAD -- package.json package-lock.json requirements.txt
Look for additions you didn't ask for. If the agent added a dependency you don't recognize, pull the source before merging:
npm info <package-name> repository
Check the download count and last publish date. A package with 12 weekly downloads and a recent publish from an unknown author deserves a harder look.
4. What to watch in production
Scope creep in permissions is silent. When you onboard a new tool or give the agent a new capability ("just let it run tests"), that often means broadening an existing permission. Track permission changes in version control the same way you track code changes — your .claude/settings.json should be committed.
Lockfile poisoning is a real vector. If the agent resolves package versions autonomously, a dependency confusion attack can land a malicious package in your lockfile before anyone notices. Running npm audit after every agent session that touched package files is cheap:
npm audit --audit-level=high
Mac vs. Linux vs. Docker environments behave differently. On macOS, agents running in sandboxed environments may have different filesystem access than on a Linux CI runner. Test your permission settings in the same environment where the agent will run in production. A deny rule that works locally might not apply if the agent runs in a container with a different base image.
Log rotation. Claude Code session transcripts grow. If you're running agents heavily, set up a cron to archive old sessions rather than letting them pile up in ~/.claude/projects/. A 6-month-old session log isn't useful, but 50MB of them is annoying.
The Snyk integration angle. If your team is moving toward embedding Snyk or a similar SAST tool in the agent workflow, the key configuration question is whether the scan runs before or after the agent commits changes to a branch. Pre-commit scanning catches issues before they enter history; post-commit scanning is better than nothing but means cleanup work. Set the gate at the right point.
Closing
The performance of the model is mostly a solved problem. The unsolved problem is the permission envelope — what the agent can touch, what it can call, and whether you can reconstruct what it did after the fact.
The three checks to run today: confirm the agent's filesystem scope is limited to the project directory, verify auto-install behavior is gated on a lockfile or explicit approval, and make sure execution logs are writing to a path you can find. If any of those three are unclear, the agent's autonomy is a larger risk than any code it might write.
Next step: add your .claude/settings.json to your repo's PR checklist so permission changes get reviewed like any other infrastructure config.
🐦 Faster updates on X: @baegseungh7061
📚 More in this series: AI Insights
💌 Subscribe: Follow on X or grab the RSS
댓글
댓글 쓰기