Skip to main content
Date: 2026-09-06. Channel: the pilot channel on channel.vexa.ai — the live registry, not a test rig. Source: Vexa-ai/vexa-delivery main @ 850c2469, clean detached checkout. Container work ran on bbb, never on the laptop. The channel’s signing key was rotated earlier the same day. This is the first artifact published under the new key, so the question the pass had to answer is not only did the kit publish but did the rotation actually take — a new key that verifies is worth little if the retired one still verifies too.

What was published

kit/release.sh --dry-run ran first and packaged an identical 262080-byte tree before anything was pushed. cosign is pinned to the 2.x series on purpose. The channel’s admission controller is Kyverno 1.19, which cannot read the signature layout 3.x writes; a 3.x signature is invisible to it rather than invalid, which is the worse of the two failures. The host carries 2.6.1, 2.6.5 and 3.1.3 side by side, so the release ran with cosign resolved to 2.6.5 through an explicit PATH entry rather than through whichever copy happened to win — release.sh calls bare cosign and has no override of its own. The flag set survives the version pin. The 2026-08-24 rehearsal recorded that 3.x requires --use-signing-config=false alongside --tlog-upload=false. 2.6.5 accepts both, so the script’s signing line is correct on either — worth stating because it is the kind of thing that silently stops being true.

Proof 1 — the version tag and latest name one digest

latest is moved with oras tag against the same descriptor bytes, so the signature made over the digest carries without a second signing operation.

Proof 2 — it verifies against the channel’s pinned key

--insecure-ignore-tlog=true is correct here rather than a weakening: the channel signs offline against a pinned key and uploads nothing to a transparency log, which is what makes it air-gappable. It is the same form kit/bootstrap.sh runs on the subscriber’s side.

Proof 3 — the rotation took, shown in both directions

Same command, same digests, differing only in --key: The control row is the one that makes this a proof. On its own, “the old key does not verify v0.1.6” is equally consistent with having pointed the check at a key that never signed anything on this channel — an easy mistake to make when a rotation has left more than one retired public half lying around, which was exactly the case here. The retired key does verify v0.1.5 and does not verify v0.1.6; the new key does the inverse. A third public half found alongside the others was tested too, and refuses v0.1.6 as expected. Where the retired key came from matters, and it was not where it was supposed to be. The obvious source — the previous revision of the published channel.pub in the state repository — does not exist: the commit that was believed to have replaced it had in fact created the file, and its contents were themselves superseded hours later. Reading git history for “the version before” produced a key that had never signed anything. The genuine retired key came from the vault, and was confirmed as genuine by the control row above rather than by where it was filed. A key’s provenance is a claim to test, not a path to trust.

Proof 4 — a subscriber-shaped pull gets a verified v0.1.6

Run on bbb from a directory holding only bootstrap.sh, with HOME and TMPDIR isolated so the publisher credential used for the push was not reachable — the isolated HOME was empty, with no .docker/config.json in it — and with a pull-only credential supplied through the environment.
The ordering is the security property and it held: the signature is checked before a single byte is unpacked. The isolation is not decoration. The same host had just pushed with the publisher credential, which oras login leaves in ~/.docker/config.json, and bootstrap.sh deliberately carries on-disk auths across to defeat a hanging credential helper. Without isolating HOME, the pull would have quietly authenticated as the publisher and proven nothing about the subscriber’s path.

What this pass does not close

  • The pull-only credential was an existing account of ours, not a freshly minted throwaway. The credential tool could not mint one; that gap is tracked internally and is not a property of the kit. What the substitution costs is narrow: reads are not scoped per account at the edge — only writes are — so the path exercised is the same one a subscriber takes, but this pass did not exercise credential issue and revoke.
  • Nothing was installed from this kit. Pull, verify, unpack and shape are proven. install.sh was not run against a cluster here.
  • The kit tree is current as of this writing: kit/ is unchanged between 850c2469 and main, so v0.1.6 is not already behind.