1
0
mirror of synced 2026-10-24 12:59:22 +03:00

707 Commits

Author SHA1 Message Date
Manuel Rüger
0433f847df Move bundle metadata types into a dependency-free package (#5180)
pkg/oci imported pkg/cosign/bundle only for RekorBundle,
RekorPayload, RFC3161Timestamp and BundleV03MediaType. That package
also contains SignData, which imports sigstore-go's sign and root
packages, so every consumer of pkg/oci linked the signing stack.

Move these types and the media type constant into the new leaf
package pkg/cosign/bundle/types and import that from pkg/oci.
pkg/cosign/bundle keeps type aliases, so its API is unchanged.

The base pkg/oci package goes from 86 to 2 transitive modules. For
ko, which uses pkg/oci, pkg/oci/mutate, pkg/oci/walk and
pkg/oci/remote, the binary goes from 161 to 146 modules.

Signed-off-by: Manuel Rüger <manuel@rueg.eu>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 13:15:46 -07:00
Carlos Tadeu Panato Junior
f8e6ea940d Add cosign-specific user-agent to all HTTP requests (#4705)
* Add cosign-specific user-agent to all HTTP requests

This change addresses issue #4692 by ensuring that all HTTP requests
made by cosign identify with a proper user-agent that includes both
the cosign version and sigstore-go version.

Signed-off-by: Carlos Panato <ctadeu@gmail.com>

* Scope sigstore-go user-agent to sigstore-go code paths

Keep the global user-agent as cosign/<version> (os; arch) and only
send cosign/<version> sigstore-go/<version> (os; arch) on requests
made through sigstore-go. Fulcio and TSA clients built in SignData
now use a transport that overrides sigstore-go's default user-agent.

Rekor requests made via sigstore-go still use sigstore-go's
user-agent until sigstore-go exposes a way to set it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Carlos Panato <ctadeu@gmail.com>

* Set cosign user-agent on sigstore-go Fulcio, TSA and Rekor clients

Bump sigstore-go to main to pick up sigstore/sigstore-go#686, which
adds a UserAgent option and always appends sigstore-go/<version>.
Pass cosign's user-agent through it and drop the transport wrapper
and the sigstore-go version lookup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Carlos Panato <ctadeu@gmail.com>

---------

Signed-off-by: Carlos Panato <ctadeu@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 11:37:45 -07:00
Ashvin
6a83f9a208 fix(verify): don't panic on a bundle entry with no hash (#5127)
* fix(verify): don't panic on a bundle entry with no hash

bundleHash dereferenced the algorithm and value of a Rekor entry hash
without checking them. The hash is optional in all five of these schemas,
and unmarshalling does not always populate it: a rekord v0.0.1 entry that
carries data.content but no data.hash, and an intoto v0.0.2 entry whose
envelope payload is empty, both unmarshal cleanly with a nil hash.

The body comes from the bundle attached to the signature, so it is read
from the registry before the certificate has been validated and before
the signature has been checked. A body that omits the hash therefore
crashes the verifier rather than failing verification.

Check each level before dereferencing it and return an error instead.

Signed-off-by: ashvinctrl <sharmaashvin27@gmail.com>

* fix(verify): trim comments in bundleHash

Drop the hashFields doc comment and cut the bundleHash comment down to the
part that is not visible from the code: the Rekor models mark the hash fields
required, but per-type validation does not always enforce it.

Signed-off-by: ashvinctrl <sharmaashvin27@gmail.com>

* test(verify): cover every bundleHash entry type and hashFields

Add success cases for all five entry types, missing-hash cases for each
type (including partial hash objects, which Rekor rejects before the
switch), and a direct test of hashFields for a nil algorithm or value.

Signed-off-by: ashvinctrl <sharmaashvin27@gmail.com>

---------

Signed-off-by: ashvinctrl <sharmaashvin27@gmail.com>
2026-10-02 10:42:03 -07:00
Aaron Lew
f624836219 test(verify): add failure cases for new bundle verification
Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-09-29 10:27:56 -07:00
Hayden
4961ad02d1 Rename crypto11 module path (#5135)
The project has been donated to the Eclipse Foundation.
See https://github.com/eclipse-keypont/crypto11/releases/tag/v1.6.8

Fixes #5134

Signed-off-by: Hayden <8418760+Hayden-IO@users.noreply.github.com>
2026-09-24 11:39:10 -07:00
Chiman Jain
f9285f2d29 chore(deps): upgrade gitlab-org/api/client-go to v3 (#5133)
* chore(deps): upgrade gitlab-org/api/client-go to v3

Signed-off-by: Chiman Jain <chimanjain15@gmail.com>

* chore(deps): fix staticcheck issues

Signed-off-by: Chiman Jain <chimanjain15@gmail.com>

---------

Signed-off-by: Chiman Jain <chimanjain15@gmail.com>
2026-09-24 07:58:14 -04:00
Aaron Lew
67a1216d73 fix: write referrers when image index has attestations (#5111)
Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-09-18 16:24:31 -04:00
Ali Asghar
43d83e8490 fix(layout): preserve manifest artifactType in index.json when saving (#4821)
When cosign save writes an OCI artifact to disk, partial.Descriptor falls
back to config.mediaType as the artifactType in the index.json descriptor
because go-containerregistry's v1.Manifest struct does not expose the
manifest-level artifactType field. The result is that config.mediaType
appears as the artifactType entry in index.json instead of the correct
manifest artifactType, violating the OCI Image Layout spec.

Fix appendImage to parse the raw manifest JSON and override the descriptor's
ArtifactType field when a top-level artifactType is present. The existing
config.mediaType fallback still applies when artifactType is absent.

Fixes #4694

Signed-off-by: Ali <alliasgher123@gmail.com>
2026-09-14 16:24:02 -07:00
Geoffrey Hichborn
1dbbc36ca4 fix(load): upload bundle layer blobs before manifest PUT
cosign load was putting v3 Sigstore bundle manifests before their layer
blobs, causing BLOB_UPLOAD_UNKNOWN on registries that enforce blob-first
ordering (e.g. AWS ECR). Reorder to match WriteReferrer.

Add a unit test for upload ordering and a cross-registry e2e whose
destination rejects manifests that reference missing blobs, so the
regression is not masked by the permissive fake registry.

Fixes #5030

Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Geoffrey Hichborn <geoff@yourparadigm.net>
2026-09-14 16:14:40 -07:00
Tommy
b327bba1f0 fix: clarify COSIGN_REPOSITORY error when repository path is missing
COSIGN_REPOSITORY expects a full repository (registry + path), not just
a registry. When a bare registry like "registry.example.com:5000" is
given, name.NewRepository() has no '/' to split on, treats the whole
value as a repository name, and rejects it with a confusing "can only
contain the characters ..." error that looks like a parsing bug rather
than a missing path component.

Detect this case and return an actionable error message pointing out
that COSIGN_REPOSITORY needs a repository path.

Fixes #3029

Signed-off-by: Tommy <tommy@bejara.net>
2026-09-14 15:53:08 -07:00
Pujitha Paladugu
3532c1d092 fix: include annotations in implied payload for offline verify
Motivation:
When signing with `cosign sign --upload=false -a key=value
--output-signature=sig.file`, cosign builds the signed payload from
payload.Cosign{Image, ClaimedIdentity, Annotations} including the
annotations (cmd/cosign/cli/sign/sign.go). When later verifying
offline with `cosign verify -a key=value --signature sig.file` and no
explicit `--payload`, cosign reconstructs an "implied" payload via
ObsoletePayload to compare against the signature, but that
reconstruction dropped annotations entirely. The reconstructed payload
therefore never matched the payload that was actually signed, so
verification always failed with "crypto/rsa: verification error" (or
equivalent) any time annotations were used with offline signing.

Approach:
Thread the caller-supplied annotations through ObsoletePayload so the
implied payload it builds matches what was used at signing time. The
verify call site (pkg/cosign/verify.go) now passes co.Annotations,
which is populated from the `-a` flag. The attach-signature call site
(cmd/cosign/cli/attach/sig.go) has no annotations flag, so it passes
nil, preserving its existing behavior exactly.

This is a pure payload-construction/serialization fix with no
dependency on registry, network, or transparency-log state: the
default (no-annotations) case is byte-for-byte unchanged.

Validation:
- go build ./...
- go test ./pkg/cosign/... ./cmd/cosign/cli/attach/... ./cmd/cosign/cli/verify/...
- go test $(go list ./... | grep -v third_party/)
  All pass. Added TestObsoletePayloadWithAnnotations in
  pkg/cosign/obsolete_test.go, which fails to compile against the
  pre-fix ObsoletePayload signature and asserts the annotation now
  appears in the marshaled payload's "optional" field once the fix is
  applied; confirmed by temporarily reverting the source changes and
  observing the test target fail to build.

Report: https://github.com/sigstore/cosign/issues/4024
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
2026-09-14 15:14:58 -07:00
Arpit Jain
b84a076464 Cap the bundle layer read in ociremote.Bundle
Bundle() decompressed the new-bundle-format attestation layer and read all of
it into memory with no size check, while every other layer read in pkg/oci
calls payloadsize.CheckSize first. A registry the user does not control could
make cosign verify-attestation --new-bundle-format allocate without bound from
a small compressed layer.

The size a registry declares is the compressed size, and this is the only one
of these reads that goes through Uncompressed(), so checking that size is
necessary but not sufficient. This does both: the declared size is checked
first so an oversized layer is rejected before anything is read, and the
decompressed stream is then bounded by the same limit.

GetBundles calls Bundle() for every manifest in a referrers index and swallows
the error with continue, since non-Sigstore referrers are expected there, so
without the second check each oversized layer in an index was read in full
before its error was reached.

MaxSize is exported from the payload size package because a caller reading a
decompressed stream needs the limit itself rather than a yes or no answer
about a size it already knows.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
2026-09-14 13:10:15 -07:00
dependabot[bot]
633e8f4303 chore(deps): bump the gomod group across 1 directory with 17 updates (#5104)
* chore(deps): bump the gomod group across 1 directory with 17 updates

Bumps the gomod group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [cuelang.org/go](https://github.com/cue-lang/cue) | `0.17.0` | `0.17.1` |
| [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) | `4.1.4` | `4.1.5` |
| [github.com/go-openapi/runtime](https://github.com/go-openapi/runtime) | `0.33.0` | `0.33.2` |
| [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) | `1.20.1` | `1.20.2` |
| [github.com/secure-systems-lab/go-securesystemslib](https://github.com/secure-systems-lab/go-securesystemslib) | `0.11.0` | `0.11.1` |
| [github.com/sigstore/protobuf-specs](https://github.com/sigstore/protobuf-specs) | `0.5.1` | `0.5.2` |
| [github.com/sigstore/rekor](https://github.com/sigstore/rekor) | `1.5.3` | `1.5.4` |



Updates `cuelang.org/go` from 0.17.0 to 0.17.1
- [Release notes](https://github.com/cue-lang/cue/releases)
- [Commits](https://github.com/cue-lang/cue/compare/v0.17.0...v0.17.1)

Updates `github.com/go-jose/go-jose/v4` from 4.1.4 to 4.1.5
- [Release notes](https://github.com/go-jose/go-jose/releases)
- [Commits](https://github.com/go-jose/go-jose/compare/v4.1.4...v4.1.5)

Updates `github.com/go-openapi/runtime` from 0.33.0 to 0.33.2
- [Release notes](https://github.com/go-openapi/runtime/releases)
- [Commits](https://github.com/go-openapi/runtime/compare/v0.33.0...v0.33.2)

Updates `github.com/go-openapi/strfmt` from 0.27.0 to 0.27.1
- [Release notes](https://github.com/go-openapi/strfmt/releases)
- [Commits](https://github.com/go-openapi/strfmt/compare/v0.27.0...v0.27.1)

Updates `github.com/go-openapi/swag/conv` from 0.27.3 to 0.29.1
- [Release notes](https://github.com/go-openapi/swag/releases)
- [Commits](https://github.com/go-openapi/swag/compare/v0.27.3...v0.29.1)

Updates `github.com/open-policy-agent/opa` from 1.20.1 to 1.20.2
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-policy-agent/opa/compare/v1.20.1...v1.20.2)

Updates `github.com/secure-systems-lab/go-securesystemslib` from 0.11.0 to 0.11.1
- [Release notes](https://github.com/secure-systems-lab/go-securesystemslib/releases)
- [Commits](https://github.com/secure-systems-lab/go-securesystemslib/compare/v0.11.0...v0.11.1)

Updates `github.com/sigstore/protobuf-specs` from 0.5.1 to 0.5.2
- [Changelog](https://github.com/sigstore/protobuf-specs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sigstore/protobuf-specs/compare/v0.5.1...v0.5.2)

Updates `github.com/sigstore/rekor` from 1.5.3 to 1.5.4
- [Release notes](https://github.com/sigstore/rekor/releases)
- [Changelog](https://github.com/sigstore/rekor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sigstore/rekor/compare/v1.5.3...v1.5.4)

Updates `github.com/sigstore/sigstore` from 1.10.8 to 1.10.9
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.10.8...v1.10.9)

Updates `github.com/sigstore/sigstore/pkg/signature/kms/aws` from 1.10.8 to 1.10.9
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.10.8...v1.10.9)

Updates `github.com/sigstore/sigstore/pkg/signature/kms/azure` from 1.10.8 to 1.10.9
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.10.8...v1.10.9)

Updates `github.com/sigstore/sigstore/pkg/signature/kms/gcp` from 1.10.8 to 1.10.9
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.10.8...v1.10.9)

Updates `github.com/sigstore/sigstore/pkg/signature/kms/hashivault` from 1.10.8 to 1.10.9
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.10.8...v1.10.9)

Updates `github.com/stretchr/testify` from 1.11.1 to 1.12.1
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.11.1...v1.12.1)

Updates `google.golang.org/api` from 0.284.0 to 0.290.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.284.0...v0.290.0)

Updates `google.golang.org/protobuf` from 1.36.12-0.20260120151049-f2248ac996af to 1.36.12

---
updated-dependencies:
- dependency-name: cuelang.org/go
  dependency-version: 0.17.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/go-jose/go-jose/v4
  dependency-version: 4.1.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/go-openapi/runtime
  dependency-version: 0.33.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/go-openapi/strfmt
  dependency-version: 0.27.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/go-openapi/swag/conv
  dependency-version: 0.29.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: gomod
- dependency-name: github.com/open-policy-agent/opa
  dependency-version: 1.20.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/secure-systems-lab/go-securesystemslib
  dependency-version: 0.11.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/sigstore/protobuf-specs
  dependency-version: 0.5.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/sigstore/rekor
  dependency-version: 1.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/sigstore/sigstore
  dependency-version: 1.10.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/sigstore/sigstore/pkg/signature/kms/aws
  dependency-version: 1.10.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/sigstore/sigstore/pkg/signature/kms/azure
  dependency-version: 1.10.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/sigstore/sigstore/pkg/signature/kms/gcp
  dependency-version: 1.10.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/sigstore/sigstore/pkg/signature/kms/hashivault
  dependency-version: 1.10.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.12.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: gomod
- dependency-name: google.golang.org/api
  dependency-version: 0.290.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: gomod
- dependency-name: google.golang.org/protobuf
  dependency-version: 1.36.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gomod
...

Signed-off-by: dependabot[bot] <support@github.com>

* update mock interface

Signed-off-by: Bob Callaway <bcallaway@google.com>

* fix linter errors

Signed-off-by: Bob Callaway <bcallaway@google.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Bob Callaway <bcallaway@google.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bob Callaway <bcallaway@google.com>
2026-09-08 15:36:42 -04:00
dependabot[bot]
b918f9d67c chore(deps): bump the all group across 1 directory with 2 updates (#5067)
* chore(deps): bump the all group across 1 directory with 2 updates

Bumps the all group with 2 updates in the / directory: golang and golangci/golangci-lint.


Updates `golang` from 1.26.5 to 1.27.0

Updates `golangci/golangci-lint` from v2.12.2 to v2.13.1

---
updated-dependencies:
- dependency-name: golang
  dependency-version: 1.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
- dependency-name: golangci/golangci-lint
  dependency-version: v2.13.1
  dependency-type: direct:production
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>

* address lints

Signed-off-by: Bob Callaway <bcallaway@google.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Bob Callaway <bcallaway@google.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bob Callaway <bcallaway@google.com>
2026-09-08 13:33:49 +00:00
Bob Callaway
559c58cffc copy annotations by key instead of copying obj (#5103)
Signed-off-by: Bob Callaway <bcallaway@google.com>
2026-09-08 08:12:40 -04:00
Ralph Bean
37cf1bc499 Add org.opencontainers.image.title annotation to attestation layers (#4498)
Add the org.opencontainers.image.title annotation to layer descriptors
in attestation manifests to enable tools like 'oras pull' to download
attestation bundles with meaningful, collision-free filenames.

The annotation format is {algorithm}-{hex}.sigstore.json where the
hyphen separator ensures cross-platform filename compatibility,
particularly for Windows which forbids colons in filenames.

Changes:
- Add Annotations field to layer descriptors in WriteReferrer
- Update tests to verify annotation is set correctly
- Document the optional layer annotation in BUNDLE_SPEC.md

Fixes #4497

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Ralph Bean <rbean@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-09-06 09:01:18 -04:00
Aaron Lew
3684926c30 test: remove redundant TUF fetch in TestValidateAndUnpackCertWithSCT (#5097)
Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-09-06 08:49:29 -04:00
Aaron Lew
6785e0e3b4 test: isolate TUF cache in TestGetCTLogPubKeys (#5096)
Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-09-06 08:48:56 -04:00
Aaron Lew
20c751629b fix(verify): support image indexes in local bundle discovery (#5080)
Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-09-03 10:28:06 -04:00
Eugene Kalinin
e9af93ff29 fix(providers): clearer errors when GitHub OIDC token request fails (#5062)
The GitHub Actions provider decoded the response body without checking the
status code, so a failing OIDC endpoint surfaced as a raw json error:

  fetching ambient OIDC credentials: invalid character 'u' looking for
  beginning of value

Check the status code first and report it along with a truncated body, and
wrap decode failures with the provider name:

  fetching ambient OIDC credentials: identity token request to provider
  github-actions failed with status 502 Bad Gateway: "upstream connect
  error or disconnect/reset before headers"

Fixes #4438

Signed-off-by: Eugene Kalinin <e.v.kalinin@gmail.com>
2026-08-18 09:09:02 -07:00
Chiman Jain
b2c119a5d2 chore(deps): upgrade gitlab-org/api/client-go to v2 (#5050)
Signed-off-by: Chiman Jain <chimanjain15@gmail.com>
2026-08-11 02:33:53 +00:00
Sergey Sannikov
4d589ba37b fix(blob): compare file checksums case-insensitively (#5036)
* Compare file checksums case-insensitively

Hex digests are case-insensitive, and vendors frequently publish them in
upper case. LoadFileOrURLWithChecksum compared the computed digest --
always lower case, as hex.EncodeToString emits it -- against the
user-supplied value with a plain string comparison, so a correct
upper-case checksum was reported as incorrect.

The only caller is 'cosign initialize --root-checksum', which verifies
the TUF root of trust, so the workaround a user is most likely to reach
for is --force-skip-checksum-validation.

Signed-off-by: Sergey Sannikov <sergey@sannikov.dev>

* Compare the decoded digests instead of their hex spellings

Per review: decoding the given checksum and comparing bytes removes the
case question entirely, and a value that is not valid hex cannot decode
to the digest either, so the existing behaviour for malformed input is
unchanged.

Signed-off-by: Sergey Sannikov <sergey@sannikov.dev>

---------

Signed-off-by: Sergey Sannikov <sergey@sannikov.dev>
2026-08-05 23:34:31 +00:00
Kenneth
d6d86c224e Supporting OCI Signing with X.509 Certificate Chain (#4614)
* Adding BYOCA Certificate Chain Option for Signing and Verification

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

* Temporary Reference to Uncommited sigstore-go Updates

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

* Update sigstore-go v1.2.2

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

* Update Copyright Date

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

* Certificate Chain Support for Verify Blob and E2E Tests

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

* Update Unit Tests for sigstore-go v1.2.2 Changes

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

* Update localCertChainProvider to Skip Self-Signed Certificate

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

* Fix Unit Test for Legacy Signing to Include Self-Signed Root

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>

---------

Signed-off-by: Kenneth Yang <kenneth.yang@coinbase.com>
2026-07-24 11:31:58 -07:00
Pujitha Paladugu
a3ee83c6e0 fix(pkcs11key): return an error instead of panicking when no key pair matches (#5022)
* fix(pkcs11key): return an error instead of panicking when no key pair matches

Motivation:
crypto11.FindKeyPair (github.com/ThalesIgnite/crypto11@v1.2.5, keys.go:240-244)
returns (nil, nil) — no error — when no key pair on the PKCS#11 token matches
the configured key id/label (e.g. wrong slot, wrong object name, a HSM/driver
that behaves differently across platforms). GetKeyWithURIConfig did not check
for this, so it happily returned a *Key with a nil signer. Any caller that
then invokes PublicKey(), Sign(), SignMessage(), or VerifySignature() directly
on that Key hits a nil pointer dereference: exactly the panic reported in
#4540 at pkcs11key.go:199 (`k.signer.Public()`), by two independent users
signing against real PKCS#11 tokens/HSMs.

The package already guards against a nil signer in Verifier()/SignerVerifier()
(present since the original PKCS11 support commit in 2021), and cosign's two
callers of GetKeyWithURIConfig (pkg/signature/keys.go) do route through those
methods before returning a usable signer/verifier. This change closes the gap
at the source — GetKeyWithURIConfig itself — so a Key can never be handed out
with a nil signer in the first place. This is a stricter, single-point
guarantee than the two narrower existing checks, and protects any current or
future caller of the exported pkcs11key API that doesn't happen to go through
Verifier()/SignerVerifier() first.

This is a correctness/UX fix, not a security issue: no auth bypass or data
corruption is involved, and cosign is a one-shot CLI so a panic and a returned
error both terminate the process with a non-zero exit code either way. The
concrete improvement is a clear, actionable error message ("signer not set:
no key pair found for id=... label=... in slot/token") instead of a Go panic
and stack trace.

Approach:
Add a nil check right after the FindKeyPair calls in GetKeyWithURIConfig,
returning a descriptive error that wraps the existing SignerNotSet sentinel
(reusing the same idiom already used in Verifier()/SignerVerifier()). The
sentinel errors and the new error-construction helper are extracted into a
new untagged pkg/cosign/pkcs11key/errors.go so they, and a unit test for the
helper, can run without the CGO/hardware-dependent pkcs11key build tag.

Validation:
- go build ./...
- go test ./pkg/cosign/pkcs11key/... -v            (untagged, runs in default CI)
- CGO_ENABLED=1 go build -tags=pkcs11key,pivkey ./...
- CGO_ENABLED=1 go test -tags=pkcs11key ./pkg/cosign/pkcs11key/... -v
- go vet ./pkg/cosign/pkcs11key/... (both with and without -tags=pkcs11key)
- gofmt -l pkg/cosign/pkcs11key/
All of the above pass. Full end-to-end validation against a real/simulated
PKCS#11 token (SoftHSMv2) was not possible in this sandbox, consistent with
this repo's own e2e test (test/pkcs11_test.go) being gated behind an
additional "softhsm" build tag requiring SoftHSMv2 to be installed locally.

Fixes #4540

Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>

* fix(pkcs11key): inline signer-not-found error, drop helper+test per review

Hayden-IO requested inlining the error message directly at the call
site instead of extracting it into a separate helper with its own
unit test, since it's just an error string. Moves the sentinel error
vars back into pkcs11key.go and removes errors.go and the test file.

Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>

---------

Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Co-authored-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
2026-07-21 09:03:15 -07:00
Aaron Lew
d6857f227c Auto-detect default digest algorithm for public keys (#5019)
This change updates public key verifier loaders to automatically detect the digest algorithm for a given public key.

This renders the deprecated --signature-digest-algorithm (to be removed in #4959) redundant.

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-07-20 09:52:04 -07:00
Aaron Lew
193d215343 Remove unused policy evaluation code (#4936)
* Remove unused policy evaluation package and associated fuzz tests

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused ValidateJSONWithModuleInput helper from rego package

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

---------

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-07-17 10:32:20 -04:00
Arpit Jain
eb3bb86f71 Guard against empty certificate PEM in mutate.Signature (#4998)
LoadCertificatesFromPEM returns (nil, nil) for an empty or
whitespace-only PEM, so mutate.Signature then panics on certs[0]
(reachable via `cosign attach signature --certificate <empty-file>`).

PR #4760 fixed the same LoadCertificatesFromPEM-returns-empty case on
the read path (pkg/oci/internal/signature/layer.go) with a len(certs)==0
check; this applies the same guard to the write/attach path so an empty
certificate returns a clear error instead of panicking. Added a test.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
2026-07-17 10:30:00 -04:00
Aaron Lew
089731c31f fix(download): Validate predicate type for new bundle format
Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-07-16 11:26:50 -07:00
Arpit Jain
d996ce12df Skip nil subject entries in IntotoSubjectClaimVerifier (#5016)
* Skip nil subject entries in IntotoSubjectClaimVerifier

An in-toto statement whose subject array contains a null entry makes
IntotoSubjectClaimVerifier panic with a nil pointer dereference at the
subj.Digest lookup.

Statement.UnmarshalJSON first tries protojson, and falls back to
encoding/json when the predicate is a string rather than an object.
On that fallback path encoding/json decodes a JSON null in the subject
array into a nil *ResourceDescriptor, which the loop then dereferences.

Skip nil entries so a crafted attestation gets the usual "no matching
subject digest found" error instead of crashing the client. The claim
verifier runs after signature verification, so this needs a validly
signed attestation (an attacker can sign their own with their own
Fulcio cert and serve it from an image they control); it is a
robustness fix, not a verification bypass.

Adds a regression case to Test_IntotoSubjectClaimVerifier.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>

* Return an error on a null in-toto subject entry

Per review: a null subject is an invalid statement per the in-toto v1 spec, so error instead of skipping it. Also drop the two comments the reviewer flagged as unnecessary.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>

---------

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
2026-07-16 09:41:27 -04:00
Anitha Natarajan
aebdc3a232 fix: include artifactType in OCI 1.1 signature referrer manifest
Signed-off-by: Anitha Natarajan <anataraj@redhat.com>
2026-07-10 14:10:04 -07:00
Zach Steindler
c0edaac063 Allow attestation download to handle both bundle types (#4996)
* Allow attestation download to handle both bundle types.

As suggested on https://github.com/sigstore/cosign/issues/4573

Signed-off-by: Zach Steindler <steiza@github.com>

* Do not error out if no old attestations are found to download

Signed-off-by: Zach Steindler <steiza@github.com>

* Update e2e test to actually check download attestation output

Signed-off-by: Zach Steindler <steiza@github.com>

---------

Signed-off-by: Zach Steindler <steiza@github.com>
2026-07-09 16:05:29 -04:00
Aaron Lew
0fc9811059 Remove unused signing code (#4918)
* Remove unused signcommon code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused Rekor code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused Fulcio code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused tlog code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused attestation code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused bundle code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused TSA code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Replace legacy signers with static.NewSignature in verify test

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Replace tsa.GetTimestampedSignature with new helpers in verify tests

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused signer wrapper implementations

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Replace tsa.SplitPEMCertificateChain with existing helper in verify test

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused exported SplitPEMCertificateChain TSA util

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Replace bundle.MakeProtobufBundle with proto in verify_blob_* tests

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Move BundleV03MediaType constant to new constants file

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Remove unused protobundle code

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

* Update go.mod and go.sum

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>

---------

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-06-12 07:57:20 -04:00
Aaron Lew
95dceda0e7 Remove unused OCI code (#4935)
Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-06-12 07:56:32 -04:00
Cody Soyland
6115844a09 Update sigstore-go to v1.2.0 (#4914)
* Update sigstore-go to v1.2.0

sigstore-go v1.2.0 encodes DSSE envelopes as hashedrekord entries
on Rekor v2. Bump conformance action to v0.0.29 and remove the
message-digest-mismatch xfail, which now passes. Fix e2e and unit
tests for updated transitive dependencies (timestamp-authority
v2.1.2 requires default-policy-oid config; tlog entry body parsing
now requires a valid Rekor v1 or v2 body).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* fix(ci): plug DSSE bundle reader leak and use --allow-http-registry

Two fixes for the Rekor v2 / sigstore-go v1.2.0 attestation path:

- oci/remote.Bundle never closed the reader returned by Uncompressed(),
  leaking a slot in go-containerregistry's pull limiter. Repeated calls
  (e.g. GetBundles walking multiple attestations) exhaust the limiter and
  block forever, hanging TestSignVerifyBundle and the vuln
  verify-attestation e2e step.

- go-containerregistry v0.21.6 narrowed the local registry regex from
  `.local` to `.localhost`, so `registry.local:5000` is no longer
  auto-detected as HTTP. Use the correct `--allow-http-registry` flag.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

---------

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-05 13:56:34 -04:00
Cody Soyland
0008f0ecd5 fix(verify): copy CheckOpts inside VerifyNewBundle to fix data race (#4917)
verifyImageAttestationsSigstoreBundle fans out one goroutine per bundle
sharing a single *CheckOpts. VerifyNewBundle -> rekorV2Bundle writes
co.UseSignedTimestamps for Rekor v2 entries, racing sibling goroutines
that read co via co.verificationOptions().

Add TestVerifyNewBundleConcurrentNoDataRace, which fans out concurrent
verifications of a Rekor v2 bundle against one shared CheckOpts and
fails under -race without the copy.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 13:52:25 -04:00
Aaron Lew
5e053b312e fix(verify): Attach provided certificate and chain to loaded signature (#4737)
This change updates loadSignatureFromFile to properly bind the provided --certificate and --certificate-chain to the constructed signature object. Previously, verification using detached materials ignored these flags during object initialization, which caused transparency log lookups to incorrectly fall back to querying with a raw public key instead of the full certificate PEM, preventing the signature from being found in the log.

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-06-02 19:58:30 -07:00
Carlos Tadeu Panato Junior
5b603990dc update go-github to v88 (#4887) 2026-05-24 14:27:48 +02:00
Carlos Tadeu Panato Junior
cb68b29724 bump golangci-lint (#4886) 2026-05-24 14:26:52 +02:00
Sebastien Tardif
da174ac4cd Fix unsafe type assertion in Rego policy evaluation (#4882)
evaluateRegoEvalMapResult asserts each element in the Rego response
array as map[string]interface{} without an ok check. If a policy
returns a non-map value in the array, cosign panics instead of
returning a policy evaluation error.

Add an ok check and return a descriptive error on type mismatch.

The bug was introduced in b2cea0c68 (2022-12-28).

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-05-22 22:22:11 -07:00
Sebastien Tardif
b4e1761f76 fix: check HTTP status code in LoadFileOrURL (#4877)
LoadFileOrURL silently returns the response body for non-2xx HTTP
responses. When a URL returns 404 or 500, the HTML error page is
passed to callers as valid key/signature/certificate data, producing
confusing parse errors downstream.

Add a status code check that returns a clear error for non-2xx
responses. The body is closed before returning to avoid leaking the
HTTP connection.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-05-22 15:31:25 -07:00
Andrew Womeldorf
a01e484b73 Use the configured Target Repository more consistently. (#4836)
---------

Signed-off-by: Andrew Womeldorf <andrew.womeldorf@gmail.com>
Signed-off-by: Andrew Womeldorf <git@andrew.wom.icu>
2026-05-21 10:22:30 -04:00
Hayden
6ea2f18739 Fix crash verifying timestamps when no timestamp was verified (#4881)
If no TSA chain in the trust root can verify a signed timestamp, then a
crash would occur when Cosign tries to read one of the verified
timestamps. We now throw an error if no timestamp was verified.

Signed-off-by: Hayden <8418760+Hayden-IO@users.noreply.github.com>
2026-05-21 09:30:29 -04:00
Sebastien Tardif
cd402b41f1 Fix impossible status code checks in GitHub provider PutSecret (#4876)
The HTTP status code checks in PutSecret use && instead of ||:

    if statusCode < 200 && statusCode >= 300 {

This condition is always false (no integer is simultaneously less
than 200 and greater than or equal to 300), so non-2xx HTTP errors
are silently ignored. Fix all four checks to use || so that error
responses from the GitHub API are properly detected and reported.

The GitLab provider (pkg/cosign/git/gitlab/gitlab.go) already uses
the correct || operator for the same check.

Introduced in PR #848 (5302c87a, 2021-10-12).

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-05-19 11:38:55 -07:00
Hayden
bf57b89820 feat(cli): add Rekor v2 flag to cosign signing-config create (#4868)
Allows populating the signing configuration using default values
from the Sigstore TUF root, specifically fetching from the target
`signing_config_rekor_v2.v0.2.json` to support Rekor v2 services.

Signed-off-by: Hayden <8418760+Hayden-IO@users.noreply.github.com>
2026-05-18 17:30:02 -05:00
Sebastien Tardif
8a86a7cf84 fix: use Header.Set to prevent duplicate Authorization on retry (#4870)
The GitHub Actions OIDC token provider uses Header.Add inside a retry
loop. On each retry iteration, an additional Authorization header is
appended to the request. By the third attempt, three identical headers
are sent. Some servers and proxies reject requests with duplicate
Authorization headers, causing retries to fail when they should
succeed.

Replace Header.Add with Header.Set so only one Authorization header
is ever present, regardless of how many retries occur.

Add a test that forces two retries via connection hijack and asserts
exactly one Authorization header is received on every attempt.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-05-18 09:40:23 -04:00
Sebastien Tardif
b33aaacb9a fix: close file descriptor leaked in WriteSignedImageIndexImages loop (#4869)
In WriteSignedImageIndexImages, os.Open is called inside a loop to parse
each blob manifest, but the returned file descriptor is never closed.
This leaks one fd per iteration—on every continue (parse error or nil
Subject) and on the normal path alike.

Close fd immediately after v1.ParseManifest since the parsed manifest is
the only value needed from the file. A plain Close() rather than defer
is used because defer inside a loop would accumulate closers until the
function returns, defeating the purpose.

Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
2026-05-17 15:10:13 -07:00
Aaron Lew
1d5c7a6d34 Sign exclusively via sigstore-go (#4618)
This change refactors the signing path in all signing and attestation commands such that all signing events occur via sigstore-go, not just those in which a signing config is used.

Signed-off-by: Aaron Lew <64337293+aaronlew02@users.noreply.github.com>
2026-04-13 16:50:12 -07:00
Simon Josefsson
f3d74d4887 Fix 'the' typo in copyright name (#4788)
Signed-off-by: Simon Josefsson <simon@josefsson.org>
2026-04-02 07:47:30 -07:00
Colleen Murphy
dd9e82345e Fix linter errors for in-toto-golang update
The update of in-toto-golang to 0.10.0 deprecated the Statement type
in favor of a protobuf-generated Statement type in the attestation
package. The types are not identical, so some translation is needed to
support arbitrarily typed predicates for some attestations.

Signed-off-by: Colleen Murphy <colleenmurphy@google.com>
2026-03-12 13:32:20 -07:00
Colleen Murphy
b9fc665c6e Add tests for attestation.GenerateStatement
Signed-off-by: Colleen Murphy <colleenmurphy@google.com>
2026-03-12 13:32:20 -07:00