Gunnar

nordisk/heimdall

Heimdall

OpenSSF Best Practices

Heimdall

In Norse myth, Heimdall guards the Bifröst bridge and lets nothing into Asgard unchecked, especially not data.

What it is

Heimdall is a defensive sandbox for inspecting content. All content is untrusted until it is verified. That includes signed content: a digital signature is itself untrusted input until it has been checked, and the check must not be able to attack the checker. So Heimdall parses, verifies and scans in an isolated job:

Pure Rust, static binaries.

Users

Layers

Each job runs inside every layer below; an attacker must break all of them.

LayerWhat it does
KernelThe node runs a kernel trimmed to what its programs use, so less kernel code can be attacked.
Container (youki)Namespaces, read-only root, no network unless allowed, all capabilities dropped, no-new-privs, cgroup v2 limits, image checked at every start.
Seccomp allowlistOnly the system calls the job really uses, with fixed arguments where possible. Anything else kills the job.
LandlockFile access only to the job's input (read) and output (write).
Syscall brokerThe few risky calls (open, socket, connect) are paused and checked by Heimdall, which opens the file or socket itself, so the job cannot race the check.
Wasm host (optional)The parser runs as signed WebAssembly with no file or network access, under fuel, time, memory and stack limits.
Signed resultThe verdict and the output hashes are signed with a per-boot Ed25519 key.

Tuning: how the allowlists and the kernel are fitted

Nothing is guessed. Heimdall measures what a program does and allows only that.

  1. Build the program and the node kernel (Build Thing).
  2. Probe: run the program's full test suite and fuzz corpus on a probe kernel, in learning mode. Heimdall records every system call with its important arguments; the probe kernel records which kernel code ran.
  3. Generate: Heimdall merges the runs into the smallest seccomp profile per program, architecture and libc (a Rust table plus reviewable JSON). The kernel side lists kernel options no program used, explained through the Kconfig dependency graph.
  4. Review: a person checks the diff and commits it. Nothing is merged automatically.
  5. Enforce: production runs the checked-in profile; any call outside it kills the job. Kernel options are removed one at a time, each with a full test rerun.
  6. Drift check: every CI run probes again and fails if a program makes a call its profile does not have, naming the call and the test that made it.

Paths a test never reached are missing from the profile, so they fail closed. The probe therefore runs error paths, failover and fuzzing, not only normal use.

Details: docs/API.md (the job API: the JobRunner trait, v0.1.0, and the interim heimdall-plain runner, an ordinary youki container stated as such), docs/SPEC.md (the specification) and docs/BUILD-THING.md (how Build Thing drives the tuning).

Usage

heimdall run --job wasm --module <guest.wasm> --trust-root <key> --in <dir> --out <dir> [--policy <file>]
heimdall verify-result <out>/result.signed --key <pinned key> --files

See docs/CLI.md, docs/POLICY.md and docs/RUN.md.

Standards and specifications

StandardUsed forStatus
RFC 8032 (Ed25519)Signed results, strict verificationImplemented
FIPS 180-4 (SHA-256)Output hashes, key idsImplemented
BLAKE3Guest module pinsImplemented
WebAssembly Component Model, WITThe guest interface; WASI is not linkedImplemented
DSSE (in-toto envelope)Bundle verification before payload parsingIn progress
RFC 5280 (X.509)Bundle signaturesIn progress
OCI Runtime SpecificationThe youki container (heimdall-plain)Implemented
Linux seccomp-bpfA fixed default profile (heimdall-plain) today; the generated per-program allowlist is plannedImplemented (fixed profile)
seccomp USER_NOTIFThe syscall brokerPlanned
Landlock LSM (ABI 1–4)File and network access rulesPlanned
Linux cgroup v2, user namespaces, no_new_privsResource limits and privilege dropImplemented
NIST SP 800-190 (Application Container Security Guide)Container hardening guidanceFollowed in design
SLSA v1.0 Build Level 3Release provenance through the same pipeline Holger and Gunnar already release with (dwarves-slsa, hardware-key signed)Planned for Heimdall's first release (v0.1.0 is not attested yet)

"Implemented" means it is on main with tests; nothing in this table is a certification.

Get the code

git clone ssh://anonymous@git.gunnar.rs:2222/nordisk/heimdall.git
cd heimdall
cargo build --release

Contributing, security and changes

Licence

AGPL-3.0-only, or a commercial licence from the joint owners Ignalina ApS and Vetra Automation AB (see COMMERCIAL-LICENSING.md). Contributions are accepted under the CLA.

Fuzzing results

Measured 2026-10-30 on main after v0.1.0: every cargo-fuzz target ran 30 minutes (the first six twice), about 1.9 billion inputs in total, with no crash. Run it yourself with scripts/fuzz.sh.

TargetWhat it feedsInputs triedCrashes
output_nameOutput file names466 million0
pinned_key_textThe pinned key line287 million0
result_encodingThe canonical result encoding209 million0
policy_fileThe TOML policy file14.4 million0
verify_result_fileA result file given to verify-result10.7 million0
signed_result_wireThe signed-result wire format10.6 million0
wasm_emit_fileGuest file names, sizes, traps partway through4.6 million0
wasm_guest_loadRandom bytes through pin, signature and compile186,0000

wasm_guest_load is slow by design: it signs and compiles every input.

Files

.cargo/
LICENSES/
assets/
ci/
crates/
docs/
fuzz/
guests/
scripts/
xtask/
.gitignore
CHANGELOG.md
CLA-SIGNATURES.md
CLA.md
COMMERCIAL-LICENSING.md
CONTRIBUTING.md
Cargo.lock
Cargo.toml
LICENSE
NOTICE
README.md
SECURITY.md
deny.toml
rustfmt.toml

Newest commits

8ef60fa1f23cREADME: the OpenSSF Best Practices badge (bestpractices.dev project 16105, passing)2026-10-30
740324112c45scripts/ci.sh: Heimdall is a defensive sandbox — every guests/*/ workspace gets fmt, clippy -D warnings, its tests (the verify-bundle guest runs in the real wasm host) and a wasm32 build; verify-bundle lock follows main2026-10-30
5438dab40a87guests/verify-bundle: GREEN — Heimdall is a defensive sandbox: the Holger bundle verifier in pure Rust for wasm32 (znippy v0.7 reader with its own total Arrow IPC decoder, Holger's release signature, approvals, two-person rule, dual digests, size caps, DSSE before statement parsing), stable codes (holger-update-<n> / heimdall-bundle-<n>), wit-bindgen export against heimdall-wasm's WIT; 157 tests incl. 7 in the real host, fuzz clean (5 targets x 240 s, three arrow-ipc panics found and kept as seeds)2026-10-30
4e0f98c6efd4guests/verify-bundle: RED — Heimdall is a defensive sandbox: the Holger bundle verifier guest's API, real Holger-made bundles and 149 tests (archive, tampering with Holger as the oracle, DSSE, policy and parameters, proptest, fuzz seed replay), five cargo-fuzz targets; reader, path guard and pipeline stubbed2026-10-30
64fce8f15928Merge m1/ci into main (lane heimci): cargo xtask ci = scripts/ci.sh for the dwarves CI forge2026-10-30