adorsys / adorsys/status-list-server
Image provenance is self-asserted; no third-party-verifiable issuer
- Dominant language
- Rust
- Stars
- 22
- Forks
- 5
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 47
Description
## Summary
The image published by `deploy.yml` carries a BuildKit provenance attestation (`provenance: mode=max`). That attestation is integrity-protected the OCI index digest chain covers it, so it cannot be altered without changing the image digest.
It is not authenticity-protected. The `builder.id` field pointing at the Actions run is self-asserted: it is a JSON blob BuildKit wrote, with nothing binding it to the run that allegedly produced it. Anyone with push access to the GHCR package can push an index carrying a fabricated provenance manifest that inspects identically.
**The gap is "who said this," not "was this changed."** These are easy to conflate and the
distinction is the whole ticket.
## Why this matters here
This service is an authority other systems trust. A compromise of package push access
currently escalates to a compromise of everything downstream that pulls the image, because
no consumer can distinguish an image we built from one someone else pushed with a matching
provenance claim.
## The non-obvious part
`actions/attest-build-provenance` **does not sign the BuildKit attestation.**
It generates a *second, independent* provenance document over the same image digest via
Sigstore/Fulcio. Different content, different trust properties, different verification tool
(`gh attestation verify` vs `docker buildx imagetools inspect`). Both end up attached to
one image and nothing reconciles them.
Anyone picking this up cold will assume the work is enabling a flag. It is not.
## The actual decision
1. **Keep both** — accept two provenance statements about one image, and document which one
consumers should verify and what it means if they disagree.
2. **Set `provenance: false`** and let GitHub's be the only one — this undoes the explicit
`mode=max` pinning from the supply-chain PR, whose justification was that the BuildKit
default is repo-visibility-dependent and would silently degrade to `mode=min` if the repo
were ever flipped private. That argument has to be answered, not ignored.
Also to be decided rather than discovered: the repo is public, so `attest-build-provenance`
publishes to Rekor, a public transparency log. Probably fine. Should be a choice.
## Permissions note
The supply-chain PR **removed** `id-token: write` and `attestations: write` from the build
job, because BuildKit-native `sbom:`/`provenance:` write into the registry under the existing
`packages: write` and do not need them.
This ticket **adds them back**, because `actions/attest-build-provenance` does need them.
Both are correct. Recorded here so that reading the two diffs in sequence does not look like
one of them is a mistake.
## Out of scope
- Cosign keyless signing of the image itself (distinct from attestation provenance)
- Any admission-control / policy enforcement on verification — that is a consumer-side
decision and a separate ticket again
## Acceptance criteria
- [ ] Decision recorded (option 1 or 2 above) with reasoning, as an ADR
- [ ] Rekor / public transparency log implication explicitly accepted or rejected
- [ ] `docs/supply-chain.md` states which attestation a consumer should verify, with the
exact verification command
- [ ] Permissions scoped per-job, zizmor clean
eta 2days
Contributor guide
Assessment
This issue has not been assessed yet.