Skip to main content

egress-guard

Deterministic, dependency-free detection of two things a task run inside a sandbox has no legitimate reason to do:

  • reaching for the host — the container runtime socket, host memory, the cloud metadata endpoint, the orchestrator's credentials; and
  • contacting a host it never declared — any external host outside the run's own egress allowlist.

It is defensive. It recognises these patterns in order to flag them and stop a run. It performs none of them, and it executes nothing it inspects — every rule is a regular expression over the text of an agent's tool calls and transcript.

from egress_guard import run_detectors

hits = run_detectors(tool_calls, egress_allowlist=["*.example.com"], messages=transcript)
for hit in hits:
    print(hit.category, hit.rule, hit.evidence)

The one rule that matters

Internal is fine; external is not.

A run whose task is to probe or attack its own declared target inside the sandbox is working correctly and must never be flagged — otherwise the guard gets switched off, which is worse than no guard. The alarm is only for reaching outside the declared boundary. So the caller's egress allowlist is not just the enforcement boundary; it is the definition of "external" that the library tests against. With an empty allowlist, every external host is flagged — the correct default for a run that declared no egress.

Offensive-shaped tooling is judged by where it points, not by its name: the same scanner aimed at a declared internal target and at a public address are different events, and only the second is a hit.

Why deterministic, not a model

These behaviours are not subtle. They are enumerable, and a named rule for each has no false-negative rate from model weakness and needs no calibration. That is the opposite regime from catching subtle deception, where rules are useless and you need a model. Use the right instrument for each: this is the cheap, exhaustive one for the blatant cases.

Evasion is handled before matching

Anything that changes a command's spelling without changing its effect is normalised first, so a literal rule sees through it:

written as normalised to
curl http://2852039166/ 169.254.169.254 (integer-encoded IP)
curl http://0xa9fea9fe/ hex-encoded IP
n''m''a''p -p- … nmap … (shell-quote splitting)
echo <base64> | base64 -d | sh the decoded payload, appended

API

  • run_detectors(tool_calls, egress_allowlist=(), messages=())list[Hit] — the main entry point; scans both what the agent did and what came back, and labels anything found only in the transcript as a mention rather than an action.
  • detect_host_escape(tool_calls)list[Hit]
  • detect_undeclared_egress(tool_calls, egress_allowlist=())list[Hit]
  • is_internal(host)bool
  • normalise(text)str

Each Hit carries a detector_id, a category (sandbox_escape or external_attack), a human-readable rule, the matched evidence, and the index of the tool call it was found in.

The names run_containment_detectors, detect_sandbox_escape, and detect_external_attack are kept as aliases for callers migrating from an in-tree copy.

Scope, honestly

This is a tripwire, not a sandbox. It tells you an agent reached for the exit; it does not contain anything, and a determined adversary who knows the exact rules can craft around them. Its value is catching the blatant, enumerable cases cheaply and without a false-negative rate — pair it with a real sandbox and, for subtle cases, a model-based monitor. Do not rely on it as your only boundary.

Licence

Apache-2.0. Built for AnyEval; useful anywhere agent traces need a cheap, deterministic boundary check.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

egress_guard-1.0.0.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

egress_guard-1.0.0-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

Details for the file egress_guard-1.0.0.tar.gz.

File metadata

  • Download URL: egress_guard-1.0.0.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for egress_guard-1.0.0.tar.gz
Algorithm Hash digest
SHA256 4f2fd8937e7972e6a1c8d9e9af342f50458a9ef7d821e2de1035244ad6826f92
MD5 6b5925c22b873d5028d5610cd040272f
BLAKE2b-256 0525d16fd1e38c1de608b710680f4e932222b5506598996a69641e021365bd6c

See more details on using hashes here.

File details

Details for the file egress_guard-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: egress_guard-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 12.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for egress_guard-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cc486210bd233ac255f374daf644a9236e8bce5a542caa73b9357d6478085799
MD5 c8e732816d04819df8494ed32dfed311
BLAKE2b-256 823317a55950dd3a0cb3b0412a3f8090366ae5e384ce01e454c3bebbfe734978

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page