How ZViz works
ZViz wraps an OCI workload in five enforcement layers, applied in a fixed order, then routes every syscall through a selective-denial policy. The ordering is load-bearing — each layer assumes the previous one is already in place.
The five layers, in order
Namespaces
A fresh user, pid, mount, ipc, and uts namespace. The container gets its own view of processes, mounts, and IPC. The user namespace lets an unprivileged process act as root inside the container while remaining unprivileged outside it.
Capabilities
All 41 Linux capabilities are dropped before the workload runs. No CAP_SYS_ADMIN, no CAP_NET_RAW, nothing. Capabilities are cleared before seccomp loads so nothing can re-add them.
Landlock LSM
An unprivileged, kernel-enforced filesystem access-control ruleset. Applied before seccomp so Landlock's own setup syscalls are not self-blocked. Requires Linux 5.13+.
Seccomp-BPF
The selective-denial filter: 132 syscalls are allowed to reach the host kernel, 24 dangerous ones return EPERM at the BPF layer, and socket() is argument-filtered inline so specific families can be permitted or refused.
cgroups v2
Memory, PID, and CPU limits are applied last, once the process boundary exists. A fork bomb inside the container hits the PID cap instead of the host.
The path a syscall takes
Once the layers are in place, every syscall the workload makes is classified by the seccomp filter into one of three outcomes:
workload syscall │ ▼ ┌─────────────────┐ │ seccomp-BPF │ │ classifier │ └───────┬─────────┘ ┌───────────┼───────────────┐ ▼ ▼ ▼ ALLOW (132) FILTER (1) DENY (24) │ │ │ ▼ ▼ ▼ host kernel socket(): return EPERM (native) inspect args never reaches per family kernel
Allowed syscalls run on the host kernel with no emulation layer. Denied syscalls never reach the kernel —
the workload simply sees EPERM. This is the difference between ZViz and a
userspace kernel: ZViz denies, it does not emulate.
Where the trust boundary sits
ZViz assumes the host kernel is trusted. Denied syscalls can never exploit it because they never run. For the 132 allowed syscalls, the host-kernel code path is shared — so a kernel CVE in an allowed path is a risk shared with the host. The full model is on the threat-model page.