Skip to content

Fix sigstore oci verification - #3

Open
andreaTP wants to merge 2 commits into
roastedroot:mainfrom
andreaTP:fix-sigstore-oci-verification
Open

Fix sigstore oci verification#3
andreaTP wants to merge 2 commits into
roastedroot:mainfrom
andreaTP:fix-sigstore-oci-verification

Conversation

@andreaTP

@andreaTP andreaTP commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

inlay:fetch could not verify any artifact signed with `cosign sign` — the
command the README, the error message, and this repo's own publisher
workflow all told users to run. Verification passed the wasm file to
sigstore-java, which hashes it, while `cosign sign` binds its signature to
the OCI manifest digest. The two can never agree.

Select the digest by bundle shape: a DSSE envelope (`cosign sign`) is
verified against the manifest digest, a message signature (`cosign
sign-blob`) against the artifact bytes as before. sigstore-java's
verify(byte[], ...) takes a digest — verify(Path, ...) is a thin wrapper
that sha256s the file — and already dispatches on bundle shape internally,
so only the choice of digest was ours to make.

Also pull by the resolved digest rather than the tag. pullByDigest resolved
a digest, then pulled with the original (mutable) ref and used the digest
only as a cache key. The blob-hash check masked this: verification hashed
whatever landed on disk. Binding verification to the manifest digest
removes that check, so a tag moving between resolve and pull would go
unnoticed. The lock file's pin is now actually enforced.

`cosign sign` still cannot be verified end to end: sigstore-java (through
2.2.0) models the in-toto subject `name` as required, but it is optional
per the spec and cosign omits it, so the payload fails to parse before the
digest is compared. Report that explicitly instead of surfacing a Gson
error. The digest handling above is already correct, so the upstream fix
lands as a version bump. Until then, sign with `cosign sign-blob` + `oras
attach`, which is what the publisher workflow and docs now do.

Fix two further defects found along the way: fetchSigstoreBundle returned
the first matching referrer, making verification nondeterministic when both
bundle kinds are attached; and the fetched bundle was written next to the
temp file and never cleaned up.

The README documented an identity glob (`https://github.com/myorg/*`) that
could never match — identities are compared with String.equals, so the `*`
is a literal.
…orkflow identity

sigstoreIssuer and sigstoreIdentity are compared with String.equals, so the
glob the README suggested (https://github.com/roastedroot/*) could never
match — the `*` was a literal. Add sigstoreIssuerRegex and
sigstoreIdentityRegex, backed by sigstore-java's StringMatcher.regex, so the
documented intent is actually expressible. Setting both forms of one field
is rejected, and an invalid pattern is reported against the parameter that
carried it rather than surfacing as a bare PatternSyntaxException.

Document that a reusable workflow's certificate identity is the reusable
workflow's own ref, identical for every repository that calls it. Pinning it
proves an artifact was signed by something using that workflow, not that it
came from the expected repository — the caller appears only in certificate
extensions inlay does not check. That is a sharp edge worth stating next to
the configuration that invites it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant