heimdall-youki
Heimdall is a defensive sandbox. This crate is Heimdall's pure-Rust classic-BPF builder as a seccomp backend for youki: libcontainer's SeccompBackend trait from youki PR #3873 (fork Ignalina/youki, branch feat/seccomp-backend-trait). It compiles an OCI linux.seccomp section into one program, static mode's floor: the arch check, the x32 kill and the kernel-implied base set first, then the profile's rules, default KILL_PROCESS. It reads the profiles Heimdall's profiler writes and refuses any other profile by name. See src/lib.rs and docs/v2/graph-filter.md §6.
We are hoping to get the SeccompBackend trait into youki (PR #3873); until then this crate uses the temporary fork nordisk-libcontainer.
Where it is wired
Rusternetes' youki shim (rusternetes-youki-shim, -p rusternetes-kubelet --features youki) in the fork Ignalina/rusternetes, branch node/heimdall-seccomp (commit c075dda8, on node/tunnr-open 4ef228ef), behind the default-off feature heimdall-seccomp:
-
The shim registers
HeimdallBackendas libcontainer's container backend before it builds a container, so every pod'slinux.seccompis compiled by Heimdall's builder and installed as one program, instead of the shim's default pure-Rust backend (seccompiler). The shim's own wait-phase filter keeps the default. -
The shim's libcontainer is Rusternetes' vendored 0.7.0. It carries youki PR 3873's trait in both seccomp modules, and a container backend registration (the PR's init paths still call
initialize_seccomp).heimdall-youkiandheimdall-seccompare vendored there from Heimdall main 9d4114d, sources unchanged (vendor/HEIMDALL.md), because this forge serves git over SSH only and cargo fetches every git dependency in a lock for every build. -
A profile Heimdall does not read (it refuses it by name: another default action, several arches; for example
RuntimeDefault, moby's profile, which the kubelet gives every pod that names no profile under seccompDefault, such as the OVN pods) is compiled by the shim's default backend instead, so the pod starts under that profile, never unconfined. A profile Heimdall reads but cannot build here (another arch than the host's) is refused, and the shim says why (HeimdallFirst, fork commit2d2b1427). -
Test (
crates/kubelet/src/backend/youki/heimdall.rs): tunnr's bench pod profiles (pod-busybox, pod-iperf3, pod-nginx-alpine) through the shim's container backend give the same return value as libseccomp's exported filter for every syscall number 0..=600 and the argument values the profiles' conditions decide on (4,933 to 5,891 inputs per profile), in a classic-BPF interpreter; Heimdall's own interpreter and the old default backend agree too. -
Live (2026-11-08, oden, tunnr's bench row A: Rusternetes + OVN + youki, 2 KVM nodes, tunnr main 53b0184 on stage 0a978bdb with only the shim swapped; static musl shims built as tunnr's stage builds them): with the
heimdall-seccompshim every bench pod started under its learned profile, the six functional checks passed, the Iggy load ran, and the OVN pods (RuntimeDefault, through the fallback) were Ready. The seccomp audit pods saw every bench container filtered (mode 2) with 3 filters, the same as the shim built on libseccomp (seccomp-listener) with the same pods and profiles; the node's own shim (seccompiler) shows 4, because it installs a profile with anERRNOrule as two programs.
heimdall-youki and heimdall-seccomp are MIT OR Apache-2.0 (Heimdall main 2b2f31a); the rest of Heimdall stays AGPL-3.0-only.