feat: add OCI 1.1 Referrers API support with configurable encoding format#1691
Conversation
|
@anithapriyanatarajan: The label(s) DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
7ff8190 to
d757d46
Compare
|
@tektoncd/chains-collaborators @arewm - Please review and share your comments. Thank you |
d757d46 to
c429a7e
Compare
|
Detailed steps to test and observations are captured here for reference - https://gist.github.com/anithapriyanatarajan/b112638e7b3d78ee6638c6fec4f51bc8 Observed Gaps, which would be analyzed further with appropriate follow ups:
Registry readiness for OCI 1.1 is much critical to realize the benefit of this PR for users. |
c429a7e to
4d43d45
Compare
4d43d45 to
ee93f82
Compare
| if err != nil { | ||
| return nil, errors.Wrap(err, "attaching attestation to entity") | ||
| } | ||
| if err := ociremote.WriteAttestationsReferrer(req.Artifact, newImage, ociremote.WithRemoteOptions(s.remoteOpts...)); err != nil { |
There was a problem hiding this comment.
Just want to confirm, here we are using req.Artifact, which drops the override of repo and ignores the storage.oci.repository. Should we use the overridden repo instead?
|
More details on why we are doing this change - sigstore/docs#411 & kubernetes-sigs/tejolote#639 |
|
@anithapriyanatarajan |
|
@anithapriyanatarajan can you add e2e tests ? |
ee93f82 to
904528b
Compare
@jkhelil - Yes, storage.oci.format=referrers-api can be safely configured without knowing the registry's OCI 1.1 support status. The fallback to the Referrers Tag Schema is handled automatically by go-containerregistry (the underlying library used by cosign and vendored in Chains). If the registry natively supports the Referrers API (e.g., Quay), it is used directly. If not, go-containerregistry automatically falls back to storing referrers as an OCI Image Index tag, per the OCI distribution spec mandate (spec lines 777–806). Since this fallback is transparent at the library level, Chains does not need to implement its own fallback logic, and users do not need to manually revert to the legacy storage format based on registry capability. I have verified this behavior with quay and ghcr. For quay it takes the referrers API path while for ghcr it takes the referrers tag path. Will share evidences after fixing a few other findings. Thank you |
904528b to
78d47da
Compare
78d47da to
276c83e
Compare
f1937ed to
8a74fdb
Compare
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: arewm, jkhelil The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/hold until sigstore/cosign#4997 (comment) is resolved |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1691 +/- ##
==========================================
- Coverage 61.96% 61.93% -0.03%
==========================================
Files 64 64
Lines 3899 4067 +168
==========================================
+ Hits 2416 2519 +103
- Misses 1222 1266 +44
- Partials 261 282 +21
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
195e676 to
4187a96
Compare
|
/hold cancel |
There was a problem hiding this comment.
Pull request overview
Adds a single OCI storage configuration knob to switch Chains between the existing tag-based .sig/.att layout and OCI 1.1 Referrers-based storage using Sigstore protobuf bundles, enabling referrer-native registries to avoid signature/attestation tag proliferation while preserving backward-compatible defaults.
Changes:
- Introduces
storage.oci.encoding-format(dssedefault,sigstore-bundle) with validation + defaults in config parsing. - Implements
sigstore-bundlestorage paths for OCI signatures/attestations using referrers + protobuf bundle writing, including referrer deduplication. - Adds unit + e2e coverage and documentation for the new encoding/storage behavior; bumps vendored cosign to
v2.6.4.
Reviewed changes
Copilot reviewed 17 out of 21 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| vendor/modules.txt | Updates vendored module listing for cosign version bump. |
| vendor/github.com/sigstore/cosign/v2/pkg/oci/remote/write.go | Vendored cosign changes related to referrer manifest handling. |
| vendor/github.com/sigstore/cosign/v2/pkg/cosign/fetch.go | Vendored cosign behavior change when no attestations are present. |
| go.mod | Bumps github.com/sigstore/cosign/v2 to v2.6.4 and makes protobuf-specs a direct dependency. |
| go.sum | Updates sums for the cosign bump. |
| pkg/config/config.go | Adds storage.oci.encoding-format key, constants, defaulting, and validation. |
| pkg/config/config_test.go | Tests default/valid/invalid encoding-format config values and validator behavior. |
| pkg/config/store_test.go | Updates config parsing expectations to include the new default OCI encoding format. |
| pkg/config/options.go | Extends storage options with PublicKey and raw Rekor entry fields for bundle construction. |
| pkg/chains/signing/iface.go | Extends signing.Bundle to carry PublicKey and raw Rekor entry for downstream storage. |
| pkg/chains/signing.go | Captures Rekor entry + signer public key (non-fatal) and threads them into StorageOpts. |
| pkg/chains/storage/oci/options.go | Adds WithEncodingFormat and helper for referrers repo override behavior. |
| pkg/chains/storage/oci/legacy.go | Threads encoding format + bundle-related fields into signature/attestation upload logic. |
| pkg/chains/storage/oci/simple.go | Implements sigstore-bundle signature storage via referrers + protobuf bundle (with dedup). |
| pkg/chains/storage/oci/simple_test.go | Adds unit tests for sigstore-bundle signature referrer writes, repo override behavior, and dedup. |
| pkg/chains/storage/oci/attestation.go | Implements sigstore-bundle attestation storage via referrers + protobuf bundle (with dedup). |
| pkg/chains/storage/oci/attestation_test.go | Adds unit tests for sigstore-bundle attestation referrer writes and dedup. |
| pkg/chains/storage/oci/oci_test.go | Adds tests for WithEncodingFormat, default behavior, backend config wiring, and payload preservation regression. |
| test/oci_sigstore_bundle_e2e_test.go | Adds e2e coverage ensuring .sig/.att tags are not created in sigstore-bundle mode. |
| docs/oci-encoding-format.md | New doc explaining encoding-format behavior, referrers layout, compatibility, and verification. |
| docs/config.md | Documents the new storage.oci.encoding-format config key and links to the new doc. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
4187a96 to
91193f7
Compare
9f92193 to
295461d
Compare
… format Adds a new storage.oci.encoding-format config key that controls both the serialization format and distribution mechanism for OCI artifacts: storage.oci.encoding-format: dsse (default) | sigstore-bundle - dsse: unchanged tag-based storage with DSSE envelopes (default) - sigstore-bundle: Sigstore protobuf bundle via OCI 1.1 Referrers API, eliminating sha256-*.sig / *.att tag proliferation in the registry Both signatures and attestations are stored as application/vnd.dev.sigstore.bundle.v0.3+json referrer manifests, distinguished by the dev.sigstore.bundle.predicateType annotation. Signatures use CosignSignPredicateType; attestations use the in-toto predicate type. This matches the manifest layout produced by cosign 3.x `cosign sign` and `cosign attest`. Also fixes a bug where the raw Rekor transparency log entry was never forwarded to MakeNewBundle in the sigstore-bundle attestation path. The entry was converted to a RekorBundle in signing.go and then discarded; the OCI attestation storer always passed a nil rekorEntry to MakeNewBundle, so bundles shipped without a tlog entry and would be rejected by cosign verify-attestation (which checks for one by default since v2). Fixed by carrying *models.LogEntryAnon through StorageOpts and signing.Bundle to the storer. Bumps cosign from v2.6.3 to v2.6.4 to include: - PR #4997: correct artifactType in OCI 1.1 signature referrer manifests - PR #4996: cosign download attestation now returns bundle-format referrers alongside legacy .att tag attestations Signed-off-by: Anitha Natarajan <anataraj@redhat.com> Assisted-by: Claude Sonnet 4.6 (via GitHub Copilot)
295461d to
18342c4
Compare
|
/lgtm |
|
Test prompt used for this PR : pr1691-test-prompt.md |
NOTE TO REVIEWERS: Originally this PR intended to allow a user-configurable approach for both distribution and serialization. During later review and iterative testing it became clear this adds needless complexity for users, and we additionally discovered via sigstore/cosign#4841 that the
sigstore-bundle+ DSSE combination is not supported in cosign. The PR therefore distills to two simple scenarios behind a single config knob, summarized below.Changes
Chains currently stores all OCI signatures and attestations using a tag-based scheme (
sha256-<digest>.sig/.att). This creates extra tags in the registry for every signed artifact. This PR adds support for the OCI 1.1 Referrers API as an alternative storage mechanism.New configuration key
A single new key controls both the serialization format and the distribution mechanism. They are intentionally coupled — not separately configurable:
storage.oci.encoding-formatdsse,sigstore-bundledssePossible Scenarios:
encoding-formatdsse.sig/.atttags) — unchanged defaultsigstore-bundle.sig/.atttagsdsse+ protobuf-bundle andsigstore-bundle+ DSSE are intentionally not offered: cosign's verification for referrer-stored attestations expects the protobuf bundle, andsigstore-bundleexists precisely to move away from the legacy tag layout, which has downsides:This keeps the surface to one knob and avoids a confusing matrix of combinations, some of which no tool can verify.
Backward compatibility
All existing deployments with no OCI encoding format config set continue to behave identically (
dsse+ tag-based). No action required.Implementation
config.go—OCIStorageConfiggains anEncodingFormatfield; new constants (OCIEncodingFormatDSSE,OCIEncodingFormatSigstoreBundle) and avalidateOCIEncodingFormatvalidator. Defaults todssewhen unset.options.go— NewWithEncodingFormat()option function; houses thereferrersRepoOverrideIgnoredhelper.attestation.go/simple.go— Dispatch keys offencodingFormat;sigstore-bundlewrites attestations as a protobuf bundle viaociremote.WriteAttestationNewBundleFormat, while signatures use cosign's native signature referrer.legacy.go— Backend passesWithEncodingFormatwhen constructing storers.signing.go/signing/iface.go—signing.BundleandStorageOptsgain aPublicKey crypto.PublicKeyfield;PublicKey()extraction after signing is non-fatal (logs a warning, storage continues) so KMS signers don't break the default path. Also wires up Rekor bundle population before storage so the bundle annotation is available for offline verification.Tests
config_test.go— Tests the default, valid/invalid values forencoding-format, and thevalidateOCIEncodingFormatvalidator.oci_test.go— TestsWithEncodingFormat, empty defaults, the Backend config, and thatstorage.oci.repositoryoverride is ignored insigstore-bundlemode.store_test.go— UpdateddefaultStorageto reflect the struct field rename.attestation_test.go/simple_test.go— Tests for thesigstore-bundlestore path including dedup.referrers_api_e2e_test.go(new) — E2E tests forTestOCIStorageSigstoreBundle_TaskRunandTestOCIStorageSigstoreBundle_PipelineRun.Docs
oci-artifact-distribution-format-referrers-schema.md(new) — Tutorial-style page explaining the Referrers schema, how cosign and Chains enable it, why referrers + protobuf bundle (not DSSE), registry compatibility, and verification examples.config.md— Newstorage.oci.encoding-formatrow in the storage configuration table.Submitter Checklist
As the author of this PR, please check off the items in this checklist:
Release Notes
/kind feature
Co-Authored-by: Copilot (Claude Sonnet 4.6)