Showcase · Artefact channel · CI / OpenTofu

Secure artefact delivery

Approved artefacts for the estate, models and runtimes, mirrored, checksummed, signed and published as one channel, so a tool that needs a large binary dependency fetches it from somewhere accountable instead of from wherever upstream happens to host it today.

Covers 3 projects

DocsRepository

The problem it exists for

A tool that needs a machine-learning model or a native runtime usually downloads it from the vendor’s URL and checks it against a SHA-256 that somebody pasted into the source. That digest can’t be rotated or revoked, it says nothing about who published the file, and it doesn’t scale. As go/onnxruntime’s docs put it, a table of four platforms across three versions is twelve constants, and “in practice one person verifies the first and copies the pattern”.

The channel carries twelve files today, ten runtime archives and two models. Each of those would otherwise be a hand-typed constant in every tool that uses it.

How it works

Approve it once, in a merge request

Adding an artefact to the channel is a merge request against one list. Once it merges, the pipeline fetches the file from upstream, checks it, records its digest and size, signs a manifest for it with a KMS key it reaches through OIDC (so there’s no stored credential anywhere), and publishes it.

Check the signature before downloading

go/artifacts is the client a tool uses, and it checks three things in order, the first two before it downloads the file at all:

  1. a signed index, which has to list that exact version as approved
  2. the manifest’s signature, against both the key built into the tool and the key published over WKD, which have to agree
  3. the file’s digest and size, once it arrives

go/onnxruntime sits on top for the ONNX Runtime specifically, resolving the right archive for the platform. There isn’t a pasted digest anywhere in it.

Decisions and what they cost

  • A manifest per version. Every artefact-version gets a manifest of its own, signed and published when its merge request lands, instead of one manifest over everything cut from repository tags (spec 0014). What it cost: the signing key now trusts the main branch, not just tag pipelines, so an approved merge can mint a signature.
  • Exact versions, no “stable”. Tools pin exact versions. A floating “stable” pointer was turned down, because a moved pointer still verifies, so nobody would notice it had moved. What it cost: every upgrade is a deliberate, approved bump.
  • The index is required. There’s no fallback mode that skips the signed index when it can’t be reached, and an index expires after 24 hours (spec 0016). What it cost: the host is a hard dependency. When the job that keeps the index fresh wasn’t running, the channel failed closed for about a day and a half, which is the design doing its job, with every pipeline still green.
  • One bucket, on a neutral name. The channel moved to object storage on a hostname that names no provider (spec 0018). What it cost: the location is part of what’s signed, so the move meant re-signing everything and waiting a day for the old indexes to expire.

Proof in use

  • krites loads its runtime and its face models through it: ONNX Runtime 1.23.0 through go/onnxruntime, and the MediaPipe face models through go/artifacts.
  • The signed index is reissued continually, because a tool refuses one older than a day. It was at generation 155 on 10 October 2026.
  • The signatures use the same keys and the same WKD check as everything else in Signing and trust.

Use it when, and when not to

Use it as the pattern if a tool of yours downloads something large and native at runtime, and you’d rather it proved where the file came from than trusted a constant.

It’s deliberately narrow. It never picks a version for you (no “latest”, no listing), it doesn’t unpack or load what it fetches, and it can’t protect a file once it’s handed you the path. An outage of the host stops a fresh resolve, withdrawing an artefact can take up to a day to reach a tool, and it vouches for what was published, not that upstream wasn’t compromised before that. go/onnxruntime has no Windows build yet.

Where it’s going

Finishing the move to object storage, which means retiring the old package registry copies and moving the last image that still fetches from there. The specs that define the channel are also due to move from phpbotscout’s wiki, where it started, to the channel’s own.

What it covers

Last reviewed .