Holger supply chain
Status 2026-10-30, read from the holger code (holger-provenance, server/lib, server/downstream).
One Holger on the internet checks every package on the way in. A downstream at the customer's site gets only what that Holger approved and signed: fetched over the network, or carried in on a USB stick.
INTERNET ON-PREM (customer site)
+--------------------------+ +-------------------------+
| Holger server + UI | fetch: | Holger downstream |
| (e.g. holger.rs) |--mTLS / WG--->| serves the site's |
| pulls pip/OCI/maven/... | signed | builds (pip, OCI, ...) |
| checks + approves | bundles | dials ONLY its upstream |
+------------+-------------+ +------------^------------+
| export: signed .znippy bundle | import
+--------------> USB stick --------------+ (no network)
The same signed bundle travels both ways: fetched online, or carried on USB.
1. Upstream (internet: server + UI)
Every check happens here, when a package comes in.
- DSSE / in-toto: envelopes with in-toto statements (v1, v0.1) are verified offline.
- SLSA: Provenance v1 and v0.2 are read: builder, build type and dependencies. The RON can require a minimum SLSA level and a list of allowed builders.
- Sigstore keyless, offline: the Fulcio chain to a pinned root, the SCT, and the Rekor entry or inclusion proof.
- Ecosystem proofs: PyPI PEP 740, npm provenance, cosign signatures and attestations on images (Chainguard),
.intoto.jsonl, APK signatures. - Scanners: CVE, malware, licence and secrets, each run in a sandbox container.
- SBOM: a CycloneDX SBOM per artifact, filed as a signed attestation.
- Own evidence: Holger signs its scan results and SBOMs as DSSE.
2. Export: one signed .znippy bundle
- The approved artifacts, a hash for each, and the DSSE evidence go into one
.znippyfile. - The bundle is signed with CMS (znippy's
sign). - It is the same bundle whether the downstream fetches it online or it arrives on a USB stick.
3. Downstream (on-prem: fetch or USB)
Both ways in get the same checks:
- The bundle's CMS signature is verified against the downstream's own trust roots. An unsigned or wrongly signed bundle is refused.
- Every artifact's hash is checked against the bundle's index.
- Every DSSE attestation inside (scan evidence, SBOM) is verified.
- It never fetches new trust: only keys configured on the downstream count. It dials nothing but its one upstream.
The downstream does not re-check the original package's SLSA or Sigstore proofs. The upstream did that on intake, and the downstream trusts the upstream's signed evidence. It could re-check them: the downstream already contains the verifier (holger-provenance), but the original proofs would have to travel in the bundle.
Gone since the lean cut (2026-10-17, holger 9521bf06)
- OCI referrers API: cosign and similar tools cannot find an image's signatures and SBOMs through Holger as a registry. Holger still checks them itself on intake.
- Arrow audit query backend: the audit log is now an append-only file, with no queries and no counts.
- korpsig: the signature bridge to korp.
- The RON flow picture (flow.rs): being restored, with counters.
Open questions
- Bring back the OCI referrers API?
- Should the downstream re-check the original SLSA proofs too? That means carrying them in the bundle.
- A USB stick from a source that is not a Holger, for example a vendor's stick: accept only Holger-signed bundles, as today, or also verify raw SLSA and DSSE files on import?