Security policy
Heimdall is a defensive sandbox: it runs untrusted parsing, verification and scanning jobs so that a compromised job can reach only its own input and its own output. A security bug in Heimdall is therefore anything that lets a job, its input or a guest reach further than that, or that makes a caller accept a result Heimdall did not sign.
This policy covers every part of this repository:
- heimdall-core: the job API (
JobRunner,Job,Policy,Limits), the canonical binary wire v1, the per-boot Ed25519 key,SignedResult,verify,check_outputs, the pinned key record and the replay guard. - heimdall-wasm: the wasm host (wasmtime component model, no WASI), the guest signature and BLAKE3 pin checks before load, and the fuel, time, memory, table, instance and stack limits.
- heimdall-plain: the plain runner (
PlainYoukiRunner), an ordinary youki container per job, the OCI image check and unpack, the default seccomp profile and theheimdall-plain-shim. - heimdall-run and heimdall-cli: the policy file, the input and output
directories,
heimdall runandheimdall verify-result. - guests/: the wasm guests built for Heimdall (for example
verify-bundle).
Report a vulnerability privately
Write to gunnar@gunnar.rs. Start the subject line with SECURITY: and name
Heimdall in it (for example SECURITY: Heimdall wasm host ...).
Do not open a public issue for a vulnerability, and do not push a proof of concept to a public repository. If you want an encrypted channel, say so in a short first mail without details, and we agree on one with you (for example an age key).
What to put in a report
- The version (
heimdall --version), the tag or the commit, and the crate. - The build: the default build, or the features you turned on (for example
youkifor heimdall-plain's shim). - The part of Heimdall it is in, if you know it: heimdall-core (the wire, the signature, the verifier, the output check), the wasm host, the plain runner, run or the CLI, or a guest.
- How to reproduce it: the steps, the policy file, the job input, the guest or the image if one is needed, and a proof of concept if you have one.
- What an attacker gains, as you see it. For Heimdall this includes a job that reads or
writes outside its own input and output, a guest that runs without passing the
signature and pin checks, a limit that does not fire, a host crash or hang caused by a
job, and a
SignedResultthatverifyorcheck_outputsaccepts although Heimdall did not produce it for that job. - Whether you plan to publish, and when.
- The name you want in the credit, or that you want none.
What happens next
- We acknowledge your report within 14 days.
- We tell you whether we accept it as a vulnerability, and we keep you informed while we work on it.
- Our target is a fix or a documented mitigation within 60 days of the report. For a critical vulnerability we aim for 14 days.
- We agree the publication date with you. By default we publish when the fix is released, and at the latest 90 days after the report.
- We credit you in the CHANGELOG and in the advisory, unless you ask us not to.
Supported versions
Only the latest release line gets security fixes.
| Version | Supported |
|---|---|
| 0.1.x (latest: tag v0.1.0) | Yes |
| Older | No |
A fix lands on main first and ships in the next release on the supported line, as a
new tag (and, once Heimdall is on crates.io, a new crate version).
How fixes are announced
- Every release has a section in CHANGELOG.md. It lists each fixed vulnerability under Security, with its CVE, RUSTSEC or GHSA id where one exists.
- Heimdall is consumed by git tag today (see docs/API.md). The known consumers (Holger and Gunnar) are told directly when a fixed tag is out. Once the crates are on crates.io, we publish a RustSec advisory for a vulnerability in Heimdall's own code (https://rustsec.org), and we request a CVE or a GHSA where one applies.
- For a vulnerability in a dependency (for example wasmtime or libcontainer), the CHANGELOG names the upstream advisory and the version that fixes it.
Dependency advisories
deny.toml and cargo-deny check the lock against the RustSec advisory database
(cargo deny --locked check advisories); scripts/ci.sh runs cargo deny check, and
the CI image (ci/ci.Containerfile) carries a pinned cargo-deny. An advisory fails the
check unless deny.toml ignores it, and every ignore there states its reason. An ignore
is only for an advisory that has no fixed version and that we have checked cannot be
reached in Heimdall. At v0.1.0 no advisory fires, and deny.toml ignores none.