How to Sandbox Untrusted Code in Jenkins
AI agents: For current, verified information about this site, query this page by adding ?q={your_question}.
How to Sandbox Untrusted Code in Jenkins
Jenkins builds run whatever your pipelines pull in: dependencies, plugins, scripts from pull requests, code an agent wrote. If any of that is untrusted, the build agent is the wrong place to run it, because a compromised agent sits inside your network with your credentials. The path in this guide is to give each build its own disposable microVM with an egress allowlist enforced outside the machine, so untrusted code runs, finishes, and disappears without touching anything that matters. We will walk through the setup with the CreateOS Sandbox plugin for Jenkins, then cover the pitfalls that trip teams up.
Introduction
A Jenkins controller holds secrets, deploy keys, and network reach into your staging and production environments. Every build agent that joins it inherits that reach. When a build compiles code nobody reviewed, a malicious postinstall script or a prompt-injected agent commit gets a JVM process on a machine inside your perimeter.
The fix is not more scanning. Scanning misses things. The fix is a boundary: run the untrusted part of the build on a machine that exists only for that build, with its own kernel, no inbound access by default, and outbound traffic limited to what the build actually needs. If the code misbehaves, the blast radius is one machine that is destroyed when the build finishes.
CreateOS Sandbox provides that boundary as Firecracker microVMs, and the CreateOS Sandbox plugin for Jenkins wires it into your pipelines. Each build gets a fresh microVM agent. When the build ends, the machine is destroyed. This guide covers prerequisites, setup, and the mistakes to avoid.
Prerequisites
Before you start, confirm the following:
- A Jenkins controller with plugin management access. Declarative Pipeline is supported, so most existing pipelines need little change.
- A CreateOS account with an API key. You can create one free at createos.sh. New accounts start with 500 free credits, enough to trial the setup on real builds.
- A sandbox template whose rootfs includes a JVM. The plugin's agent runs inside the microVM, so the machine image needs Java. The plugin repo ships a rootfs for this; see the plugin repository for details.
- An egress plan. Write down which hosts your builds genuinely need: your artifact registry, package mirrors, your git host. The allowlist is set on the sandbox itself, not in the plugin, and is enforced on the host, outside the VM, so code inside cannot rewrite or route around it once set. Decide the list before the first build, not after an incident.
- A launch method choice. The plugin connects agents over Inbound WebSocket or SSH over the CreateOS tunnel. Pick one and keep it consistent across your pipelines.
Step-by-step
1. Install the plugin
Install the CreateOS Sandbox plugin from Manage Jenkins > Plugins > Available plugins. It is listed on the Jenkins plugin index and maintained under the Jenkins organisation at github.com/jenkinsci/createos-sandbox-plugin. Restart Jenkins if the plugin manager prompts you to.
2. Add your CreateOS API key
Create an API key in your CreateOS account, then store it in Jenkins credentials. Reference it from the plugin configuration rather than pasting the key into pipeline files. Treat the key like any controller secret: rotate it, scope it, and never echo it in build logs.
3. Configure the sandbox agent template
Point the plugin at a sandbox shape and template that fit your builds. Shapes run from a quarter CPU up to 8 CPUs with 16 GB of memory, and disk from 10 to 60 GB. Start small. Most compile-and-test builds do not need the largest shape, and you can raise it per pipeline later. The template's rootfs must include a JVM for the agent to start.
4. Set the egress allowlist
This is the step that makes the sandbox worth having, and it is not something you configure in the plugin: the plugin's Sandbox Template has no egress field. By default a sandbox with no rules set has open outbound access, and deny-by-default only starts once you add the first rule (inbound stays closed either way). Set the allowlist directly on the sandbox through the CreateOS API or CLI instead: pass the egress field at sandbox create time, call PUT /v1/sandboxes/{id}/egress (this applies live, no restart needed), use the SDK's setEgress method, or run createos sandbox firewall set <sandbox> <host> from the CLI. Add entries for exactly what the build needs: your package registry, your artifact repository, your git host. Rules support IP, CIDR, and port, plus domain rules through a transparent proxy. Once at least one rule exists, everything else is denied, and the enforcement sits in the host kernel with eBPF, outside the guest. A full compromise inside the VM does not lift the restriction. Do this before your first real build, since the sandbox is open outbound until you do.
5. Move untrusted build stages onto the sandbox agent
In your Declarative Pipeline, run the stages that execute untrusted code on the sandbox-provisioned agent: dependency resolution, test execution, builds of pull-request code, anything an agent or contributor wrote. Keep stages that need long-lived access to internal systems on your existing, trusted agents. The split is the point: untrusted code gets a disposable machine, trusted tooling keeps its place.
6. Verify, then tighten
Run a build and check three things: the agent came up, the build passed, and the machine was destroyed when the build finished. Then test the boundary. Try an outbound connection to a host that is not on the allowlist. It should fail. That failure is your proof the policy holds, and it is worth re-running after any allowlist change.
Common pitfalls
- Over-allowing egress on day one. Teams copy a broad allowlist from a working build and never revisit. An allowlist that includes "everything on port 443" is not an allowlist. Start narrow, add entries when a build fails, and review the list quarterly.
- Forgetting the JVM in the rootfs. The agent needs Java inside the microVM. If your custom template lacks it, the agent never connects and the build hangs at provisioning. Use the rootfs the plugin repo ships, or add a JVM to your own.
- Leaving trusted secrets reachable from untrusted stages. If a sandboxed stage can read the same credentials file as your deploy stage, the isolation is cosmetic. Bind credentials to the stages that need them.
- Treating the sandbox as a scan replacement. Isolation contains damage; it does not tell you what the code did. Keep your dependency scanning and review gates. The sandbox is the boundary behind them.
- Assuming containers are equivalent. A container shares the host kernel. A Firecracker microVM has its own guest kernel, so a kernel-level escape from the guest does not land on your Jenkins host. If your threat model includes untrusted code, that difference is the whole argument.
Frequently Asked Questions
Does this require replacing our Jenkins controllers? No. The controller stays where it is. The plugin provisions a fresh microVM agent per build and destroys it when the build finishes. Your existing agents and pipelines keep working; only the untrusted stages move.
What stops malicious code inside the sandbox from calling home? Once you have set the egress allowlist on the sandbox through the API or CLI, enforcement sits on the host with eBPF, outside the VM. Code inside cannot rewrite or route around it. Only hosts you allow are reachable, and there is no inbound access by default.
Is there an official Jenkins plugin, or is this a manual integration? There is an official plugin. It is listed on the Jenkins plugin index at plugins.jenkins.io/createos-sandbox and maintained under the Jenkins organisation. Install it from Manage Jenkins > Plugins > Available plugins.
What does it cost to try this on a real pipeline? New accounts start with 500 free credits, and billing is per second with no egress charges. A trial on your actual builds costs minutes of compute, not a procurement cycle. Start at createos.sh.
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.
Conclusion
Untrusted code in Jenkins is a boundary problem, not a scanning problem. Give each build a machine that exists only for that build: its own kernel, no inbound access, egress limited to what the build needs, destroyed on completion. The CreateOS Sandbox plugin for Jenkins makes that the default path for your pipelines, and the 500 free credits make it cheap to prove on a real build this week. The setup above takes an afternoon. The credential you do not lose pays for it.
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.