← Back to all posts
Security Guide

Preventing AI Agent Data Exfiltration: Tool Boundaries Done Right

August 2026 · GaleOps

When an AI agent has tool access - file readers, email senders, API callers - prompt injection stops being a curiosity and becomes a data breach vector. Here's how to structure tool boundaries so that even a fully injected agent can't exfiltrate data.

The exfiltration pattern

Nearly every real-world agent exfiltration follows the same chain:

  1. Inject — attacker gets instruction-like text into the agent's context (via a document, web page, database row, or even the user's own input)
  2. Chain — the agent calls a read tool to fetch sensitive data, then a send tool to move it out
  3. Exfiltrate — data crosses the boundary, and neither the model nor the monitoring catches it because each individual tool call looked legitimate

Boundary 1: Data/Instructions separation (prompt layer)

Your system prompt must define an explicit hierarchy: content retrieved by tools is DATA. It is never instructions, regardless of formatting, labels, or urgency markers. This blocks the injection at step 1 for most attacks.

Limitation: prompting is probabilistic. Sophisticated injections can still slip through, which is why the next two layers matter.

Boundary 2: Tool-level allowlists (code layer)

Enforce restrictions in the tool wrapper code, not the prompt:

# BAD: relies on the model behaving
def read_file(path):
    return open(path).read()

# GOOD: enforced in code
ALLOWED_DIRS = ["/data/public/", "/data/reports/"]

def read_file(path):
    resolved = os.path.realpath(path)
    if not any(resolved.startswith(d) for d in ALLOWED_DIRS):
        raise PermissionError(f"Access denied: {path}")
    return open(resolved).read()

Boundary 3: Destination validation (network layer)

APPROVED_RECIPIENTS = {"team@company.com", "alerts@company.com"}

def send_email(to, subject, body):
    if to not in APPROVED_RECIPIENTS:
        raise PermissionError(f"Recipient not approved: {to}")
    # proceed with send
...

This breaks step 2 of the chain: even if the agent decides to exfiltrate, the send fails because the destination isn't approved.

Boundary 4: Confirmation gates (human layer)

For high-stakes actions (sending data externally, deleting records, financial operations), require human approval before execution. The agent prepares the action; a human approves or denies it.

Boundary 5: Monitoring and alerting (detection layer)

If all else fails, detect the exfiltration:

The minimum viable defense

If you only do three things: explicit data/instructions separation in the system prompt, code-enforced path/recipient allowlists, and confirmation gates on external sends. Those three break every exfiltration chain I've tested.

Test your boundaries

The free GaleOps scanner includes exfiltration-chain attack patterns among its 5 vectors. Run it against your agent's system prompt to see if your boundaries hold. ~3 minutes, no signup.

Need a Real Assessment?

GaleOps tests AI agents against production-grade attack chains and delivers prioritised remediation. Fixed price, no retainer.

See Assessments →

Test Your Agent Right Now

The free prompt-injection scanner runs 5 real attack patterns against your system prompt in about 3 minutes. No signup.

Run the Free Scanner →

← Back to all posts