Changelog
All notable changes to Holger are listed here, one section per version published on crates.io. Each entry names the commit on main it comes from. The format follows Keep a Changelog, and Holger uses Semantic Versioning.
Each fixed vulnerability is listed under Security with its RUSTSEC, CVE or GHSA id. To report a vulnerability, see SECURITY.md. The full list of features, with status, date, source path and commit, is docs/v1/FEATURES.md.
3.1.1 (unreleased)
A draft. Changes on main after 3.1.0 (the freeze 2d7db79e merged hol310/release, d3d7bf2d). The upload fix P12 is in both: 3.1.0 carries it cherry-picked (bc7c1056, 37fc0c97), and main has it as 3bb8bc75.
Added (3.1.1)
- A pull is approved as ONE dependency set (lane HOL-DEPSET-APPROVE, field row HOL-MAVEN-APPROVAL-WAVES). A request that pulls a package now pulls its whole dependency closure. Maven: the POMs Maven reads (parents, imported BOMs, every version the graph visits) and the JARs of the mediation winners, resolved as Maven 3.9 does (
pull_intake::pom). Formaven-dependency-plugin3.7.0 that is 221 files, exactly the set a realmvn dependency:getdownloads. npm, cargo and Python closures come from their registries' metadata (pull_intake::closures). Every file goes through the intake chain as before. The approvers see the closure as one set:GET /-/intake/sets,GET /-/intake/set?id=,POST /-/intake/set/approve|refuse?id=&reason=, and the Dependency sets cards on holger-ui's Security page. The two-person rule is unchanged per member. A member with a refusal reason refuses the set and is named (holger-depset-2). A member that cannot be resolved or scanned holds the set (holger-depset-3, fail closed). In the field, the plugin's 221 files were judged in one round instead of 30+ rounds of about 100 approvals.
Changed (security policy, 3.1.1)
- A Maven POM's advisories are a warning, never a block (lane HOL-DEPSET-APPROVE). A
.pomcarries no code: it is the descriptor Maven reads to build the dependency graph, and Maven reads the POMs of OLD versions it then mediates away without fetching their JARs (a realmvn dependency:getreadscommons-collections 3.2.1,log4j 1.2.12anddom4j 1.1POMs undermaven-dependency-plugin3.7.0). Before, such a POM was refused by its CVE (403), and Maven fails hard on a refused descriptor, so the plugin could never resolve through Holger. Now the vulnerability scanner records the POM's advisories as a WARN (named in the evidence, the dependency set and the console; scanner policyholger-scan-vulnerability/2, so stored verdicts are scanned again), and the rulecve_maxskips them. The JAR, WAR, EAR or AAR of the same coordinates is matched and refused as before (a log4j-core 2.14.1 JAR is refused with GHSA-jfh8-c2jp-5v3q). Malware, licence, provenance, secrets and inspection still block a POM. The rule is keyed on the Maven ecosystem and the.pomsuffix only (scanner::advisories_warn_only).
Changed
- Peak memory is bounded. glibc's arenas are capped at 4 (
server_lib::memory::bound_allocator), and a download is read from the znippy store in pieces (stream_get,ZnippyBase::file_pieces), never whole: pip, npm, Maven, apt and dnf first (54a734a7), then Helm, gems, Go, conda, Rust read-only archives, Composer, Docker blobs and NuGet, delta chunks too (a444ec32). holperf on the real package sets (oden, 32 threads, 499 GiB RAM): peak RSS per set 3643 to 8449 MiB on 2026-10-31 (holger 2103f732) and 139 to 191 MiB on 2026-11-01 (holger ad6d66db) (holperf/results/2026-10-31-oden-holperf.json,2026-11-01-oden-holperf.json).cargo xtask bench-readme checkis red above 512 MiB per set. - No intel is said by name. A box with no advisory database, or one past
intel.block_after_days, still holds every package (it always failed closed), and now says so as "no vulnerability data (HOLGER-INTEL-MISSING)" or "vulnerability data N d old (HOLGER-INTEL-EXPIRED)", not as a finding (bfc198cc, bf78828c, 4cfc055f). GET /-/sandbox/probelooks into Heimdall's runner: the worker's probe runs as one job of the server's runner, and the answer names the engine (HOL-HEIMDALL-06, d0899f40).- The console's Disks pane says that a repository's storage folder not made yet is created at the first upload, not a fault (
AdminUnresolved.made_at_first_upload, 68aa7d69).
Added
cargo publishis a door of the intake chain (lane HOL-CARGO-PUBLISH-DOOR). Since P19 a chain Holger refusedcargo publishinto a writable crates registry (holger-intake-15). Now the repositorypromotion.intake.cargonames (crateson an estate, no storage of its own) is the chain's cargo door, the waypromotion.intake.npmis the npm door: a publish is INGESTED intoincoming(crates/<name>/<name>-<version>.crate) and walks the chain (scan, policy, two approvers); the sparse index lists only AVAILABLE versions, each line from the sealed crate's ownCargo.toml(the scan worker's new crate row,holger_index_rows::crates);cargo yankandcargo yank --undoare recorded for AVAILABLE versions only. A crate with a malware finding is refused at the publish; a crate that pins a dependency version with a known advisory (=x.y.z, or a binary crate'sCargo.lock) is refused at SCANNED by the advisory and the dependency's name. New codesholger-cargo-1toholger-cargo-4. The console's client setup offerscargo publish,cargo installandcargo yankfor the door again. Test:cargo_publish_walks_the_intake_chain.rs(real cargo).- Archive-backed deb and rpm repositories sign their metadata (
ron_archive_path):InRelease,Release.gpgandrepomd.xml.ascunder the box's repository key, like the chain views. The console's apt and dnf setup names the box's key fingerprint (a downstream's own) (HOL-SIGN-2). - A locked crate version that is not the newest pulls through. The crate index lists the upstream versions that are not AVAILABLE as yanked, so a
Cargo.lockpin pulls exactly that.crate(HOL-FIELD-TEST, de14ed73). - Maven plugin-prefix resolution through the pull-through. The group-level
maven-metadata.xml(for exampleorg/apache/maven/plugins/) is served as the source's plugin list, somvn dependency:getand other prefix goals resolve (HOL-FIELD-TEST P13, 1ae850f0). - The ONE box's refeed carries the console's public-site switch (
console_public_site = on | off); main and twin keep it as the settingconsole.public-site, audited (HOL-PUBSITE-FEED, d8060233).
Fixed
- Security: the repository key's file is never written through a left-over temporary (a 0644 file or a symlink in
repo-signing/), and arepo-key createthat races another never replaces its key (HOL-SIGN-2 review, F1). - Security: a chain view never serves or signs an index that came through the chain. A
Release,InRelease(a replayed older one) orrepomd.xmluploaded underdists/orrepodata/and approved is not a file of the view; the view serves and signs only the index it synthesizes (HOL-SIGN-2 review, F2). The key signs aReleaseonly at a plain suite word (H1). - Two pulls of one coordinate at once never block it. cargo asks for the index and the download together; the second pull now walks on from where the first left it, where it was BLOCKED with SCANNED to SCANNED (ryu 1.0.23 in the field) (HOL-FIELD-2, 4f336f1d).
- The feature sets
gateway(sync, fetch, downstream-wg, supply-chain, gateway) and the combined set (supply-chain, jobs, online, sign, auth-passkey, estate, fmt-all, pull-apk) are green and are steps of the full CI set (70903647, 4df743ea); clippy-D warningsis clean on xtask, holger-agent-cli and server-lib with all features (ed63b753, bf17f87b);xtask/tests/lone_clone.rsreads the whole publish list again (8484f3e4).
Documentation
- docs/v2: chapters 3, 4, 5, 9, 10 and 11 filled from v1 and the code on
main, with the client setups for pip, npm, cargo, Maven, apt, dnf, OCI, Go and Helm (HOL-DOCS-V2).
[3.1.0] - 2026-11-01
Published from the main commit the tag v3.1.0 names. Changes since 3.0.0. The products holger, holger-downstream, holger-cli and holger-ui are 3.1.0. Only the crates whose content changed are published again: holger-scan-worker, holger-intel, holger-zip-entry, holger-index-rows, holger-server-lib, holger-traits (its README) and the Composer, deb, Helm, NuGet and rpm repositories are 3.1.0; holger-job-runner and holger-sandbox are 4.0.0 (cargo-semver-checks against 3.0.0: a new field on an exhaustive struct, a new engine variant). holger-server-lib stays on the product line although cargo-semver-checks finds new fields and variants in its flow model and protos: its version is Holger's version identity (holger --version, health, the fleet's build, the scan worker's build). Every other crate stays 3.0.0.
Security
- Fixed: a known vulnerability in a pulled package was not caught. A package pulled through the pull-through (a Python sdist, an npm tarball, a Maven jar, a crate) was matched against no ecosystem, so the advisory scan found nothing: PyYAML 5.3 and lodash 4.17.15, each with a known CVE, passed the scan and were served. A pulled package is now scanned in its source ecosystem (pip for every Python file, npm and Maven with their coordinates, cargo), and a known CVE refuses it as for an uploaded one (HOL-FIELD-TEST P11, ddc04aab; a real-record guard holds PyYAML 5.3 to both its critical advisories, CVE-2020-1747 and CVE-2020-14343, 2574fc6f). Every 3.0.x box that pulls through should upgrade: what it pulled before was not matched against its ecosystem.
- Fixed: an upload with a known vulnerability passed as raw (Log4Shell). A package uploaded under a chain view was scanned as raw, so the advisory scan found nothing: the real log4j-core 2.14.1 (CVE-2021-44228, Log4Shell) uploaded under
maven/passed with 0 findings, and deb, rpm, Helm and pulled APK packages had the same gap. An upload is now scanned as its format with the coordinates its path names (deb, rpm, Maven with group:artifact, Helm), a pulled APK as its repository's distribution, and a package file (.jar .pom .deb .rpm .crate .gem .nupkg .apk .conda .war .ear) that would reach the CVE scan as raw is held (holger-no-ecosystem), never passed (HOL-FIELD-TEST P12, bc7c1056 + 37fc0c97, cherry-picked). Every 3.0.x box should upgrade. - Fixed: an offline downstream could dial out. In a downstream build, an explicit
network: Offlinethat also named an upstream left the process pinned to that upstream, so it could still make the call. Such a declaration is now refused at start (holger-offline-2), and an offline downstream is fully offline: the process makes no network call (HOL-PRODUCTS-8, 4a2b3b79).
Changed
- Every host rebuilds its scan worker image for 3.1.0. The worker image is tagged with Holger's release,
localhost/holger-scan-worker:3.1.0(it was:0.1.0for every version), every scan report names the worker's build (its version and scanners), and the server refuses a worker that names no build, another version or fewer scanners, by name and with the rebuild command, where an old worker blocked every artifact with "the scan worker sent no sbom record" (HOL-FIELD-TEST P1, 3a6eeefb). After the upgrade, runcargo xtask scan-worker image(podman) orcargo xtask scan-worker stage(a medium's rootfs) on every host; a RON that namesimage: "localhost/holger-scan-worker:0.1.0"names the new tag. - A pip project page whose files wait for approval answers 200 and lists those files as yanked, with the reason (PEP 592 / PEP 691
yanked, PEP 503data-yanked), where 3.0.0 answered 404. pip skips a yanked file unless it is pinned exactly, so a pinned install (requests==2.32.3) through the pull-through now pulls exactly that file, a wheel included, and not only the newest sdist (HOL-FIELD-TEST P2, cb9773f9). A client that read the 404 as "not here yet" now sees the project with no installable file. - A pending npm package answers 200 with its unapproved versions listed as deprecated, with the reason, where 3.0.0 answered 404. Their tarballs go through Holger's door, so a pinned npm version that is not
latestpulls through (HOL-FIELD-TEST, 58e18660). - Heimdall 0.2 (lane HOL-HEIMDALL-02, 02deccdc):
nordisk-heimdall-core"0.2" from crates.io; the job results are Heimdall's signed wire v2, and producer and verifier moved in one build (a 0.1 result is refused). - The flow (HOL-FLOW-SMART, Henrik, 2d945aee): three zoom levels of one model. With no
openit draws the machines and the upstream sources (the Overview);?open=main,lab-1unfolds those machines with their part of the RON;?open=allis the full RON, on/-/flow.svg,/-/flow.jsonandAdminService.FlowSvg(FlowSvgRequest.open,FlowSvgReply.links). Every node names its box, lines cross a machine border at ports, the diode drop area and a one-way inbox are drawn, a downstream line says declared/paired/seen. The schema isholger.flow/v2. - The sync report (HOL-SYNC-SKEW, 50cbe685): a downstream reports a summary of its own RON (
DownstreamSummary) under its own proof (summary_proof); the signed report text is the 3.0.0 text, so a 3.0.0 and a 3.1.0 Holger hear each other's reports. A stray downstream seen long ago is grey with a?; the diode and inbox counters come from the audit; the console is seen per server.
Added
-
The front unfolds in the flow, and another Holger leads to its own flow (lane HOL-FLOW-FRONT, Henrik's Q1 and Q4 of HOL-FLOW-SMART): the estate front reports its doors, the names it serves and where each goes to main (
POST /-/front/report, proven under a key derived from the front's and the box's console keys; an older main answers 404 and the front carries on), main keeps the last report and the flow draws the front unfolded at levels 2 and 3 with the same box and port rules; a front that never reported stays one closed box. A downstream's summary carries its console's address with its own proof (console_proof, so a 3.1.0 upstream still opens the summary), and its box links to that server's own flow (FlowLinkwith the console's/flow); with no known console there is no link. New error codeholger-front-5. -
promotion.intake.sandbox: (engine: heimdall, heimdall: (…))(featureheimdallofholgerandholger-server-lib): the scans and the bundle verifies run as jobs of Heimdall's protected runner (nordisk-heimdall-container 0.2: Landlock, Heimdall's seccomp profile, the worker image verified at every start), following Heimdall's scan-worker job contract; where Heimdall cannot start, youki-plain, then crun overrootfs(never for a root process: there a job's root maps to the host ids 100000/65536, Heimdall 0.2.1with_host_ids), each said by name. The Security page andholger jobsshow the runner's features and Heimdall's kernel report; strict CDS warns when the runner is not Heimdall. -
Heimdall's released verify-bundle guests (heimdall-guests-0.2.1) vendored under
guests/heimdall/0.2.1/with their pins, SLSA statement and signatures, loaded as the split pair under korp-root-ca (holger-job-runnerfeatureheimdall-wasm). -
The appliance medium carries Heimdall (the static shim 0.2.1, the released verify-bundle guests, the worker tar), the estate declares
engine: heimdall, and the import door verifies every bundle in the split wasm guest inside the worker (nordisk-heimdall-wasm 0.2.1, strict DSSE) (HOL-HEIMDALL-03/04, 9cfbf221). -
A crates.io
holgernames the commit it was published from (.cargo_vcs_info.jsongit.sha1) instead ofunknown(GUN-VERSION-STAMP, 81c13781). -
The README's speed table comes from holperf on real packages (pip, npm, Maven, Helm, apt, dnf, OCI), with the cost of the first index and the peak RSS beside each number (
cargo xtask bench-readme, README-BENCH, c694a3f0). -
The deb and rpm views serve signed metadata under the box's repository key (
InRelease,Release.gpg,repomd.xml.asc, the key at/-/repo-key.asc), so apt and dnf check it without[trusted=yes]orgpgcheck=0(HOL-SIGNED-APT-DNF, HOL-FIELD-TEST P4, f9257ddd). Operators runholger repo-key createonce per box; a box without a key serves unsigned metadata and warns. -
The first admin of a plain start with a passkey method comes from a single-use first-sign-in link in
<data>/holger-passkeys/first-sign-in.url: its passkey becomes the admin (HOL-FIELD-TEST P3, 8b5e367c). -
The sync doors (HOL-PRODUCTS-5):
GET /-/sync/keyanswers an authenticated identity only (401 without a credential), andPOST /-/sync/ackchecks both the downstream's bearer (itstoken_file) and the ack's signature; the doors' table says so (f45d99bf, db29fb7c). -
The WireGuard tunnel comes up only when Holger starts, never when the intake chain is built (for example by
holger sync key) (HOL-PRODUCTS-9, cf0459de).
Fixed
- A scanner error at ingest is a scan failure, retried, not a refusal for good. A pull refused only by scanners that could not run (
scanner-error,scanner-not-configured, for example a stale worker) was recorded as a permanent refusal; it is now "scan-failed, retry": nothing is stored or served in the meantime (fail closed), and the next request scans it again once the scanners can run (HOL-FIELD-TEST P8, e59af7e7). - A main laid again after its death is held for its recharge again and keeps its sync key: the medium's seeded Sigstore trust root no longer counts as history of its own (HOL-REBUILT-SYNC-KEY, bcc23545).
holger intel buildreads the real OSV dumps: an OSV dump has its own member ceiling (npm'sall.ziphas 230994 members), and an affected entry with no package is dropped with the record kept (8a0b9afd); the alias merge runs per (ecosystem, package) in linear time, so a build over the real feeds ends (100000 records in seconds, 6416a8ce).- The tests that were red on main (HOL-310-RELEASE): the twin test's fixed loopback pair, the source scans after the fmt sweep, the front's console token mode, the
boundary: Fetchdownstream tests after a one-way build, the server-lib--all-featuresclippy.
[3.0.0] - 2026-10-31
Published from the main commit the tag v3.0.0 names. Changes since 2.0.0. A major release: the defaults are the NCSC P1 safe defaults, Holger is four products, and the ORIGINAL and OPEN suites are retired.
Crate versions
- Every holger crate is 3.0.0, and so is the web console
holger-ui(holger-ui repo). - New on crates.io:
holger-cli(the thin client with the offline tools), the productsholger-downstream(a thin crate overholgerwithdownstream; crates.io's holger-downstream 2.0.0 was the rules library, nowholger-downstream-rules) andholger-ui(the web console; crates.io's holger-ui 0.1.4 was the old egui console),holger-ui-server,holger-public-site,holger-scan-workerandholger-job-runner. Heimdall's job API comes from crates.io (nordisk-heimdall-core0.1.0, fe3e2f75), so no published crate names a git or unpublished path dependency.
Changed (breaking)
- Four products, one crate each:
holger(the server),holger-downstream,holger-ui,holger-cli; every product has the extrasall-formats,online,federation,full(00b40dcd). The suites ORIGINAL and OPEN, the tiersminiandembeddedand the bins holger-embedded, -mikro, -full, -bundle, -verify, -agent are retired (00b40dcd). - NCSC P1 safe defaults: a bare door is HTTPS unless it is this machine (holger-listen-1/2, a5c3c57c); no profile runs without its audit log (holger-audit-13, 44038a07); a Security Approver is invited only from a stepped-up passkey session (holger-auth-6, c5cd8171); the sandbox and clamd are required where the intake chain runs (holger-sandbox-14/-15, 5b9edc10, 2f57bf3e); every socket asks the egress check first and every refusal leaves an audit row (NCSC P1 item 5, a2aec0a6).
- The admin plane has its own listener (
ron_admin_url: AdminService, PromotionService, AuditService, TokenService) (NCSC P2, c4d577ec). - Untrusted work runs as jobs behind Heimdall's job API: bundle import and scans are jobs of the interim ContainerRunner (d276bdc1).
Added
holger-cli bundle allow-first-importand the console's First import form (c39b26ef).- A plain server invites its downstream directly (
holger-cli downstream invite, b03ead25). - The export carries only what decides (
export_profile, NCSC P2, 431143e1); mTLS doors check a CRL (ron_tls.crl, NCSC P3, 55befeba);cargo xtask release-attestnames every shipped artifact (NCSC P3, e5b4a99d); the system threat model, docs/v2/threat-model.md (325801eb). holger-index-rows: the scan worker's bounded per-package index fields on the scan wire (HOL-PERF-2, a4bf77e6).
Security
- znippy-common 0.10.3: a whole-body read reserves its result and reads stored chunks in place (a 64 MiB crate download allocates 67.5 MiB, was 220.7 MiB).
- znippy-plugin-maven 0.10.1 moves to quick-xml 0.41, and quick-xml 0.36.2 leaves the lock (RUSTSEC-2026-0194, RUSTSEC-2026-0195). In Holger, quick-xml 0.36.2 was reached only through dev-dependencies (tests), not through the shipped server (73a5e5fb, 69bbe575).
- crypto-bigint 0.5.5 (RUSTSEC-2026-0387) is ignored in
deny.tomlwith its reason: it comes only through the PGP verifier (pgp0.21.0, the newest), where Holger uses public keys only, and no fixed 0.5 release exists. The estate locks follow monetize to skidbladnir 0.2.3 (f3f3a023). - The front carries only Holger's own gRPC services on the repository host, so the identity core is never reached from the internet through the front (48600b3e).
- The scan sidecar bounds each job's processes with a cgroup
pids.max(2d5dead9, eabdb3c1). - An invite needs a fresh step-up (nornir-identity 0.2.2) (5ba2272c).
Added
- holger.rs's front page names the release key (its key id) under the credit and links to
slsa/(ab668791). - The release signing key in
slsa/: the owner's YubiKey key (PIV slot 9c, P-256, PIN once, touch always), key idd24d3785e8281bcd37e8f2c40a3a85e8152d3ce2200a5c929a1a5ca636e8249e, with the YubiKey's attestation of it and the attestation CA (67154e42). - SLSA Build L3 release provenance:
docs/v1/SLSA.md, the release key inslsa/, the attestations inattestations/, and a test that the provenance scanner verifies such a release bundle (25e9033b). - The front's downstream interface logs its relay counters (48ac2fe7).
- Holger's guest declares its front's downstream port (udp/51830), so the ONE box opens only declared ports (09525b5d).
Changed
- holger-server-lib and the
holgerbinary are clippy clean under-D warningsat every feature set a build uses (f0d43bcf, 2812762c, 0d665955). - The root takes monetize-proto 0.3.3 and estate-front 0.3.0 from crates.io (10adba30).
- holger-provenance leaves its 11 MB test fixture out of the crates.io package, as the 2.0.0 package already did (7a4f5fce).
Fixed
- A dead main is rebuilt from its twin again (3df55b53).
- A lean main (no public IPv4) that the ONE box lays again is re-admitted at its utility address (1bc2d71f).
- The promotion gate refuses over gRPC
PromoteArtifact(81309576). holger-cli artifacts putstreams a file of any size (63f82f3f).- holger-server-lib's default build compiles again (27049467).
- An endpoint the admin names wins over the front's own address in a WireGuard invite (b892cf05).
2.0.0 - 2026-10-29
Published from 87e5ada5, which is main at 7bebb1e6 plus one packaging commit (the large test fixture left out of the package). Changes since the 0.6.10 crates (2026-08-23).
Holger 2.0 is a security gateway: every artifact passes an explicit intake chain before it is served, and the open core builds and installs with plain cargo.
Security
- The intake chain: each artifact has one state from UNTRUSTED to AVAILABLE, on HTTP PUT, native uploads and gRPC, and is served only when AVAILABLE (99daae77).
- Separation of duties: Developer, Importer, SecurityApprover, RepositoryAdmin and Auditor; the importer never approves its own import (17bda3af).
- File and archive inspection on every ingest (zip bombs, nesting, path traversal), and ClamAV and YARA hooks (b231aa9e).
- Every scan runs in a hardened rootless container, never in the server (1998749a, babf13c8).
- The offline provenance verifier: DSSE, in-toto, SLSA, and Sigstore keyless (Fulcio chain and identity), PEP 740, npm attestations and cosign (5eeac4fd).
- Offline vulnerability intelligence: OSV, NVD and KEV as a signed bundle, with Wolfi and Chainguard advisories (c643b9a7, d605b919).
- One tamper-evident audit trail per artifact (a hash chain with signed checkpoints), and its SIEM export (2c0d2eca).
- AI models are artifacts, and pickle files are blocked by default (7bb56235).
- The public HTTP door and the gRPC door speak TLS 1.3 only (831a8dee).
- Holger runs on edda's shared identity core, with a
__Host-HttpOnly session cookie (d47e5b15). - The security review of 2026-09-11 found 40 defects, and all 40 are fixed, each with a test that failed first (5ad190d8;
docs/v1/security-review-2026-09-11.md). -
Dependency advisories fixed in the lock:
- rustls 0.23.46 (RUSTSEC-2026-0285, RUSTSEC-2026-0346, RUSTSEC-2026-0348, RUSTSEC-2026-0349) (61954cd6);
- wasmtime 49.0.3 with cranelift 0.136.3 (RUSTSEC-2026-0353 to RUSTSEC-2026-0364) (61954cd6), then wasmtime 49.0.4 (RUSTSEC-2026-0378, RUSTSEC-2026-0379) (0b829a36);
- the plugin host moves from wasmtime 27 to 48, which clears 15 of the 17 wasmtime advisories that
deny.tomlhad accepted (1bd8c086); the wasmtime 45 copy of a dev-dependency (RUSTSEC-2026-0222, RUSTSEC-2026-0269) later leaves the graph (5f9898f9); - zip 9.0.5 in bench-scenarios and znippy-rust (RUSTSEC-2026-0367, RUSTSEC-2026-0368, RUSTSEC-2026-0369) (61954cd6);
- rustls-pemfile (RUSTSEC-2025-0134, unmaintained) is gone: PEM is read with rustls-pki-types (61954cd6);
- h2 0.4.19 (RUSTSEC-2026-0258), and quinn-proto, crossbeam-epoch and webbrowser (bcdf9b64);
- zbus 6 through skidbladnir 0.2.1, which leaves the unmaintained zbus_names, zvariant and zvariant_derive behind (a5b97301).
Added
cargo install holgerand a plaincargo build --releasegive a working server, and a lone clone builds and serves (80ec7d64, 81085f58).- Tier 1: a plain cargo build carries the intake chain, configured in one RON shape (sources, steps, rules, gates) (baa48b3a).
- Pull-through through the intake chain for OCI (cgr.dev), Python (PyPI, Chainguard Libraries), npm, Maven, crates and APK (Alpine, Wolfi) (77477911, ce1d6a13).
- npm through the security gateway (1027710e), and
twine uploadinto the intake chain (513dcac5). - The airgap:
holger-server exporttakes the AVAILABLE set with its evidence and signed attestations, and the secure side imports and verifies it (297c3efb);cargo xtask demo airgapruns the demo (0c73355d). - The sync protocol (signed sync manifests with generations), behind a default-off feature (be9cb743).
- The on-premises downstream gateway:
cargo install holger --features downstream(7b1b68fe), and WireGuard downstreams. holger-cli, the thin gRPC client; every console call is a CLI command (5022717e).- The estate board, the Security page, buyer pages, and the shared buy flow.
Changed
- The licence is AGPL-3.0-only plus a commercial licence, owned jointly by Vetra Automation AB and Ignalina ApS (d936a182). Versions published on or before 2026-10-02 keep the licence they were published with (mostly MIT).
- The root workspace is the open core; the estate parts are a separate
estate/workspace (c804ffc9). - Airgap is the default: with no upstream named, Holger is offline (d72706dd).
HOLGER_QUARANTINE_PROPERTYis retired and refuses the boot (holger-intake-14); the hold is the intake QUARANTINED state (0cb5f11f).- Everyone registers their passkey again after this release, because sessions move to the shared identity core (d47e5b15).
Known advisories
- RUSTSEC-2023-0071 (
rsa, no fixed release) is ignored with its reason: Holger performs no RSA decryption on attacker-supplied data. - The packaged
Cargo.lockholds crypto-bigint 0.5.5 (RUSTSEC-2026-0387), which is triaged under Unreleased. It holds no quick-xml.
Earlier versions
Before 2.0.0, the server was published on crates.io as holger-server-cli, beside holger-server-lib, holger-traits and the other holger-* crates. These versions are listed by their publication date on crates.io and by the git tags:
- 0.6.10 (2026-08-23): tags
holger-server-cli-v0.6.10and the other per-crate-v0.6.10tags (86cb764b). - 0.6.9 (2026-07-17), 0.6.7 (2026-06-26), 0.6.6 (2026-06-19) and 0.6.5 (2026-06-18).
- The git tags
v0.7.1(2026-06-15, 58fb6a55) andv0.7.0(2026-06-13, d674434c) mark workspace releases; noholger-server-cli0.7 was published. - 0.6.4 (2026-05-29), 0.6.3 (2026-05-27), the tag
v0.6.2(2026-05-27, a16277b1), and 0.5.1 (2026-05-25, tagv0.5.1, 18cb73f9).
The holger crate names 0.0.1 (2025-08-01) and 0.2.1 (2025-08-11) were published from an earlier repository, whose history is not part of this one.