Sysbox Increases Kernel Attack Surface By 267 Percent
Many platform teams running builds in Kubernetes eventually hit the same wall: your build needs Docker, Docker needs privileges, and privileged: true fails your compliance audit. So you go looking for a way, and eventually you find Sysbox: a container runtime that runs Docker inside a container without --privileged. It works. Then somebody writes "we removed privileged containers" in the compliance doc, and the story ends.
But we wanted to know what kind of tradeoffs introducing user namespaces to your CI environment creates. So we decided to measure the security implications by probing the shared kernel.
A probe measures whether a container can invoke a privileged kernel operation: create a network namespace, mount an overlay filesystem, open a raw socket, add an nftables chain, load a BPF program, etc. We ran 40 probes, spanning namespace creation, mounts, network device creation, netfilter, sockets, capability-gated syscalls, BPF, perf, and keyrings.
An operation counts as reached when the kernel lets the call into the subsystem rather than rejecting it at the door. A return of EPERM or EACCES means the door was shut. Anything else, including a failure like EINVAL, means the kernel accepted the call, parsed its arguments, and ran real code inside that subsystem before deciding what to do with it. Code that runs is code an attacker can try to break, which is why reachability is the thing worth measuring rather than success.
How We Measured Kernel Attack Surface Across Runtimes
We reused userns-probe from our earlier user namespace research, which already implements the 40 probes described above. That tool was built to compare an unprivileged process against a user namespace it creates itself, which answers what creating a user namespace buys an attacker on a given host. Comparing runtimes needs a different question, so we added an ambient mode that runs each probe exactly once in whatever context the runtime provided, changing nothing. This matters because the runtime, not the probe, decides the starting position: a Sysbox container is already root inside a user namespace, while a stock container is root in the initial namespace behind a seccomp filter that forbids creating one.
Everything else was held constant. All measurements ran on a single EKS node running Ubuntu 24.04 and kernel 6.17, using the same statically compiled probe and the same image, under Docker with runc, Docker with sysbox-runc 0.7.0, and a privileged container. Running them on one machine means kernel version, distribution, and LSM policy cannot account for any difference between the columns.
The Result: Docker vs. Sysbox vs. Privileged Containers
.png)
Nine operations became thirty-three on an identical kernel, which means 24 are newly reachable operations and a 267% increase in reachable kernel attack surface. Sysbox gives every container a user namespace by design, so it inherits that additional threat surface.
The reason a vanilla container scores 9 is Docker's own default seccomp profile denies user namespace creation to any container process without CAP_SYS_ADMIN. Sysbox's entire operating model is to hand every container the thing that the default Docker seccomp profile denies.
What opens up is the bulk of the kernel's namespace and mount code. Under Sysbox a container can create all seven namespace types, perform nine of the ten mount operations we tested, create veth, bridge, and dummy network devices, and nest user namespaces at least 32 levels deep, which makes every namespace-gated code path reachable recursively. It can also reach nftables. In our earlier survey of kernel CVEs enabled by user namespaces, nearly half of them were in nftables, making it the most vulnerability-dense subsystem we measured. And it’s fully accessible to Sysbox.
Sysbox does block real things, and it deserves credit for them. Compared to a privileged container it denies BPF program loading, BPF map creation, perf_event_open, both mknod variants, setdomainname, and hugetlbfs mounts. That is meaningful mitigation on genuine escalation paths. It is also seven operations out of forty, which puts Sysbox considerably closer to --privileged than to an ordinary container.
One caveat on reading these numbers. Reachability is only comparable between runtimes sharing a kernel, and all three rows above share the host's. Run the same probe inside an Edera zone and it reports 40 of 40, because the workload is root in a kernel that’s isolated to that workload alone. The count is high but the blast radius is a disposable kernel with no other tenants in it, which is a different question from how much of your node's kernel a build job has access to.
Why Kernel Attack Surface Matters Most in CI/CD Pipelines
CI is the one place where running untrusted code is the entire product. A build job executes whatever is in the repository: Makefiles, test suites, and the postinstall scripts of every transitive dependency. Arbitrary code execution is not a failure mode, it is the main feature of CI.
That code runs on the most valuable machines you own. A build node holds registry push credentials, a cloud IAM role, signing keys, and a checkout of your source. It is the seam between source code and production, which is precisely why supply chain attackers aim at it rather than at your application servers.
Those two facts together are what make kernel bugs different from application bugs in CI. An application vulnerability gets an attacker code execution inside a container. A kernel vulnerability gets them the node: every other pod, every secret mounted, the kubelet's credentials, and the instance's IAM role. There is no graceful degradation, the boundary either held or it did not.
You do not get to choose whether the kernel has bugs, and draining and rebooting a build fleet is disruptive enough that most teams run weeks behind CVEs. The one variable you actually control is how much of the kernel a build job can reach in the first place. That is the number we measured, and under Sysbox it is three and a half times larger than it needs to be.
Sysbox's own documentation makes the point more bluntly than we would. Its CVE table marks CVE-2022-0185, a user namespace escape, as affecting Sysbox containers:
“This vulnerability can negate the extra isolation of containers deployed with Sysbox as they always use the Linux user-namespace.”
The demo: Running privileged: true Safely with Edera
The reason privileged: true is unacceptable is that the container shares a kernel with the host and every other tenant. A dedicated kernel per workload means that privileged loses its risk to the host and other tenants. No Sysbox, no Kaniko, no rootless daemon, no second runtime on the node:
apiVersion: v1
kind: Pod
metadata:
name: dind
spec:
runtimeClassName: edera
volumes:
- name: docker-storage
emptyDir: {}
containers:
- name: dind
image: docker:dind
securityContext:
privileged: true
args: ["--storage-driver=vfs"]
env:
- name: DOCKER_TLS_CERTDIR
value: ""
volumeMounts:
- name: docker-storage
mountPath: /var/lib/docker
It builds images. And the whole argument fits in one command. Inside a Sysbox container:
$ uname -r
6.17.0-1019-aws
That is the host's kernel, shared with every other tenant on the node. Inside an Edera zone:
$ uname -r
6.18.39-edera-zoneThe host is running 6.18.38-edera-host. Edera gives every workload its own dedicated kernel.
What To Do on Monday: Reducing CI Kernel Exposure
If you are already running Sysbox, you are not in an emergency. You are in a better position than a fleet of privileged containers. But three things are worth doing this week.
Stop counting Sysbox as a security boundary in your threat model
It is a compatibility layer with security benefits, enforced entirely by the (hopefully patched) kernel your untrusted workload is attacking. The gap between "we removed privileged" and "the build cannot reach the host" is where you should be focusing, particularly for CI and untrusted code.
Check whether your unprivileged pods actually have a seccomp profile
Our Kubernetes pod with no securityContext at all reached 13 of 40 operations. The same pod with seccompProfile: RuntimeDefault reached 9. Seccomp is free, and a lot of cluster operators are leaving it on the table.
Measure your own fleet
The probe is open source. Run it in your build containers and see what your CI jobs can actually reach. The number will be higher than you expect.
And if the answer you actually want is "the build job runs privileged: true and I stop caring," come talk to us at Edera or try it out for yourself with EderaON – our one node access program.
Reproduce Our Sysbox Kernel Attack Surface Benchmark
Everything above is measurable. The probe tool, the ambient mode, the pod manifests, and the raw JSON output for every column are in our GitHub edera-dev/namespace-research.
Run it against your own runtime. If we are wrong, the tool will say so.
FAQ
Does Sysbox provide real kernel isolation for CI/CD build containers?
No. Sysbox removes the need for --privileged by granting containers a user namespace, but the underlying kernel is still shared with the host and every other workload on the node. Our testing found Sysbox reaches 33 of 40 tested kernel operations, compared to 9 for a default Docker container, so it is closer to --privileged than to an ordinary container in terms of what a compromised build job can reach.
How does Edera make privileged: true safe for CI/CD pipelines?
Edera runs each workload in its own zone with a dedicated Linux kernel enforced by a Type-1 hypervisor. A container running privileged: true inside an Edera zone still shares nothing with the host, so escalation attempts that would normally reach the node have no host kernel to reach.
Is Sysbox vulnerable to CVE-2022-0185?
Yes. Sysbox's own documentation lists CVE-2022-0185, a user namespace escape, as affecting Sysbox containers because Sysbox containers always use the Linux user namespace.
What is kernel attack surface reachability testing?
Reachability testing measures whether a container can invoke a privileged kernel operation rather than being rejected outright. A probe that returns anything other than EPERM or EACCES means the kernel accepted the call and ran code inside that subsystem, which is the code an attacker could try to exploit.

-3.avif)