You’ve written JavaScript for years. This 60-day program reforges that experience for 2026 — modern JS and TypeScript, the frameworks that matter now, and the AI-engineering skills that separate senior developers from the pack.
Written for mid-level and senior developers (not beginners), this is a structured, day-by-day program that upgrades your JavaScript craft across the whole stack — and adds the one thing most JS developers are still missing: real AI-engineering ability, in the language you already know.
Tag Archives: Development
New AI-Era Attack Vectors
For years the most effective attackers have avoided bringing malware at all. Why smuggle in a payload your EDR will flag when the target machine already ships with everything you need? This is living off the land (LOTL): abusing legitimate, pre-installed tools — PowerShell, WMI, signed system binaries (“LOLBins”) — to operate. Because the tools are allowlisted and the activity looks normal, LOTL leaves no malware signature and blends into routine operations. By 2023, CrowdStrike reported that roughly 6 in 10 detections involved LOTL techniques rather than traditional malware. It works because the safest tool to attack with is one the defender has already decided to trust.
Now consider what just got installed on every endpoint and in every enterprise: an AI agent. It holds credentials. It can call tools, APIs, and databases. It operates inside your network with real access. And — unlike PowerShell — it is eager to please, following instructions wherever they come from. It is, in other words, the most powerful living-off-the-land tool ever deployed, and attackers have noticed.
Living off the agent
The 2026 term for this is “living off the agent.” The attacker brings no malware and exploits no memory-corruption bug. Instead, they hijack the agent’s own legitimate tools, permissions, and workflows, turning your trusted AI assistant into their instrument. The agent already has the access; the attacker just has to redirect it.

The mechanics, at a high level: an attacker plants instructions in content the agent will read — an email, a shared document, a support ticket, a web page, a code comment, a dependency’s docstring. When the agent ingests that content (its entire job is ingesting content), the hidden instructions hijack its plan, and it carries them out using its own sanctioned tools and credentials. This is the classic confused deputy problem: a privileged party (the agent) is tricked by an unprivileged one (the attacker’s text) into misusing its authority — except this deputy operates at machine speed and never gets suspicious.
The reason this is so hard to defend with traditional tooling is that the attack vector is language itself. You can sandbox a binary; you cannot sandbox a sentence. A firewall can block a known-bad domain, but it can’t reason about whether the paragraph in an incoming email is data or a command. And to the agent, there is no reliable difference — text is text.
The parallel-poisoned web
One emerging variant shows how proactive this gets. Researchers have demonstrated a “parallel-poisoned web”: a malicious site that serves benign content to human visitors and a different, instruction-laden version to any AI agent it detects. The attacker sets up one page and waits for agents to arrive. Because the malicious content is delivered dynamically and only to agents, it sails past email filters and malware scanners entirely — and the user, who sees only the clean version, has no idea. It’s a new form of living-off-the-land where, as the researchers put it, the victim’s own trusted AI agent is turned into the attack tool.
Persistence without a foothold
Traditional persistence means leaving something behind — a backdoor, a scheduled task, a modified binary. Agentic systems offer a quieter option: memory poisoning. If an agent has persistent memory, a single planted instruction can silently influence its behavior across future sessions, with no need for the attacker to maintain access. The poisoned memory entry is a backdoor that reloads itself every session, and it lives in your agent’s memory store, not on disk where a scanner would find it. The practical defensive consequence: treat memory writes as security events, log them, and review what an agent is allowed to persist.
Why your existing defences are blind to it
Here’s the uncomfortable part for security teams. Living off the agent defeats the conventional detection stack almost by construction:
- No malware artifacts. There are no file hashes, no dropped executables, no suspicious downloads for EDR to catch. The “weapon” is a string of text that’s already been deleted from the email.
- Legitimate activity. Every action the hijacked agent takes is an authorised API call by an authenticated identity using an allowlisted tool. To your logs, it looks like the agent doing its job.
- No traditional forensic trail. Incident responders accustomed to malware hashes and process trees find little to grab onto. Confirming an attack even happened can require AI-specific logging that most organisations don’t yet have.
The deeper shift is architectural. For a decade, the model was: watch the traffic between the endpoint and a centralised LLM chat app, monitor for sensitive data, and block at the firewall if needed. The perimeter was legible. That model is gone. The agent now operates inside the network, with real data and real tools, and the dangerous activity is indistinguishable from legitimate activity at the network layer.

What this means for how you defend
If the activity is legitimate and there’s no malware to find, detection has to move from artifacts to behaviour — specifically, to the agent’s decisions. You catch a hijacked agent not by scanning its outputs but by noticing that its sequence of actions is abnormal: a triage agent that suddenly reads credentials and opens a network connection is mid-incident, and only a decision-level trace reveals it. That means logging every tool call, delegation, and retrieval (not just final outputs), baselining what a normal tool-call sequence looks like, and alerting on deviation. It also means the harness controls from the previous post — least privilege, scoped credentials, egress allowlists, a tool gateway that enforces policy independent of the model — aren’t optional niceties. They’re the only things standing between “the agent was tricked” and “the agent was tricked into doing real damage.”
The trusted insider you onboarded without a background check
Enterprise AI assistants — Microsoft 365 Copilot, Salesforce Agentforce, ServiceNow Now Assist, Slack AI, Glean — share a profile that should make any security architect nervous. Each one ingests external content (emails, documents, CRM records, tickets, web data), holds privileged internal access (your SharePoint, your CRM, your databases), and can produce output that reaches the outside world (links, images, sent emails, written records). That’s Simon Willison’s lethal trifecta from the previous post — private data, untrusted content, and an exfiltration channel — assembled by default, at enterprise scale, in a system you deliberately gave broad access. As one analysis put it, these assistants are “trusted but indiscriminate insiders.”
In 2025 and 2026, researchers turned that structural exposure into a series of working, zero-click exploits. The pattern across all of them is identical, which is exactly why it matters.
EchoLeak: the zero-click breakthrough
The watershed was EchoLeak (CVE-2025-32711, CVSS 9.3), disclosed by Aim Labs in June 2025 — the first documented case of prompt injection weaponised for concrete data exfiltration in a production AI system, and it required zero clicks.
The anatomy, at the level a defender needs (the vulnerability is patched and the details public): an attacker sends an ordinary-looking email containing hidden instructions. When the victim later asks Copilot something unrelated, Copilot retrieves that email as part of the user’s context — and processes the hidden instructions as if they were commands. Aim Labs named the core failure an “LLM Scope Violation”: the assistant was tricked into crossing its own trust boundary, pulling the most sensitive data from the user’s context and embedding it into an outbound reference. The data then left automatically — through an auto-fetched image and a link proxied via an allowlisted Microsoft domain, which sidestepped the content-security policy. No click, no download, no malware.

What makes EchoLeak instructive isn’t the specific bypasses — Microsoft patched those server-side, and no in-the-wild exploitation was reported. It’s the structural lesson Aim Labs drew and Microsoft’s own response confirmed: patching the CVE does not remove the attack surface. Copilot still ingests external content and still processes it with the same model that has access to your internal data. That mixing of untrusted content and privileged data in one context is a property of how the assistant works, not a bug you can fully patch away. EchoLeak closed one chain of exploits; the class remains.
It was never just Microsoft
If EchoLeak were a Microsoft-specific flaw, you could patch and move on. The disclosures that followed proved it’s endemic to the entire category of RAG-based enterprise agents:
- ForcedLeak (CVSS 9.4) — Noma Security, September 2025, against Salesforce Agentforce. An attacker submitted a public Web-to-Lead form whose Description field carried injected instructions; when an employee’s agent later processed the lead, it exfiltrated CRM data to a domain that had been on Salesforce’s allowlist, expired, and was repurchasable for about $5. Noma’s framing was blunt: AI agents present “a fundamentally different and expanded attack surface compared to traditional prompt-response systems.” Aim Labs added that ForcedLeak is “a subset of these same EchoLeak primitives… endemic to RAG-based agents.”
- Copilot Studio (CVE-2026-21520) and PipeLeak — Capsule Security, late 2025 into 2026. Notably, Microsoft assigned a CVE to a prompt-injection flaw in an agentic platform — which researchers called “highly unusual,” and which carries a signal: if that precedent holds, every enterprise running agents inherits a new vulnerability class to track, one that, as the researchers note, “cannot be fully eliminated by patches alone.” When Salesforce added human-in-the-loop confirmation for email actions, Capsule reported the email channel remained exploitable on custom sub-agents — the majority of real deployments.
The agent-building platforms multiply the exposure further. A productivity assistant can leak what it can read; an agent built on the same platform can also take actions in external systems — send emails, create records, write to databases — which are far more capable exfiltration and impact channels than a chat response, and it does so across longer autonomous task chains before any human reviews the result.

Cross-agent hijacking: the insider recruits other insiders
A distinct and worsening variant appeared with multi-agent enterprise platforms like ServiceNow Now Assist. The systems were designed so that one agent can legitimately ask another to perform an action — so when it happens, no security control thinks it odd. The consequence: if one agent falls to a prompt injection, it can instruct other agents to do worse things, faster than any human could intervene. Researchers liken it to an LLM-powered insider threat — one part of the system undermining another from the inside, the agentic equivalent of lateral movement between microservices. Agent-to-agent trust, established for productivity, becomes a privilege-escalation path.
Why enterprise AI is uniquely exposed
Three properties make this class especially dangerous, and all three are features you paid for:
- Service-account-level reach. The assistant operates with broad organisational access, so an injected instruction can pull data beyond the triggering user’s own privileges — the agent’s permissions, not the victim’s, set the blast radius.
- Shared context. External content and privileged internal data sit in the same model context, with no hard isolation between “stuff to act on” and “stuff to act with.”
- Forensic darkness. The exfiltration is silent and leaves no malware artifacts; standard EDR and SIEM tooling, built for files and processes, can miss it entirely. Confirming an incident can require AI-specific logging most teams haven’t deployed.
The defensive thesis
You cannot patch your way out of a structural attack surface, and you cannot prompt-filter your way out either — every one of these exploits bypassed the vendor’s injection classifier. The durable defences operate outside the model and around the data but the shape is already clear from the incidents: scope the assistant’s data access before it can reach sensitive material (not after the model has it), break the trifecta by separating the agent that reads untrusted content from the one that holds privileged access, lock down output channels (strict CSP, no auto-fetching of external images and links, output DLP, restrained markdown rendering — the exact mechanisms EchoLeak abused), and deploy AI-centric logging so a silent exfiltration isn’t also an invisible one.
We’ve established how attackers turn an agent against you. Now is about how far that reach extends — and it extends much further than most teams have mapped. The moment you connect an agent to your APIs, databases, and tools, you don’t add attack surface linearly. You add a new trust boundary at every connection, and a new privileged identity that legacy security was never designed to govern.

Agents are privileged non-human identities
Start with the identity problem, because it underlies everything else. Every agent you deploy is a non-human identity (NHI) that needs API access and machine-to-machine authentication — and legacy identity and access management was built for humans logging in, not for autonomous software acting continuously across systems. The result in most organisations is NHI sprawl: a growing population of agent identities, often over-permissioned, frequently unmanaged, sometimes entirely unsanctioned (shadow agents that employees wired up under deadline pressure). The correct mental model is uncompromising: an agent is a privileged identity, and you should govern it with the same rigour you apply to an admin account — least privilege, monitoring, audit, and short credential lifetimes.
MCP: capability without containment
The Model Context Protocol is how most agents now reach tools, APIs, and data — and each MCP server is an independently attackable trust boundary. MCP was designed for capability, not containment, and the security numbers reflect it: a February 2026 audit found 43% of publicly available MCP servers vulnerable to command-execution attacks, and one disclosure put up to 200,000 vulnerable MCP instances exposed across IDEs, internal tools, and cloud services. Two attack patterns deserve specific attention:
Tool poisoning — “the new prompt injection.” An attacker hides instructions inside a tool’s metadata or description — text the agent reads but the user never sees. Because the agent treats tool descriptions as trusted, a poisoned description can change how the agent behaves and even override how it uses other, previously safe tools. The model thinks it’s calling a benign search tool; the tool does something else. This is the supply-chain risk of the agent era, and it’s why tool definitions must be reviewed like code, not trusted like configuration.
The confused deputy at the data layer. Many MCP servers execute actions with their own elevated privileges, not the requesting user’s. Picture a database MCP server that holds admin credentials: a user with no database-admin rights asks the agent to “clean up old records,” and the server — which does have admin — dutifully runs it. The user’s lack of privilege was never checked; the server’s privilege was used on their behalf. This is the classic confused-deputy problem, and it’s endemic to tool servers that carry standing credentials.
Databases, APIs, and excessive agency
Beyond MCP, the direct connections matter. An agent that generates and runs database queries introduces text-to-SQL injection and over-broad reads — which is why practitioners now say “database activity monitoring is critical again,” this time watching a non-human identity. An agent with broad API access can be driven to chain individually benign calls into a harmful sequence — excessive agency (OWASP’s LLM06 / the agentic risk catalogue), where the danger isn’t any single permission but the breadth of what the agent can orchestrate. And configuration is not innocent: a 2026 round-up documented remote code execution where config fields in an AI orchestration platform turned out to be code paths, not just settings — a reminder that “settings” an agent can influence may be executable.
The defensive playbook
The throughline of this post is that these attacks abuse legitimate access by a trusted identity, so the defences live in identity, data scope, and behaviour — not in signatures or prompt filters. Here is the consolidated playbook; it is, deliberately, defence in depth, because every credible source agrees no single control is sufficient.

Identity and least privilege. Govern each agent as a privileged NHI: minimal tools and data, short-lived scoped credentials, identity binding, and context-aware authorisation (decisions based on who is asking, the sensitivity of the data, and the action attempted). Crucially, fix the confused deputy by having the agent act as the requesting user — propagating the user’s identity and permissions — rather than with a tool server’s standing privileges.
Scope data access at the source. The EchoLeak lesson: restrict what the agent can reach before it reaches it, not after. Provenance-based access control, retrieval firewalls, pre-ingestion validation, and prompt partitioning keep untrusted content and privileged data from sharing one unbounded context.
MCP and tool hygiene. Allowlist tools; pin and verify MCP server versions with the same rigor as any dependency; review tool descriptions and agent config paths in code review; block auto-approval of new MCP servers; sandbox servers and restrict outbound connectivity from orchestration hosts.
Output channel controls. Lock down exactly what the enterprise exploits abused: strict content-security policy, no auto-fetching of external images or links, output DLP for secrets and PII, and restrained markdown rendering.
Monitoring built for agents. EDR and SIEM watch files and processes; agent attacks hide in decisions. Log every tool call, delegation, and retrieval — the reasoning chain, not just the output — apply user-and-entity behaviour analytics to non-human identities, baseline normal tool-call sequences, and treat memory writes as security events. A hijacked agent reveals itself by an anomalous sequence, not a bad file.
Human-in-the-loop on what matters. Mandatory approval for high-impact, irreversible, and externally-facing actions — tiered by risk so the gate stays meaningful and doesn’t dissolve into approval fatigue.
Align the program to the frameworks now maturing for exactly this: the OWASP Top 10 for Agentic Applications (2026) — which names tool misuse, identity and privilege abuse, supply-chain, code execution, and excessive agency as distinct risks — plus MITRE ATLAS for adversary techniques and the NIST AI Agent Standards Initiative (launched February 2026) for governance.
The whole picture
The agent is a powerful new insider that lives inside your network, holding credentials and wielding tools, and eager to follow whatever instructions reach it. Attackers in the AI era don’t break in — they redirect what you already trust. They live off the agent, they hijack the enterprise assistants you’ve connected to everything, and they reach through the expanding web of APIs, databases, and MCP servers each agent touches. Not one of these attacks requires malware; nearly all of them are invisible to the defences built for the previous era.
That’s why the security has to be built into the workflow and the harness from day one — and why the defensive posture is the same one the industry adopted for malware a decade ago, now pointed at a new kind of insider: assume the agent can be turned against you, govern it like the privileged identity it is, watch its decisions rather than its files, and contain every blast radius so that a hijacked agent stays a contained incident rather than a breach. The capability is extraordinary, and worth having. The discipline is what lets you keep it.
Securing the Agent Harness
Start with a number. An agent that opens 1,000 pull requests a week at a 1% vulnerability rate ships 10 new vulnerabilities every week — quietly, confidently, indefinitely. That’s the uncomfortable arithmetic of autonomy: a small per-action error rate, multiplied by machine-speed volume, becomes a steady stream of security holes. A human writing ten PRs a day can’t produce vulnerabilities fast enough to matter at that scale. An agent fleet can.
This reframes the whole problem. Security for AI agents isn’t a model-quality question you can solve with a better prompt. It’s a systems question, and the answer to “how do I keep this safe?” is the same answer we’ve used for every other dangerous-at-scale system: build the controls into the workflow so they can’t be skipped, and contain the blast radius for when — not if — something goes wrong. As the field’s bluntest formulation puts it: autonomy without security is an automated vulnerability.
You’re securing a harness, not a model
The single most useful mental shift in this entire topic: you cannot fully secure the model, so secure the harness instead.
The “harness” is everything around the model — the runtime scaffold that turns a text predictor into something that acts: its tools, its permissions, its credentials, its sandbox, its network access, the context you feed it, and the gates between it and the real world. The model is the part you can’t make trustworthy (more on why in a moment). The harness is the part you can engineer, and it’s where all real agent security lives.

Why can’t you just secure the model? Because of a result every agent builder should internalise. A 2026 joint study by OpenAI, Anthropic, and Google DeepMind — titled, ominously, “The Attacker Moves Second” — found that under adaptive attack conditions, every published prompt-injection defence was bypassed with success rates above 90%. You cannot prompt-harden your way to safety. The only robust posture is to assume the model will be compromised and build controls outside it that contain what a compromised model can do. This is the same shift the security industry made with malware a decade ago: stop trying to prevent every execution, assume breach, and focus on segmentation, least privilege, and blast-radius containment.
The blast radius principle
Here’s the principle that makes the harness concrete: an agent’s potential damage equals that of an employee holding the same credentials. If the agent can merge to main, it can ship a vulnerability. If it holds a production database token, it can drop a table. If it can make outbound network calls, it can exfiltrate data. The blast radius scales precisely with the privileges you hand it — and in 2026 that’s not hypothetical. In April 2026, a coding agent reportedly wiped a startup’s production database. The damage wasn’t exotic; it was simply an over-privileged agent doing a destructive thing with credentials it should never have held.
So the first question for any agent isn’t “is it smart enough?” — it’s “what’s the worst thing it can do with what we’ve given it?”
Prompt injection: the attack that makes it real
The mechanism that turns “the model might be wrong” into “the model is now working for an attacker” is prompt injection — OWASP’s #1 LLM vulnerability, present in an estimated 73% of production deployments. It comes in two flavours:
- Direct injection: malicious instructions in the user’s own message.
- Indirect injection: malicious instructions hidden in external content the agent processes — web pages, documents, code comments, dependency docstrings, issue and PR bodies, API responses. This is the dangerous one for coding agents, because a coding agent’s entire job is to ingest untrusted content: the repo, retrieved docs, web search results, package documentation. Every one of those is an attacker-controllable input channel.
In agentic systems this gets worse, not better. The OWASP Top 10 for Agentic Applications 2026 introduces ASI01: Agent Goal Hijack — a single injected instruction doesn’t just corrupt one output, it reprograms the agent’s plan, redirecting its multi-step behaviour, triggering privileged tool calls, and persisting across the workflow. A real example landed in May 2026: a CVSS-10 vulnerability in Gemini CLI where a malicious package injected prompts through code comments and docstrings, causing the agent to execute arbitrary commands it believed were legitimate — indirect injection delivered straight through the software supply chain.
The lethal trifecta
The cleanest model for when prompt injection becomes a breach is Simon Willison’s lethal trifecta. An agent is structurally exploitable when it has all three of:
- Access to private data (your repo, your secrets, your database).
- Exposure to untrusted content (anything an attacker can influence — issue bodies, web pages, dependencies).
- The ability to communicate externally (an outbound channel — an API call, a
curl, a public PR comment).

When all three overlap, a single poisoned input becomes an exfiltration pipeline: the agent reads the malicious instruction, pulls your secrets, and ships them out the door — a confused deputy moving faster than your monitoring can react. Remove any one leg and the attack collapses.
And here’s the catch that makes this urgent for developers: a CI/CD pipeline contains the entire trifecta by default. Workflow secrets sit in the runner’s environment, every public issue and PR body is attacker-controlled input, and tools like gh or curl are ready-made exfiltration channels. The Gemini CLI exploit chained exactly this — injection through a public issue, credentials lifted from .git/config on disk, then a pivot to a token with write access. If you’ve added an AI triager or reviewer to your CI, you may have shipped a trifecta without noticing.
Why bolt-on security fails
Put the pieces together and the conclusion is forced. At 10 vulnerabilities a week, a quarterly pentest is laughably out of phase — you’d accumulate ~130 vulnerabilities between assessments. When the model can be compromised >90% of the time by an adaptive attacker, an after-the-fact review of its output misses the architectural problem entirely. And prompt injection, the field’s consensus holds, needs architectural fixes, not bolt-on filters. The numbers say teams know this and aren’t acting on it: an independent 2026 assessment of 100 production agents found only 11% passed a baseline security assessment, and 57% of organisations lacked the visibility to even audit their agents for the trifecta.
Security that’s added after the agent works is security that’s always behind the agent. The only posture that keeps pace is one where the controls are part of the harness from the first commit.
Building the Secure Harness
We’ve previously reached a conclusion, a design principle: assume the model is compromised, and contain the blast radius with controls outside it. Now, we’ll turn that principle into concrete architecture. The unifying idea is defence in depth — stack independent layers so an attack has to defeat every one of them in series, not just slip past a single clever filter. No layer is sufficient alone (adaptive attacks bypass even good classifiers >85% of the time); stacking them is how production contains risk.
The organising constraint: the Rule of Two
Before the individual controls, the design rule that ties them together. Meta’s “Agents Rule of Two” (October 2025) is the most actionable security constraint in agent design: within a single session, an agent should have at most two of these three properties:
- (A) processes untrusted input,
- (B) has access to sensitive systems or private data,
- (C) can change state or communicate externally.

This is the lethal trifecta restated as a build rule. Keep all three apart and the trifecta never assembles. In practice that often means splitting one risky agent into two safe ones — a read-only agent that ingests untrusted content but holds no secrets and can’t reach the network, handing structured results to a write-capable agent that never touches untrusted input. Separating read and write capability is one of the highest-leverage architectural moves you can make.
With that frame, here are the layers.
Layer 1 — Least privilege and least autonomy
The blast-radius principle from before has a direct corollary: give the agent the minimum tools, data, and credentials its task requires, and no more. Treat an agent exactly like a service account — narrowly scoped, audited, and reviewed. Start each new agent with the narrowest possible capability set and a small, well-defined task where the blast radius of failure is contained, then expand deliberately. “What’s the maximum access available” is the wrong default; “what’s the minimum this task needs” is the right one.
Layer 2 — Sandboxing and isolation
Assume the agent will, at some point, run hostile code — generated by a poisoned dependency, an injected instruction, or its own mistake. So run everything it does in an isolated, ephemeral environment with hard resource limits and the ability to roll back.
The 2026 consensus on strength: default to microVMs for untrusted code (Firecracker — the technology behind AWS Lambda, exposed by platforms like E2B — gives each sandbox its own kernel and network namespace, so a guest-kernel vulnerability can’t reach the host), and relax to gVisor or plain containers only when your threat model justifies it. Make sandboxes per-session and disposable with clean teardown so nothing persists between runs, and set hard memory, disk, and CPU limits to stop resource-exhaustion attacks. For coding agents this dovetails with the isolation you already want for parallelism: each agent gets its own throwaway workspace.
Layer 3 — Network egress control
This is the layer that directly kills the trifecta’s exfiltration leg. Agents should run on a zero-trust network: default-deny all outbound traffic, and allowlist only the specific endpoints the task requires. Add DNS restrictions to prevent command-and-control lookups, segment the agent’s network from production systems and sensitive data stores, and watch for anomalies (connections to low-reputation domains, unusually large outbound POSTs). If the agent can only reach three approved hosts, a stolen secret has nowhere to go.
Layer 4 — Scoped credentials and the broker pattern
Credentials are the crown jewels, and there are two distinct goals: keep them out of the model’s context (so the LLM provider never sees them) and out of the agent runtime entirely (so a compromised agent can’t read them). The pattern that achieves both is a credential broker: the agent never holds a real secret — it calls a tool, and a separate broker process, outside the agent’s reach, attaches the short-lived, narrowly-scoped credential and makes the actual API call.
# The agent asks the broker to act; it never sees the credential.
class CredentialBroker:
def call(self, tool: str, args: dict, session: Session) -> Result:
policy.authorize(tool, args, session) # per-tool PERMIT/DENY
cred = self.vault.mint(tool, ttl_seconds=300, # short-lived, scoped
scope=min_scope_for(tool))
try:
return execute(tool, args, cred) # broker makes the call
finally:
self.vault.revoke(cred) # gone after one use
Credentials are minted just-in-time, scoped to the single operation, and expire in minutes. Even a fully hijacked agent can’t exfiltrate a secret it never possessed — and a stolen short-lived token is worthless minutes later.
Layer 5 — The tool gateway
The agent’s reasoning must never be the thing that decides whether a dangerous action is allowed — because we’ve previously established that its reasoning can be hijacked. So put all tool access behind a single policy gate that enforces authorisation, consent, filtering, and audit centrally, so nothing bypasses policy. Per-tool PERMIT/DENY rules (the Cedar policy engine and the cedar-for-agents pattern are built for this) are evaluated against a declared rule — principal, action, resource, conditions — independent of the agent’s reasoning. Expose tools with fixed schemas so the agent can’t improvise novel calls, and wrap your most sensitive integrations as sealed tools running in a separate container. An MCP gateway is a natural home for this — it’s the chokepoint where you sanitise context and enforce allowlists between the agent and everything it can touch.
def gateway(call: ToolCall, session: Session) -> Result:
if not schema_valid(call): # fixed schema — no improvising
return deny("schema violation")
decision = cedar.evaluate(call, session) # policy, not model judgment
if decision != "PERMIT":
return deny(decision)
if call.is_high_impact: # irreversible / sensitive
require_human_approval(call) # tiered gate
audit_log.record(call, session) # decision, not just output
return broker.call(call.tool, call.args, session)
Notice the gateway is also where the later layers attach: human approval for high-impact actions, and an audit record of every decision.
Putting the harness together
Stacked, these layers form a harness where a compromise stays contained:

Trace an attack through it. A poisoned dependency injects an instruction. The hijacked agent tries to exfiltrate secrets — but it holds none, because the broker does (Layer 4). It tries to call a destructive tool — but the gateway’s policy denies it regardless of the agent’s “reasoning” (Layer 5). It tries to phone home — but egress is default-deny (Layer 3). It tries to corrupt the host — but it’s in a disposable microVM (Layer 2). Every layer the attack defeats, another stands behind it. That’s defence in depth, and it’s the difference between a bad session and a production incident.
Security in the Workflow
A secure harness is necessary but not sufficient. 10 vulnerabilities a week from a 1%-error agent fleet is a flow problem, and flow problems need controls in the flow. A harness you configure once protects the runtime; it doesn’t catch the vulnerability in PR #847 on Tuesday afternoon. For that, security has to live in the workflow itself, running on every action the agent takes, automatically. This is the “built-in, not bolted-on” thesis made operational.
Gate every agent PR like untrusted code
The agent’s output is untrusted code — we’ve already established the model can be hijacked, so its commits deserve the same suspicion as a pull request from an anonymous outside contributor:

The deterministic gates run on every agent PR and block on failure:
- SAST (static application security testing) for vulnerability patterns — the direct defence against the 10-vulns-a-week problem.
- Secret scanning so a credential never lands in a commit.
- Dependency and CVE scanning, plus a hallucinated-package check — does every new import actually exist and is it the real package, not a slopsquatted look-alike registered to catch exactly the names models invent (the supply-chain attack).
- IaC scanning for misconfigured infrastructure.
Because these are deterministic, they make trustworthy hard gates — no human time spent on a leaked key or a known-vulnerable dependency. This is shift-left security applied to a contributor that never sleeps.
Tier human oversight so it survives contact with volume
Human approval is the control that stops a hijacked agent’s high-impact action — but naive human review doesn’t scale to agent volume, and worse, it breeds approval fatigue: ask a human to rubber-stamp 200 trivial changes and they’ll rubber-stamp the one dangerous one too. The fix is risk-based tiering, the same Green/Yellow/Red routing, applied to security impact:
- Low-risk (docs, tests, isolated non-sensitive code) → auto-merge with notification.
- High-impact / irreversible (auth, payments, data migrations, production deploys, anything touching the paths from your risk map) → mandatory human approval, every time.
Tiering concentrates scarce human attention exactly where the blast radius is largest, and keeps it sharp by not wasting it everywhere else. Even a lightweight approval step — a Slack confirm, a required reviewer on protected paths — is a meaningful gate. The goal is that no irreversible action happens without a human, without drowning humans in reversible ones.
Audit decisions, not just outputs
You detect a hijacked agent not by reading its final answer but by watching its behavior. So log the agent’s decisions — every tool call, every delegation, every retrieval, every hand-off — not just its outputs. Baseline what a normal tool-call sequence looks like, and alert on deviations: a triage agent that suddenly reads .git/config and opens a network connection is mid-exploit, and only a decision-level trace shows it.
This audit trail does double duty. It’s your incident-response timeline, and it’s your compliance evidence — the record of which agent accessed which data, under which policy, authorized by which human, at what time. (Treat memory writes as security events too: a poisoned memory entry is a backdoor that reloads every session.) The 900+ agent gateways found exposed on the public internet in early 2026 — plaintext credentials, no authentication — failed precisely because there was no governance layer recording and enforcing any of this. Audit is the floor of that governance layer.
The trifecta audit: a gate before production
The lethal trifecta becomes a concrete pre-deployment gate. Before any new agent ships, audit it explicitly:
TRIFECTA AUDIT (run before every agent goes to production)
[ ] Does it access private data? (repo, secrets, DB, customer data)
[ ] Does it process untrusted content? (issues, PRs, web, dependencies)
[ ] Can it communicate externally? (network, public comments, APIs)
All three present? → DO NOT SHIP without compensating controls:
• break it with the Rule of Two (split read-only from write-capable), OR
• content inspection + strict tool scoping + mandatory human gates on egress
Assign an explicit owner to each leg. "Logging" is not "prevention."
Make this audit a required, version-controlled step — not tribal knowledge. Only 11% of production agents passed a baseline security assessment in 2026, and 57% of organizations couldn’t even answer these three questions for their agents. Being able to answer them, on every agent, before it ships, already puts you ahead of the overwhelming majority.
Govern from day one
Tie it together with a governance layer that exists from the first commit, not after the first incident. Version-control your agent security policy and risk map alongside the code; align your controls to a recognised framework — the OWASP Top 10 for Agentic Applications 2026, MITRE ATLAS for adversary techniques, and the NIST AI Risk Management Framework for lifecycle governance — so you’re not inventing controls from scratch; and gate the installation of new tools and plugins behind review (CODEOWNERS plus CI schema validation), since a new tool is a new capability and a new piece of attack surface. Governance isn’t a launch-day checklist; it’s the substrate the agent runs on.
The whole picture
Assemble the three parts and the architecture is coherent. You secure the harness, not the model, because the model can be compromised — and a coding agent’s blast radius at machine speed makes that compromise expensive. The harness is defence in depth organised by the Rule of Two — least privilege, ephemeral sandboxing, default-deny egress, a credential broker, and a policy gateway that doesn’t trust the model’s reasoning. Security lives in the workflow — deterministic gates on every PR, risk-tiered human approval, decision-level audit, and a trifecta gate before production — all sitting on a governance layer present from day one.
The thread through every layer is the same: a single compromised agent should stay a single bad session, never a production-wide incident. You get there not by trusting the agent more, but by engineering the workflow so that trust is never required — the controls run whether the agent is behaving or not. That’s what “built into the workflow, not bolted on” actually means, and at 10 vulnerabilities a week, it’s the only thing that keeps pace.
