Book a Free Strategy Call
Skip the read: talk to Walid in 30 min.
Free strategy call. We map your AI engineering team, you keep the notes.
AI agents introduce a distinct attack surface: autonomous execution capability that an adversary can commandeer. This guide covers eight practical controls that address the most common failure modes for teams deploying agents in production.
What the Hugging Face breach showed. On July 20, 2026, Axios reported that Hugging Face had disclosed a breach of part of its production infrastructure that it described, in its own incident writeup, as driven end to end by an autonomous AI agent system. Over a single weekend, the attacking agent uploaded a malicious dataset, exploited two code-execution vulnerabilities in Hugging Face's dataset-processing pipeline, escalated privileges, and harvested credentials, executing more than 17,000 actions with no human operator directing the intrusion step by step. Hugging Face said the incident reached a limited set of internal datasets and service credentials, with no evidence of tampering with public models, datasets, or Spaces. We are not claiming inside knowledge of the incident beyond what Hugging Face and Axios reported; we cover it here because it is the second documented case in three weeks of an autonomous agent driving a full attack chain without a human at the keyboard.
On July 1, 2026, Sysdig's threat research team published documentation of what they assessed to be the first fully autonomous AI-driven ransomware operation. The attacker, which they named JADEPUFFER, exploited an unauthenticated remote code execution flaw in Langflow (CVE-2025-3248), then handed execution to an AI agent that conducted reconnaissance, harvested credentials, moved laterally, escalated privileges, and encrypted 1,342 Nacos service configuration items using MySQL's AES_ENCRYPT() function. The original tables were dropped. The encryption key was generated ephemerally and never stored or transmitted, making recovery impossible even in theory. The entire intrusion from initial access to ransomware deployment was executed without a human operator issuing step-by-step instructions. When a login step failed, the agent diagnosed the root cause and issued a corrected multi-step payload 31 seconds later.
That is not a hypothetical. It is a documented case that shows what the risk looks like when none of these controls are in place.
The same week brought a different failure mode: not an autonomous agent attacking, but agentic tools with a hole an attacker could walk through. On July 22, 2026, The Hacker News reported that researchers at Manifold Security found a flaw in Microsoft's official Azure DevOps MCP server: pull request descriptions accept Markdown, so an attacker can hide instructions inside an HTML comment that renders as nothing in the web UI but is still returned verbatim by the API. An agent reviewing the PR reads the hidden text as a command, not as PR content, because the specific tool that returns PR descriptions (repo_get_pull_request_by_id) was missing the "spotlighting" defense, wrapping untrusted content in delimiters, that Microsoft had already applied to other tools in the same server. In the researchers' proof of concept, the hidden instructions got an agent to approve the PR, trigger pipelines in unrelated projects, and exfiltrate confidential wiki pages, all without alerting the human reviewer. As of this writing, Microsoft has acknowledged the report but no fix has shipped and no CVE has been assigned; cybersecuritynews.com independently reported the same mechanism and status.
The second is AWS Kiro, an agentic coding IDE. Intezer's research team, working with Kodem Security, found that Kiro would rewrite its own MCP configuration file, ~/.kiro/settings/mcp.json, the file that lists which MCP servers Kiro is allowed to launch and how, without requiring approval. An attacker only needed to hide instructions in a web page using near-invisible CSS (white text at 1 pixel), get Kiro to fetch that page, and the agent would write a malicious server entry into its own config and reload it, with no approval prompt shown. As the researchers put it, "the agent can therefore edit its own trust boundary." The finding was reported through HackerOne on February 11, 2026, escalated to AWS's Vulnerability Disclosure Program on March 6, and AWS confirmed a fix, shipped in v0.11.130, on April 3, 2026, ahead of the public writeup on July 21, 2026. No CVE was assigned. The fix marks mcp.json as a protected path that now requires explicit approval to modify, in every mode.
Neither of these is a model failure. Both are the same category of bug: a tool that hands an agent untrusted content, a PR description, a fetched web page, without marking it as data instead of instructions, plus a configuration surface the agent could rewrite without a human in the loop. That is exactly the gap section 4 below covers for untrusted input, and the gap section 8 covers for MCP configuration specifically.
We run agent fleets ourselves, including the Claude Code agent swarm that builds and maintains this site, and we have applied every practice here to our own setup before recommending it to anyone else.
Quick reference: eight practices at a glance
| Practice | What it prevents | Effort |
|---|---|---|
| Permission scoping | Blast radius from a compromised or manipulated agent | Low |
| Tool allowlists | Agents calling tools they were never meant to use | Low |
| Sandboxing | File system and network actions escaping the intended scope | Medium |
| Prompt injection defenses | Adversarial instructions in untrusted input redirecting agent actions | Medium |
| Audit logging | Invisible agent actions you cannot investigate after the fact | Low |
| Human gates for outward actions | Irreversible actions (deploys, emails, payments) running without review | Low |
| Secrets handling | Credentials leaking through logs, transcripts, or generated code | Medium |
| Supply chain checks | Third-party skills and MCP servers carrying hidden behavior | Medium |
Related Reads
1. Permission scoping: give agents only the access the task requires
The single most cost-effective security control is also the most consistently skipped. Most agents we see in the wild have broader permissions than their actual job requires: write access to directories they only read, shell access when only file edits are needed, full database credentials when only one schema is relevant, API keys with admin scope for endpoints that only need read.
Broad permissions exist not because teams made a conscious decision to give them but because the path of least resistance during setup is to hand over a full key and move on. The problem surfaces when the agent is manipulated or compromised, because the attacker inherits whatever the agent had.
The JADEPUFFER case illustrates this directly. The attacking agent had access to MySQL root credentials and broad environment variable access on the Langflow host. Researchers noted methodical container-escape probing through MySQL's file primitives, suggesting the agent was systematically testing what access it had before proceeding to destructive phases. Wide permissions give an adversarial agent a richer toolkit.
How to apply this:
Start by listing what the agent actually needs to do its job, not what it might need in some edge case. Then map that list to the minimum set of permissions that covers it. For Claude Code agents specifically, this means:
- Using the
allowlist insettings.jsonto explicitly permit only the tools the agent needs for a given task context - Creating service accounts or API keys scoped to the specific resource and operation type the agent uses (read-only where only reading is needed, scoped to one database schema, restricted to one S3 bucket prefix)
- Revoking permissions that were granted for a one-time task and never cleaned up
- Reviewing the permission set before each new agent deployment, not just at initial setup
Least privilege is not a one-time hardening step. It degrades as agents are extended and tasks change.
Free weekly brief
Steal our production automations
The exact n8n flows, Claude Code setups, and prompts we ship for clients, broken down step by step. No spam, unsubscribe anytime.
2. Tool allowlists: make the tool list explicit
A tool allowlist defines which tools an agent can call. It is the difference between an agent that could theoretically call any available tool and an agent that can only call the tools it is supposed to use.
Most agent frameworks, including Claude Code, support explicit tool permission controls. The problem is that teams often leave this unconfigured, either trusting the default set or not knowing the mechanism exists. An agent with access to shell execution, file writes, and network calls is a significantly larger attack surface than one that can only call the specific tools its task requires.
This matters independently of permission scoping. An agent with narrow permissions but unrestricted tool access can still be manipulated into calling tools it was not intended to use. The allowlist prevents that.
How to apply this:
For Claude Code, define your tool permissions in settings.json at the project level:
{
"permissions": {
"allow": [
"Read",
"Edit",
"Bash(git status)",
"Bash(npm run test)"
],
"deny": [
"Bash(curl *)",
"Bash(wget *)"
]
}
}
The pattern is: start with a minimal allow list based on the task, then add tools deliberately as the task definition requires them. Do not start with a broad default and try to deny specific things. Deny lists miss what you did not think of. Allow lists are closed by default.
3. Sandboxing: constrain what agents can touch
Sandboxing isolates agent execution so that even a fully compromised agent cannot reach outside its intended scope. This is defense in depth: it limits the blast radius when something goes wrong, regardless of how it went wrong.
For code-writing agents, this typically means:
- File system scope: agents should have write access only to directories relevant to their task. A frontend agent does not need access to infrastructure config directories. A testing agent does not need access to the deployment scripts.
- Network scope: agents that process documents or call internal APIs do not need unrestricted outbound network access. An allowlist of permitted hosts and ports limits exfiltration paths even if the agent is manipulated.
- Process scope: agents running shell commands should do so in an environment without access to production credentials. This often means separate CI/CD pipelines for agent-written code, with production credentials gated behind a deploy review step.
For agents running in containerized or cloud environments, standard isolation controls apply: network policies, IAM role boundaries, read-only volume mounts for directories the agent should not modify.
The JADEPUFFER operation did not benefit from meaningful sandboxing on the target. The agent had access to the full host environment, multiple databases, and internal network ranges. A sandboxed deployment would have confined the initial RCE to a limited execution context before any credential harvesting could begin.
What this looks like in practice:
We run our own Claude Code agents in worktrees isolated from the main branch, with file write access scoped to the specific files relevant to the task. Network calls to production systems require a human-approved step. This is not a heavy setup. It is a few lines of configuration and a consistent practice of scoping tasks before launching agents.
4. Prompt injection defenses: treat untrusted input as adversarial
Prompt injection is the attack where instructions hidden in content the agent reads cause it to take actions the operator did not intend. The attacker is not attacking the model directly. They are attacking the boundary between untrusted data and trusted instructions.
This is the most common gap we find when reviewing agent deployments, because it is also the gap that feels theoretical until it is not. Teams test the happy path: a correctly formatted request produces the right output. They rarely test what happens when the content the agent reads contains instructions designed to redirect it.
The Perplexity Comet case documented by Brave's security team in August 2025 showed indirect prompt injection working against a production AI assistant: adversarial instructions embedded in a webpage caused the agent to execute sensitive cross-site actions, including fetching one-time passwords from the user's Gmail when asked to summarize the page. The agent followed the instructions because it could not distinguish them from legitimate content.
For code-writing agents, the attack surface includes: GitHub issues an agent is asked to triage, support tickets it processes, documentation it reads during research, web pages it fetches, and any database rows it queries. Each is a potential injection vector if the agent has outbound tool access.
Defenses that are actually deployable:
The strongest defense is structural: separate the roles of "content processor" and "action taker." An agent that summarizes content should not have the same tool access as an agent that executes changes. If a summarizing step finds actionable items, a separate agent with appropriate scope acts on them. This limits what an injection can do even when it succeeds.
For agents that must both read and act:
- Treat all externally sourced text as untrusted data, not as instructions. This is a prompting constraint: the system prompt should make explicit that user-provided content is data to be processed, not commands to be followed.
- Add a structured output step before any irreversible action. Instead of "read ticket, fix bug, commit," the flow is "read ticket, produce structured task spec, human or a second agent reviews spec, then fix bug." The injection can corrupt the spec but the review gate catches it before execution.
- Log what the agent read before each tool call. If an action is later found to be anomalous, you need to trace it back to the input that triggered it.
5. Audit logging: record what agents do and why
If an agent takes an action you cannot explain, you have a problem you cannot diagnose. Audit logging is the practice of recording enough information about agent activity that you can reconstruct what happened, trace anomalous actions to their inputs, and detect patterns that indicate manipulation or misconfiguration.
Minimum useful log content per agent action:
- Timestamp
- Which agent ran (agent ID or label)
- Which tool was called with what arguments (sanitized for secrets)
- What input triggered the tool call (the relevant context window slice, if practical)
- The result
This is not the same as saving every token of every conversation. The goal is traceability: given an unexpected file change, a failed deploy, or an anomalous API call, you can reconstruct the decision chain that produced it.
For Claude Code specifically, the transcript files in .claude/ capture much of this, but they are not structured logs. If you are running agents in production contexts, purpose-built event logging (a simple append-only file, a structured log aggregator, or a session recording tool) is more reliable for post-incident investigation than reading through markdown transcripts.
The practical value shows up quickly. We have used our own agent logs twice in the past six months to trace anomalous commits back to ambiguous task descriptions that should have been more tightly scoped. In both cases the agent did exactly what its instructions implied, not what the operator intended. The logs made the root cause obvious in minutes. Without them, we would have been reviewing diffs manually.
6. Human gates for outward actions: require approval before irreversible steps
Some actions an agent can take are difficult or impossible to reverse: deploying to production, sending emails, posting to external services, deleting records, making payments, merging pull requests into a protected branch. For these, a human approval step before execution is not a bottleneck. It is a control.
This is also where the risk profile of AI agents differs most sharply from traditional automation. A script that deploys on every merge is a known, predictable behavior. An agent that deploys based on its interpretation of a task description can be unpredictably triggered by edge cases, ambiguous inputs, or adversarial instructions. The unpredictability is exactly the reason human gates matter here even when they would be unnecessary for a deterministic system.
Practical implementation:
Claude Code's permission system supports interactive approval for specific tools and actions. For agents running in CI or headless contexts, the pattern is to have the agent produce an action proposal (a structured description of what it wants to do) rather than executing directly, and to require a human or a second review agent to approve the proposal before the execution step runs.
For outward actions that are genuinely irreversible, the gate should be mandatory regardless of how confident the agent appears. Confidence in an agent's output is not the same as correctness. An agent that has been injected with adversarial instructions will also appear confident.
We apply this rule to our own setup: agent commits are automatic, pushes require a human. Agent-generated PR descriptions are automatic, merges require review. This is not a technical constraint imposed by the framework. It is a practice the team follows deliberately, because the cost of an unreviewed production push is higher than the time the approval step takes.
7. Secrets handling: keep credentials out of agent context
Agents introduce new paths for secrets to leak: into generated code, into tool-call arguments that get logged, into conversation transcripts that get shared, into MCP server configurations, and into model context windows that may be transmitted to a third-party API endpoint.
Each of these is a distinct exposure, and most teams have not audited all of them.
Common patterns to address:
Credentials should not be resolved into plaintext in the same environment where the agent runs unless the agent explicitly needs them for a specific tool call. Use references (environment variable names, secret manager paths) in agent configurations, not the values themselves. The agent knows to call DATABASE_URL from the environment; it does not need to see postgres://root:actualpassword@hostname.
Scan agent-generated code for secrets before it is committed. Claude Code's pre-commit hook capability exists precisely for this. A hook that runs a secret scanner on staged files before every commit is a one-time setup that prevents the most common accidental credential commit pattern.
Audit what goes into transcripts and logs. Tool-call arguments are often logged verbatim, which means a database credential passed to a connection tool ends up in a plain-text file. Sanitize secrets from structured logs. Do not rely on agents redacting them.
For MCP server configurations: each server that handles secrets needs its own review. An MCP server that proxies database calls should use a least-privilege service account for that database, not a shared admin credential.
8. Supply chain checks: verify every third-party skill and MCP server
Agent skills and MCP servers are third-party code and instructions that execute with your agent's privileges. This makes them a supply chain risk with a profile closer to npm install than to reading a document.
Public skill marketplaces and MCP registries carry supply chain risk. Malicious packages have been published to appear useful while carrying hidden behavior that runs with the installing agent's privileges, meaning the malicious behavior has access to everything the agent has access to. The lesson applies to any public skill or MCP registry.
For our own setup, we treat every skill and MCP server as untrusted until:
- We have read the full source code, not just the description or README.
- The source matches what is installed (no post-install mutation).
- The skill or server has no network calls that are not explained by its stated function.
- The permission footprint matches the task (a text-processing skill that wants shell access is suspicious).
This is more work than installing from a registry. It is also the only way to know what is actually running with your agent's permissions.
For teams that cannot audit every skill themselves, the practical alternative is to restrict the install surface: only install skills from sources your team controls or has formally reviewed, use pinned versions so you know exactly what is installed, and run a diff before every update.
We built our own supply chain scanning practice (pin-guard) specifically because we discovered skills with permission footprints that were inconsistent with their stated purpose. You do not need our tooling to apply the same practice. A manual read of any skill before installation is the baseline.
How these practices interact
These eight controls are not independent. They compound.
An agent with narrow permissions that is also sandboxed and running behind a human gate for outward actions has three separate layers of containment. An injection that succeeds against the prompting layer still cannot call tools outside the allowlist. A compromised skill still cannot reach outside the file system scope. A manipulated agent still cannot push to production without review.
This is the architecture that makes sense for any agent deployment that touches real systems: overlapping controls, each of which reduces the impact of a failure in any other layer.
The JADEPUFFER attack succeeded because none of these layers were in place. The agent had root database credentials. It had unrestricted internal network access. There was no tool allowlist. There was no sandboxing. There were no human gates. The RCE vulnerability gave the attacker an execution context, and from there the agent could do everything.
Patching CVE-2025-3248 would have prevented this specific attack. But the practice of applying these eight controls would have contained any similar agent compromise regardless of the initial access method.
Practitioner notes: what we have learned running agent fleets
We run a Claude Code agent swarm on this project. Multiple agents, specialized by domain, building and maintaining a production website. We applied each practice in this guide to our own setup before we wrote about it.
A few things we learned that are not obvious from reading security documentation:
Permission drift happens fast. Agents get extended with new tasks and the permission set follows. Scope creep in permissions looks exactly like normal configuration changes. We schedule a permission audit every time we expand an agent's task scope, not just at initial setup.
Human gates slow things down in ways that are easy to skip. The temptation is real. An agent just wrote a clean diff, the tests pass, and the gate feels like overhead. We have kept the gate anyway, because the cases where we caught problems at review were exactly the cases where the diff looked clean.
Log volume is lower than expected. We worried that structured event logging per agent action would produce unmanageable output. In practice, agents do fewer tool calls per task than we assumed, and the logs are genuinely useful for debugging task descriptions, not just for security. The security value is a side effect of something operationally useful.
Skills are the easiest surface to overlook. Reviewing installed skills once at setup is not enough. Skills update. A skill that was clean on first install may not be clean after an update. We treat skill updates like dependency updates: review the diff before accepting.
Frequently asked questions
What is the most important of these eight practices to implement first?
Permission scoping. It is the lowest-effort control and it limits the blast radius of every other failure mode. If an agent can only do what its task requires, a successful injection or supply chain compromise has a ceiling on what it can accomplish. Start there, then add audit logging so you can see what is actually happening.
Do these practices apply to agents that only read data and never write?
Yes, but with a different risk profile. Read-only agents can still leak data through logs, transcripts, or outbound calls. Prompt injection in a read-only context can still cause data exfiltration if the agent has any outbound capability. Audit logging matters more for read-heavy agents, not less, because their outputs are the attack surface.
How do prompt injection defenses interact with RAG-based agents?
RAG retrieval is an injection vector. Every document chunk retrieved from an external source should be treated as untrusted input. The structural defense (separate content processing from action execution) applies here: a retrieval step produces data, a separate step with tightly scoped tools acts on it. Never retrieve content and act on it in a single unbounded step.
We use an agent framework that handles permissions for us. Do we still need to configure these controls manually?
The framework handles the mechanism, not the configuration. A framework that supports tool allowlists only enforces them if you define the list. Default configurations in most agent frameworks are permissive. The defaults exist to make getting started easy, not to make production deployments secure. Review the defaults and override them explicitly.
What is the difference between a skill supply chain risk and an MCP server supply chain risk?
Both run with your agent's privileges. Skills are typically prompt-level: they inject instructions and context into the agent's behavior. An MCP server is a code-level execution environment: it handles tool calls and can execute arbitrary code on the host. MCP servers are higher risk for active code execution; skills are higher risk for behavioral manipulation. Both require the same review process: read the source, verify the permission footprint, pin the version.
Our agents run in a private cloud environment. Is the supply chain risk still relevant?
Yes. The supply chain risk is about what you install, not where you run it. A malicious skill installed into a private cloud environment runs with the same privileges as in a public one. The isolation of your infrastructure does not protect you from behavior introduced by code or instructions you installed.
How do we handle secrets in multi-agent architectures where agents call each other?
Each agent in a chain should receive only the credentials relevant to the tools it calls in that step. Passing a full credential bundle through the chain multiplies the exposure at every step. Design inter-agent interfaces to pass task context and structured data, not raw credentials. Credentials are resolved at the point of use from a controlled source (environment, secret manager), not passed along as payload.
Is a Claude Code security audit the same as a general AI security assessment?
No. A general AI security assessment typically covers model-level risks (bias, output quality, adversarial robustness). A Claude Code security audit is focused on the agent deployment: the permissions and tool access the agent holds, the skills and MCP servers it runs, the code it generates, and the injection exposure it carries. The two assessments address different things. If you are shipping agent code to production, the deployment security review is the one you need first.
If you are implementing these practices and want a structured review of your current Claude Code or agentic AI deployment, AY Automate runs dedicated Claude Code security audits covering prompt injection exposure, tool permission scope, MCP server risk, and hook configuration. 30-minute discovery call, no slides. Book a security audit call to map the gaps before something goes wrong.
Continue Reading
7 Best AI Agent Security Tools in 2026 (Verified, Compared)
What the Hugging Face breach showed. On July 20, 2026, Axios reported that Hugging Face had disclosed a breach of part of its production infrastructure that it described, in [its own incident write…
OpenAI Codex CLI vs Claude Code: Which Terminal Coding Agent Should You Use? (2026)
Both are terminal coding agents that edit files, run commands, and iterate on their own. An honest, verified comparison of OpenAI Codex CLI and Claude Code: install, pricing, permissions, and ecosystem, no invented benchmarks.
Claude Mythos: The AI Model Anthropic Says Is Too Dangerous to Release (And What It Found)
Claude Mythos: The AI Model Anthropic Says Is Too Dangerous to Release (And What It Found)
Book a Free Strategy Call
Building this in production?
Walid runs a 30-min call to map your AI engineering team. Free, no slides.
Free weekly brief
Steal our production automations
The exact n8n flows, Claude Code setups, and prompts we ship for clients, broken down step by step. No spam, unsubscribe anytime.

Robel engineers production-grade automation pipelines at AY Automate, focused on integrations, reliability, and the systems that keep client workflows running.



