fix(oci): extract index digest in verify step so attestation builds pass #56

Merged
nrupard merged 1 commit from fix/verify-attestation-digest-LINKS-24 into main 2026-06-09 20:37:40 +02:00
Owner

Problem

The Verify pushed image step in build-oci-image.yml failed on every main build with a spurious DIGEST MISMATCH (LINKS-24, run #152). It compared the --iidfile digest against docker buildx imagetools inspect $ref --format "{{.Manifest.Digest}}".

The docker-container buildx driver attaches a provenance attestation by default, so the pushed ref is always an OCI image index: the linux/amd64 manifest plus an unknown/unknown attestation manifest. For an index, {{.Manifest.Digest}} does not reduce to the digest. buildx falls back to its full human-readable dump (Name: ... MediaType: ... Digest: ... Manifests: ...), so the captured $remote is that whole block and never equals the pushed digest. The step exits 1 even though the publish succeeded.

The publish itself is fine: the registry index digest equals the --iidfile value. The buildcache 499 seen in the same run is non-fatal because cache-to sets ignore-error=true. The broken verify was the only thing failing the job, so this is a code fix, not the infra/human action the triage guessed.

Fix

Render the index descriptor as JSON and read .digest:

let remote = (^docker buildx imagetools inspect $ref --format "{{json .Manifest}}" | from json | get digest | str trim)

{{json .Manifest}} serializes the index descriptor (including the digest field), which nu parses natively and which equals the --iidfile digest.

Verification

Reproduced locally against a registry:2 with a docker-container buildx build (attestation index, image-agnostic verify logic):

  • --iidfile digest: sha256:e985...946eddc (the index)
  • Old {{.Manifest.Digest}} -> captured Name: localhost:5000/test:v0.4.0 ... (full dump) -> MISMATCH
  • New {{json .Manifest}} | from json | get digest -> sha256:e985...946eddc -> Verified, exact match

Confirmed in nu 0.112.2 (the runner shell).

## Problem The **Verify pushed image** step in `build-oci-image.yml` failed on every `main` build with a spurious `DIGEST MISMATCH` (LINKS-24, run #152). It compared the `--iidfile` digest against `docker buildx imagetools inspect $ref --format "{{.Manifest.Digest}}"`. The docker-container buildx driver attaches a provenance attestation by default, so the pushed ref is always an OCI image index: the `linux/amd64` manifest plus an `unknown/unknown` attestation manifest. For an index, `{{.Manifest.Digest}}` does **not** reduce to the digest. buildx falls back to its full human-readable dump (`Name: ... MediaType: ... Digest: ... Manifests: ...`), so the captured `$remote` is that whole block and never equals the pushed digest. The step exits 1 even though the publish succeeded. The publish itself is fine: the registry index digest equals the `--iidfile` value. The buildcache `499` seen in the same run is non-fatal because `cache-to` sets `ignore-error=true`. The broken verify was the only thing failing the job, so this is a code fix, not the infra/human action the triage guessed. ## Fix Render the index descriptor as JSON and read `.digest`: ```nu let remote = (^docker buildx imagetools inspect $ref --format "{{json .Manifest}}" | from json | get digest | str trim) ``` `{{json .Manifest}}` serializes the index descriptor (including the `digest` field), which nu parses natively and which equals the `--iidfile` digest. ## Verification Reproduced locally against a `registry:2` with a docker-container buildx build (attestation index, image-agnostic verify logic): - `--iidfile` digest: `sha256:e985...946eddc` (the index) - Old `{{.Manifest.Digest}}` -> captured `Name: localhost:5000/test:v0.4.0 ...` (full dump) -> MISMATCH - New `{{json .Manifest}} | from json | get digest` -> `sha256:e985...946eddc` -> Verified, exact match Confirmed in nu 0.112.2 (the runner shell).
fix(oci): extract index digest in verify step so attestation builds pass
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 47s
Create release / Create release from merged PR (pull_request) Has been skipped
eef5d9726c
The Verify step rendered the pushed digest with `imagetools inspect --format "{{.Manifest.Digest}}"`. The docker-container buildx driver attaches a provenance attestation by default, so every pushed ref is an OCI image index (the linux/amd64 manifest plus an unknown/unknown attestation manifest). For an index, `{{.Manifest.Digest}}` does not reduce to the digest: buildx falls back to its full human-readable dump, so the captured value never equals the `--iidfile` digest and the job fails with a spurious DIGEST MISMATCH on every main build. The publish itself succeeds (the index digest matches `--iidfile`) and the buildcache 499 is non-fatal (`cache-to` sets `ignore-error=true`); the broken verify was the only thing exiting 1. Render the index descriptor as JSON and read `.digest`, which yields the bare index digest that matches the pushed value. Reproduced locally against a registry:2 with a docker-container build: old logic captured `Name: ...` and mismatched, new logic verified the index digest sha256 exactly.

#LINKS-24

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch fix/verify-attestation-digest-LINKS-24 2026-06-09 20:37:40 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
a8n-tools/rusty-links!56
No description provided.