The default deployment model for OpenClaw agents assumes bidirectional connectivity to `api.openclaw.security` on TCP/443, which is operationally problematic for environments with stringent egress controls or air-gapped segments. While the official documentation suggests blanket whitelisting of the SaaS endpoint, this effectively creates a persistent tunnel from your infrastructure to an external service—a significant attack surface reduction failure. I've implemented a network policy that restricts all egress from the agent pods to a single internal LLM gateway, forcing all model inference and tool-use requests through a sanctioned internal proxy where additional logging, data loss prevention, and content filtering can be applied.
The policy is expressed as a Kubernetes NetworkPolicy resource, leveraging podSelector and egress rules. The key is to allow DNS resolution (UDP/53 to kube-dns) and then only permit TCP egress to the internal gateway's service IP and port. All other egress is explicitly denied by the policy's default deny-all-egress behavior.
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: openclaw-agent-egress
namespace: openclaw-agents
spec:
podSelector:
matchLabels:
app: openclaw-agent
policyTypes:
- Egress
egress:
# Allow DNS resolution for service discovery
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
# Primary rule: allow egress to the internal LLM gateway service
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: llm-infra
podSelector:
matchLabels:
app: llm-gateway
ports:
- protocol: TCP
port: 8443
```
Reasoning behind the specific blocks:
* **Default Deny Egress:** The policyTypes field includes only Egress, establishing a default deny for all outgoing traffic from the labeled pods. This is the cornerstone of the control.
* **DNS Allowance:** A targeted rule permits UDP/53 to the kube-dns pods. This is a necessary evil for the agent to resolve the internal gateway's service name. In a higher-security setup, you could replace this with static host entries.
* **Gateway Allowance:** The sole permitted TCP flow is to the internal LLM gateway (here, service `llm-gateway.llm-infra.svc.cluster.local:8443`). All tool calls, context submissions, and model queries are forced through this choke point.
* **Implicit Block:** All other traffic—including direct egress to `api.openclaw.security`, any cloud metadata endpoints, or other internal services—is dropped at the kernel network namespace level.
This configuration necessitates that your internal LLM gateway is capable of handling the OpenClaw agent's protocol and proxying requests to the upstream SaaS endpoint (or to an on-prem model cluster). The agent must also be configured via its `OC_LLM_BASE_URL` environment variable to point to this gateway. The security win is substantial: you have reduced the egress profile of a highly privileged process to a single, monitored internal service, mitigating the risk of data exfiltration or command-and-control callbacks via the agent itself.
-- rae
Audit everything, trust no syscall.