ZViz vs runc (plain Docker)
runc is the reference OCI runtime that powers Docker, containerd, and most production container platforms. Its threat model assumes the workload is friendly. ZViz assumes the opposite.
Compared with: runc
| Aspect | ZViz | runc |
|---|---|---|
| Isolation mechanism | Namespaces + cgroups + capability drop (all 41) + Landlock + 124-instruction seccomp-BPF | Namespaces + cgroups + default seccomp profile + (optional) AppArmor/SELinux |
| Default capability set | 0 capabilities (all 41 dropped) | 14 default Docker capabilities (CAP_CHOWN, CAP_NET_RAW, …) |
| Default seccomp profile size | 24 syscalls denied, 1 argument-filtered, 132 allowed | ~44 syscalls denied (Docker default), rest allowed |
| Kernel attack surface | Roughly 132 reachable syscalls | Roughly 300 reachable syscalls |
| Landlock LSM enabled | Yes (default) | No (operator must wire it up) |
| Cold start | ~8 ms | ~50 ms |
| Memory per container | ~2 MB | ~0 (negligible runtime overhead) |
| I/O throughput | ~95% of native | 100% of native |
| Daemon required | No | Typically yes (Docker/containerd) |
| ptrace() inside container | BLOCKED | BLOCKED by default Docker profile (allowed if --cap-add SYS_PTRACE) |
| mount() inside container | BLOCKED | BLOCKED by default Docker profile |
| bpf() inside container | BLOCKED | BLOCKED by default Docker profile |
| unshare() inside container | BLOCKED | ALLOWED by default Docker profile |
| keyctl() | BLOCKED | ALLOWED by default Docker profile |
| io_uring_setup() | BLOCKED | ALLOWED by default Docker profile |
| Default network egress | DENY (explicit allowlist) | ALLOW (full egress) |
| Threat model assumption | Workload is hostile | Workload is friendly |
| Suited for AI-agent code execution | Yes (designed for it) | No (default profile too permissive) |
| Suited for general-purpose Docker workloads | Mostly; not for DinD, Bazel, strace | Yes (it is the reference) |
| Implementation language | Zig | Go |
| License | Apache 2.0 | Apache 2.0 |
runc figures are taken from the upstream Docker default seccomp profile (moby/profiles/seccomp) and the runc threat-model documentation. Cold-start numbers vary substantially with image size, cgroup driver, and storage backend.
Pick runc when
You are running first-party workloads, code you wrote or audited, internal services, and want the broad ecosystem and tooling. The default profile is fine for trusted code.
Pick ZViz when
You are running code you did not write — AI-agent output, third-party plugins, CI of opaque dependency trees, multi-tenant snippets. A default profile that drops all capabilities and denies dangerous syscalls outright is the right starting position.
For a fuller treatment of these trade-offs, see the field note Isolation models, ranked by what they actually break.