An egress allowlist limits where an agent is permitted to send network traffic, typically by restricting domains and IP ranges at the execution layer. In Claw EA, you define the allowlist as policy-as-code in a WPC and bind execution to that policy using a CST, so the agent cannot “prompt its way” into new network access.
Egress allowlist enforcement is optional and is typically implemented outside clawproxy, at the sandbox or infrastructure boundary (container networking, host firewall, VPC egress, or a dedicated egress proxy). Claw EA focuses on making the intent and the run verifiable: the WPC is hash-addressed and the run can produce proof bundles with gateway receipts for model calls.
Step-by-step runbook
Use this runbook when running OpenClaw as the baseline agent runtime and you want predictable outbound traffic boundaries. The goal is to fail closed: if the allowlist cannot be enforced, the job should not run.
-
Write an egress allowlist policy in a WPC.
Include the exact domains (and subdomain rules) plus IP CIDRs you want to permit, and include an explicit default deny.
-
Publish the WPC to the WPC registry and record the policy hash.
Because the WPC is signed and hash-addressed, you can pin later execution to the specific policy version instead of “latest”.
-
Issue a CST for the job with optional policy hash pinning.
The CST should be job-scoped so it cannot be replayed across jobs, and the scope hash should reflect the exact egress allowlist intent.
-
Enforce egress at the execution boundary (optional; implemented outside clawproxy).
Common patterns are: run tools in Docker with controlled networking, attach a dedicated egress proxy that only permits allowlisted destinations, or enforce host-level firewall rules bound to the sandbox process identity.
-
Route model traffic through clawproxy so you get Gateway receipts.
This makes model calls auditable even if the agent is compromised, because the receipts are emitted by clawproxy and can be verified later.
-
Export the run’s proof bundle and store it for review.
Store the proof bundle internally and, when appropriate, publish a Trust Pulse artifact for audit viewing.
Threat model
Egress allowlists are about containment: assume the agent will eventually see malicious instructions and try to reach unexpected endpoints. Prompt-only controls are not sufficient because they do not change what the process can do once a tool can open sockets.
| Threat | What happens | Control |
|---|---|---|
| Prompt injection causes data exfiltration | The agent tries to POST secrets or files to an attacker-controlled domain. | Default-deny egress, allowlist only required vendor APIs; keep tools sandboxed and reduce filesystem access. |
| SSRF to internal network | The agent reaches RFC1918 or metadata IPs and extracts credentials or config. | Deny private CIDRs and metadata IPs; explicitly allow only known public CIDRs if needed. |
| DNS-based bypass | The agent uses DNS to resolve domains that later point to disallowed IPs, or uses raw IPs to bypass domain rules. | Enforce by IP at the network boundary; if you allow domains, resolve and pin to permitted IP ranges where possible. |
| Tool-side network access escapes model proxying | Even if model calls go through clawproxy, a tool can still call the internet directly. | Implement egress enforcement outside clawproxy; treat clawproxy receipts as model-call evidence, not full network coverage. |
| Policy drift between environments | Dev runs allow broad internet while prod is locked down; incidents become hard to reproduce. | Bind job execution to a WPC hash and include the WPC hash in the run metadata so reviewers can compare runs deterministically. |
Policy-as-code example
This is a JSON-like sketch of how teams typically represent egress allowlists in a WPC. The key point is that the allowlist is machine-enforced at runtime and referenced by hash, not described in natural language prompts.
{
"wpc_version": "v1",
"control": "egress_allowlist",
"default": "deny",
"allow": {
"domains": [
{ "pattern": "api.openai.com", "ports": [443] },
{ "pattern": "*.openrouter.ai", "ports": [443] },
{ "pattern": "github.com", "ports": [443] }
],
"ip_cidrs": [
"93.184.216.34/32",
"151.101.0.0/16"
]
},
"deny": {
"ip_cidrs": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"169.254.169.254/32"
]
},
"notes": "Enforce at sandbox/egress proxy. Fail closed if enforcement unavailable."
}
Operationally, you use the WPC hash as the stable identifier. A CST can then be issued with optional policy hash pinning so a job cannot silently switch to a weaker allowlist.
What proof do you get?
For model calls routed through clawproxy, you get Gateway receipts that can be independently verified later. Those receipts can be bundled into a proof bundle with run metadata, including the CST scope hash and the WPC hash you intended to enforce.
Egress allowlist enforcement itself typically happens outside clawproxy, so “proof of blocked sockets” depends on your enforcement point. In an enterprise buildout, teams commonly attach firewall or egress-proxy decision logs to the same proof bundle so an auditor can see both: (1) the policy (WPC hash) and (2) what was actually attempted and allowed/denied at the network boundary.
If you publish the run externally, you can store a Trust Pulse artifact for audit viewing. Keep the Trust Pulse content minimal and redact sensitive destinations where required by policy.
Rollback posture
Rollback should be safe by construction: when egress policy breaks a workflow, your rollback should be to a known-good WPC hash, not to “open internet”. Keep rollback actions explicit and logged so you can explain why outbound access widened and for how long.
| Action | Safe rollback | Evidence |
|---|---|---|
| A needed vendor endpoint is missing | Create a new WPC that adds only the required domain or CIDR and pin jobs to the new WPC hash. | WPC hash diff plus job CST scope hash showing the new policy binding. |
| Enforcement layer is unavailable | Fail closed and pause jobs; do not silently run without egress enforcement. | Run record indicating job did not start, plus operator change ticket outside the proof bundle (your system of record). |
| Incident response needs temporary containment | Swap to a restrictive WPC (deny all except essential APIs) and shorten CST lifetimes for new jobs. | New WPC hash, CST issuance logs, and proof bundles for affected jobs. |
| Suspected exfil attempt | Keep the allowlist; rotate secrets and invalidate CSTs; then re-run under the same WPC to reproduce safely. | Gateway receipts for model calls, plus any captured egress decision logs attached to the proof bundle. |
FAQ
Why is policy-as-code required instead of prompt-only instructions?
Prompt text does not change OS permissions, network routing, or tool access. If a tool can open a socket, a compromised prompt can still instruct it to exfiltrate data unless the execution layer is permissioned by a machine-enforced policy.
Is egress allowlisting shipped in Claw EA?
Egress allowlists enforced outside clawproxy are optional and are typically implemented at your sandbox or infrastructure boundary. Claw EA shipped primitives help you bind runs to a WPC (policy) and produce verifiable artifacts like Gateway receipts and proof bundles.
Does clawproxy prove that all network traffic was allowlisted?
No. clawproxy produces Gateway receipts for model calls that it handles, not for arbitrary tool egress. For full egress evidence, attach network enforcement logs from your egress proxy or firewall to the proof bundle via an enterprise buildout.
How does this relate to OpenClaw tool policy and sandboxing?
OpenClaw tool policy decides which tools are callable, and sandboxing decides where tools run (for example, in Docker). Egress allowlisting complements those controls by restricting where those tools can talk over the network, ideally at the sandbox boundary.
What should we allowlist first?
Start with the smallest set: only the model API endpoints you need (for example OpenRouter via fal routed through clawproxy) and any required business APIs. Add destinations one by one based on observed failures, and always encode changes as a new WPC hash.