Skip to main content

Release image lock

Each release publishes release-vX.Y.Z.chart.json with its Sigstore bundle. This joint lock records the release, source commit, chart repository, chart version and chart digest. It also records the provenance class, repository, multi-platform index digest and platform child digests of every application image. The chart uses these image digests. Tags identify releases for people.

Before an install or upgrade, verify the lock as Independent verification describes. Then follow Verify the release chart. That procedure authenticates the chart and checks its release version. It reads the lock only to find the chart digest. The installed reconciler verifies the lock signature itself before it applies the chart that the lock names.

Chart-only release

These instructions describe the chart-only release. For a 0.95.x deployment, use that release's versioned instructions and signed assets. The 0.x upgrade path requires 0.95.1 and its installed reconciler tooling before the cutover.

Release assets​

The release builds one joint lock from its verified evidence and chart. Every asset that names an image uses the same image digests. The signing identity is release.yml on main in hephaestus-build/Hephaestus.

AssetContentsReader
release-vX.Y.Z.chart.json and its .sigstore.json bundleThe joint lock of schema version 2.Chart verification, the installer and the reconciler.
The chart at ghcr.io/hephaestus-build/charts/hephaestus@sha256:…, signed in the registryRelease metadata and references to all images from the signed joint lock, by digest.Helm, after chart verification.
hephaestus-k3s-X.Y.Z.tar.gz and its .sigstore.json bundleThe installer and the platform and host configuration, in one archive.Install on one host.
hephaestus-chrome-extension-X.Y.Z.zip and its .sigstore.json bundleThe production Chrome extension, the ZIP that the Chrome Web Store takes.Get the extension package.
release-vX.Y.Z.intoto.jsonlThe release attestation bundle. Subjects include the first-party image digests, chart manifest and package, joint lock, k3s bundle and extension package.Independent verification.
manifest.json, SBOMs, vulnerability and license reports, and signed SHA256SUMSPer-platform release evidence.Operator verification.
source.syft.json, source.spdx.json, source.cdx.jsonThe source and build inventory, separate from installed runtime packages.Supply-chain evidence describes its scope and signed verification.
host-smoke-k3s-amd64.json, host-smoke-k3s-arm64.jsonThe native k3s install, repeated-install, upgrade and isolation qualification records.Operators who check the hosts that the release passed on.

A stable release that promotes a qualified candidate keeps its image digests. The chart is packaged from the same source with stable release metadata. The extension package is built from the same source with the stable version. The joint lock names the new chart digest. Image build metadata retains the candidate version. The chart reports the stable release and source commit.

Independent verification​

Use the target release's joint lock:

VERSION=X.Y.Z
LOCK="release-v$VERSION.chart.json"
gh release download "v$VERSION" --repo hephaestus-build/Hephaestus \
--pattern "$LOCK" --pattern "$LOCK.sigstore.json" \
--pattern "release-v$VERSION.intoto.jsonl"
cosign verify-blob \
--bundle "$LOCK.sigstore.json" \
--certificate-identity \
'https://github.com/hephaestus-build/Hephaestus/.github/workflows/release.yml@refs/heads/main' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
"$LOCK"
gh attestation verify "$LOCK" \
--bundle "release-v$VERSION.intoto.jsonl" \
--predicate-type https://in-toto.io/attestation/release/v0.1 \
--repo hephaestus-build/Hephaestus

Continue with Verify the release chart to authenticate and inspect the chart that the lock names. Do not use the lock contents before signature verification succeeds.

Image build provenance​

First authenticate the joint lock with Independent verification. Run the following commands in the directory that holds the verified $LOCK file:

set -euo pipefail
COMMIT=$(jq -er '.commit' "$LOCK")
jq -er '.images[] | select(.provenance == "first-party") | "\(.repository)@\(.indexDigest)"' "$LOCK" |
while IFS= read -r image; do
gh attestation verify "oci://$image" --bundle-from-oci \
--repo hephaestus-build/Hephaestus \
--signer-workflow hephaestus-build/Hephaestus/.github/workflows/reusable-docker-build.yml \
--source-digest "$COMMIT" \
--predicate-type https://slsa.dev/provenance/v1 \
--deny-self-hosted-runners
done

Every first-party image must pass. The command checks its index digest, source repository, source commit, signer workflow, and hosted-runner identity. A reused image can keep its merge-group build provenance while a later main run signs the same digest. This does not describe a second build.

These commands do not assign a Build level to upstream images or to the chart. Release artifact provenance gives the assessment and its limits.

Rollback​

Follow Rollback. Restore the database, secrets and signed release together when schema compatibility requires it. Do not reconstruct an old lock or resolve image tags.

Runtime identity handoff​

The chart gives the server Pods APP_VERSION, HEPHAESTUS_RELEASE_COMMIT and HEPHAESTUS_IMAGE_APPLICATION_SERVER from the verified release metadata. Each process reports these values, with its runtime roles, under release in /actuator/info. The chart's deploymentEnvironment value identifies the environment. This is deployment metadata from the verified lock, not a second signature verification or an observation of the container. Malformed identity values stop startup.

/actuator/info is unauthenticated, like the adjacent health probes. After an upgrade, compare release on each role's private management listener. The administration overview shows the server that it connects to. The instance-admin API adds the update check: GET /admin/release reads it and POST /admin/release/checks asks GitHub now. Update checks describes cadence, privacy and offline operation.