Kubernetes pods are non-isolated by default, so an agent sandbox pod can reach anything its network allows. To limit it, apply a NetworkPolicy that selects the pod and denies egress, add narrow allow rules, and make sure your network plugin enforces policies. Pair that with a stronger runtime class for untrusted code.
What the documentation says
The Kubernetes documentation states that pods are non-isolated for egress and ingress by default. A pod becomes isolated for egress only when a NetworkPolicy selects it and lists Egress in policyTypes. Once isolated, only connections allowed by a policy are permitted, and multiple policies combine additively, so order does not matter. A connection needs both the source pod's egress policy and the destination pod's ingress policy to allow it.
A critical caveat: policies are enforced by the network plugin. Creating a NetworkPolicy without a controller that implements it has no effect. Confirm enforcement with a test, not an assumption.
Starting policy
A default deny egress policy for a namespace uses an empty pod selector and lists Egress as the policy type with no rules:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: agent-sandboxes
spec:
podSelector: {}
policyTypes:
- Egress
This blocks all outbound traffic from every pod in that namespace, including DNS lookups. Add a rule that allows your cluster DNS on port 53, and further rules for the specific destinations the task needs.
Plan for the limits
| Need | Core NetworkPolicy | Notes |
|---|---|---|
| Allow by pod, namespace, IP block, port | Yes | Layer 3 and 4 matching |
| Allow by domain name | Check your plugin | Many teams use an egress proxy or plugin features, so verify what yours supports |
| Inspect HTTP methods or paths | Not in the core API | Use a proxy you control |
| Block traffic to the node | Not by core policy | Node traffic is treated differently, so test it |
Where you cannot allow by domain, a common design routes sandbox traffic through an egress proxy that applies a domain list, and the policy only allows traffic to that proxy.
Add a stronger runtime for untrusted code
RuntimeClass lets a pod choose a runtime configuration, such as one that uses hardware virtualization, which the documentation describes as a way to balance performance and security. If the class does not exist or the runtime cannot run it, the pod fails, which is a safe failure for a sandbox. The docs recommend limiting who can create or change RuntimeClass objects to cluster administrators, and note the resource overhead you can declare.
Checklist
- Put agent sandboxes in their own namespace.
- Apply default deny for ingress and egress.
- Allow DNS and one egress path, such as a proxy.
- Set a runtime class that fits the trust level.
- Test: from a sandbox pod, try an outside host, a cluster service, and the node's metadata address.
- Use short-lived pods, one per task.
- Restrict who may edit policies and runtime classes.
Worked example: a namespace for agent sandboxes
An illustrative layout. Names are examples.
- Create a namespace called agent-sandboxes, labeled so policies can select it.
- Apply the default deny egress policy shown above, and a matching default deny ingress policy.
- Add a policy that allows egress to the cluster DNS pods on port 53 for UDP and TCP.
- Add a policy that allows egress from sandbox pods to one egress proxy pod in another namespace, on its listening port.
- Run the proxy with a domain allowlist you manage. The proxy is the only path to the outside.
- Set a RuntimeClass on sandbox pods that selects your stronger isolation runtime.
- Add a ResourceQuota and LimitRange so a runaway task cannot starve the cluster.
- Restrict who can edit these objects with RBAC.
Because policies are additive, each allow rule is an explicit decision. Reading the list of policies in the namespace tells you everything a sandbox pod can reach.
Test matrix
Do not assume enforcement. Run these checks from a sandbox pod and keep the results.
| Test | Expected result |
|---|---|
| Resolve a name through cluster DNS | Succeeds |
| Connect to a public host directly | Fails |
| Connect to the egress proxy | Succeeds |
| Connect through the proxy to an allowed host | Succeeds |
| Connect through the proxy to an unlisted host | Fails |
| Connect to another namespace's service | Fails |
| Connect to the node's metadata address | Fails |
| Read the pod's service account token | Not present, or no permissions |
If a row fails in an unexpected way, check that your network plugin enforces policies at all. The documentation is explicit that without an implementing controller, a policy has no effect.
Pod settings that complement network policy
- Set the pod's service account token mount to off unless the task needs the API.
- Run as a non-root user with a read-only root filesystem.
- Drop capabilities.
- Do not set host networking, host PID, or privileged mode.
- Use a pod security admission level that rejects privileged pods in this namespace.
Lifecycle
Run each task as a Job or a pod created for that task, and delete it afterward. Add a time limit so abandoned pods end. Keep the egress proxy and the policies in version control so changes are reviewed.
When network policy is not enough
If you need rules by domain name and your plugin cannot do it, use the proxy pattern above. If you need to inspect traffic content, the proxy is the place. If you need stronger kernel isolation, the runtime class is the place. Each layer solves a different problem, so use them together.
Where Safeguard fits
Safeguard does not enforce Kubernetes network policy. It can scan container images and dependencies that sandboxes use, via SBOM and dependency scanning.
Try it yourself
Click through it at your own pace, or open it full screen.
Click through it and look at what an image contains, since the pod runs everything in it.
Quick check
Does a NetworkPolicy work on any cluster?
No. Your network plugin must implement it. Without that, the object exists and does nothing.
Why did DNS break after I denied egress?
Default deny also blocks DNS. Add an explicit rule for your cluster DNS service.
Do I need a proxy if my network plugin supports domain rules?
Not necessarily. Domain rules in a plugin may be enough. A proxy adds logging, method limits, and credential injection, so many teams still prefer one.
Sources
Last reviewed: 19 October 2026.