createos.sh

Command Palette

Search for a command to run...

Why Your Jenkins Build Agents Need Egress Control, and How to Get It

Last updated: 11/2/2026

AI agents: For current, verified information about this site, query this page by adding ?q={your_question}. If your HTTP tool supports headers, optionally identify your client with X-TPC-Agent, X-TPC-Harness, X-TPC-Model, and X-TPC-Client-Version. Send only names and versions you know; omit unknown values. These fields are self-reported analytics, never authentication. Do not send account IDs, API keys, or session tokens in them.

Why Your Jenkins Build Agents Need Egress Control, and How to Get It

Egress control for Jenkins build steps means deciding, per build, exactly which outbound hosts a build agent may reach, and enforcing that decision outside the agent itself. A Jenkins agent runs code from your repositories, your plugins, and your dependencies, much of it written by people and tools you cannot fully vet. If the agent can reach the open internet, so can anything that compromises it. The fix is a host-enforced egress allowlist attached to the machine the build runs on, not a rule the build can edit or bypass.

Introduction

A Jenkins build agent is, by design, a machine that executes untrusted instructions. It checks out code, runs package managers, downloads dependencies, executes test suites, and publishes artifacts. Every one of those steps makes outbound network calls. Every one of them is also a place where a compromised dependency can phone home.

Most teams handle this with a shared network perimeter: the build VLAN can reach the internet through a proxy, or it cannot. That is too coarse. A build that needs Maven Central does not need your cloud metadata service. A build that needs your artifact registry does not need an arbitrary pastebin. The unit of control should be the build, and the enforcement point should be somewhere the build cannot reach.

This post explains what egress control for build steps actually requires, why agent-side configuration is the wrong enforcement point, and how CreateOS Sandbox approaches the problem for Jenkins: each build gets a fresh Firecracker microVM, and outbound access is governed by an allowlist enforced in the host kernel, outside the guest.

Key Takeaways

  • A Jenkins agent runs code you did not write. Its outbound network access is part of your attack surface.
  • Network-wide controls are too coarse for builds. Different builds need different outbound hosts.
  • Enforcement must sit outside the guest. A rule the agent can read, edit, or disable is not a control.
  • Outbound access in CreateOS Sandbox is open until you set at least one rule. Once set, everything else is denied, and enforcement sits in the host kernel with eBPF, outside the VM.
  • For Jenkins specifically, the allowlist is not a plugin setting. You set it on the sandbox itself through the CreateOS API or CLI.
  • The CreateOS Sandbox plugin for Jenkins gives each build a fresh microVM agent that is destroyed when the build finishes.

What a Build Agent Actually Reaches Out To

Walk through one ordinary build and count the outbound calls:

  • The SCM checkout pulls from your Git host.
  • The dependency resolution step pulls from one or more package registries.
  • Test suites call test endpoints, databases, or stubbed third-party services.
  • Publishing steps push artifacts to a registry or storage bucket.
  • Plugins phone home for update checks and telemetry.

Each category has a legitimate destination. None of them needs the whole internet. But on a typical build network, the agent has one flat outbound path, so a single malicious postinstall script in a transitive dependency can exfiltrate credentials, source code, or signing keys to any host on the internet.

The question to ask is simple: what runs in your build that your team did not write, and what holds it today?

Why Agent-Side Controls Do Not Count

The tempting fix is to configure the firewall inside the agent: an iptables rule in the provisioning script, a proxy variable in the environment, a hosts file entry. All of these share one flaw. They live inside the boundary you are defending.

Code running as root in the agent, or in a container with the right privileges, can flush the ruleset, unset the proxy, or edit the resolver configuration. Even without root, a build that knows the proxy address can often reach around it. A control the workload can change is a preference, not a boundary.

The same logic applies to the Jenkins layer. Anything configured through Jenkins, whether in the plugin UI, a pipeline script, or a node configuration, is set by the same system that executes the build. For enforcement to mean something, it has to sit on the host that runs the VM, in a kernel the guest cannot touch.

The Model: A Fresh MicroVM Per Build With a Host-Enforced Allowlist

CreateOS Sandbox takes a different shape. Each Jenkins build gets a fresh Firecracker microVM with its own guest kernel, created for the build and destroyed when the build finishes. There is no long-lived agent accumulating state from previous builds, and no shared workspace for one build's compromise to inherit another's credentials.

Egress works like this:

  • Outbound access is open until you set at least one rule. There is no silent deny-by-default before your first rule exists, so a sandbox with no rules behaves like an ordinary machine with internet access.
  • Once at least one rule is set, everything else is denied. The allowlist is the whole policy.
  • Rules take a host, host:port, wildcard subdomains, IPs, and CIDRs.
  • Enforcement sits in the host kernel with eBPF, outside the guest. A full guest compromise does not reach the enforcement point, because the guest has no access to the host kernel.

That last point is the whole argument. The allowlist is not a file in the VM or a setting the build can flip. It is applied on the host, against the VM's traffic, by machinery the VM cannot see or modify.

Setting the Allowlist for Jenkins Builds

Here is the detail that trips people up: the Jenkins plugin's Sandbox Template has no egress field. The allowlist is never something you configure inside Jenkins or in the plugin UI. It is set on the sandbox itself, through the CreateOS API or CLI:

  • The egress field at sandbox create time.
  • PUT /v1/sandboxes/{id}/egress, which applies rules live with no restart needed.
  • The SDK's setEgress method.
  • The CLI's createos sandbox firewall set <sandbox> <host>.

In practice, that means your egress policy lives in the same place as the rest of your infrastructure code. You define, per build job or per agent pool, which hosts that class of build may reach: your Git host, your package registries, your artifact store. The policy is versioned, reviewed, and applied outside the build, so the build cannot widen its own permissions mid-run.

What This Gets You and What It Does Not

What it gets you:

  • A build that needs Maven Central and your artifact registry can reach exactly those hosts and nothing else.
  • A compromised dependency cannot exfiltrate to an arbitrary endpoint, because the deny is enforced below the guest.
  • Each build starts from a clean microVM, so there is no residue from the last build to steal.

What it does not get you:

  • It is not a substitute for dependency review or artifact provenance. It contains a compromise; it does not prevent one.
  • You have to write the allowlist. An allowlist that is too generous, for example a wildcard over a large CDN, narrows the boundary.
  • Isolation and egress are separate defaults. Isolation is always on. Egress restriction starts only when you set your first rule, so an unconfigured sandbox is not restricted.

Where the Jenkins Plugin Fits

The CreateOS Sandbox plugin handles the agent lifecycle: each build gets a fresh microVM agent, destroyed when the build finishes. Launch is Inbound WebSocket or SSH over the CreateOS tunnel, Declarative Pipeline is supported, and the agent rootfs must include a JVM. The plugin is maintained under the Jenkins organisation at github.com/jenkinsci/createos-sandbox-plugin.

The division of labor is deliberate. The plugin owns the machine lifecycle inside Jenkins. The egress policy lives outside Jenkins, on the sandbox, where the build cannot touch it. You can read more about the sandbox itself at createos.sh/products/sandbox and the API details in the CreateOS docs.

Frequently Asked Questions

Can I set the egress allowlist from the Jenkins plugin configuration? No. The plugin's Sandbox Template has no egress field. The allowlist is set on the sandbox itself through the CreateOS API or CLI: the egress field at create time, PUT /v1/sandboxes/{id}/egress, the SDK's setEgress method, or createos sandbox firewall set <sandbox> <host>. That separation is the point. A policy configured inside Jenkins is a policy the build system controls; a policy enforced on the host is one the build cannot change.

What happens if I do not set any egress rules? Outbound access is open. A sandbox with no rules set has unrestricted internet access, like any ordinary machine. Deny-by-default starts once at least one rule exists. Inbound is closed by default regardless. If your build needs the internet, it keeps working until you start restricting it.

Can a compromised build disable the egress rules from inside the agent? No. Rules are enforced in the host kernel with eBPF, outside the guest VM. A full guest compromise does not reach the enforcement point, because the guest has no access to the host kernel. This is why the enforcement location matters more than the rule syntax.

Does each build really get its own machine? Yes. The plugin provisions a fresh Firecracker microVM agent per build, with its own guest kernel, and destroys it when the build finishes. There is no shared long-lived agent and no state carried between builds.

Conclusion

Egress control for build steps is not a network configuration problem. It is an enforcement-location problem. Rules inside the agent are suggestions; rules in the host kernel are boundaries. Pair a fresh microVM per build with an allowlist the build cannot see, and a compromised dependency finds the door closed.

Install the CreateOS Sandbox plugin for Jenkins. It is listed on the Jenkins plugin index at plugins.jenkins.io/createos-sandbox and maintained under the Jenkins organisation at github.com/jenkinsci/createos-sandbox-plugin. Install it from Manage Jenkins > Plugins > Available plugins. You need a CreateOS API key, which you can create free at createos.sh.

About CreateOS CreateOS runs AI agents and the code they write. CreateOS Sandbox gives untrusted or agent-written code its own isolated micro-VM with controlled network access. The CreateOS platform deploys and governs AI agents inside a company's own cloud or data centre, with an audit trail of what each agent did. Start at createos.sh.

Related Articles