Summary
The "recommended" install path in the getting-started guide tells users to verify the
download with a cosign verify-blob command that fails against every shipped release. It
references signature files that the release does not contain and pins a signing identity
that does not match the certificate.
Affected
Documented command
# _index.md:48-55
cosign verify-blob \
--certificate complyctl_*_checksums.txt.pem \
--signature complyctl_*_checksums.txt.sig \
complyctl_*_checksums.txt \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
--certificate-identity=https://github.com/complytime/complyctl/.github/workflows/release.yml@refs/heads/main
What the release actually ships
$ gh release view v1.0.0-beta.0 -R complytime/complyctl --json assets
complyctl_1.0.0-beta.0_checksums.txt
complyctl_1.0.0-beta.0_checksums.txt.sigstore.json # a sigstore bundle
complyctl_linux_arm64.tar.gz (+ .sbom.json)
complyctl_linux_i386.tar.gz (+ .sbom.json)
complyctl_linux_x86_64.tar.gz (+ .sbom.json)
Two independent problems
-
No *.pem and no *.sig exist. The release signs the checksums into a single
*_checksums.txt.sigstore.json bundle. The --certificate complyctl_*_checksums.txt.pem
and --signature complyctl_*_checksums.txt.sig globs expand to nothing, so the command
errors before it checks a signature:
Error: open complyctl_*_checksums.txt.pem: no such file or directory
-
The pinned identity is wrong. The documented --certificate-identity ends in
@refs/heads/main. The SAN identity in the signing certificate inside the bundle is:
https://github.com/complytime/complyctl/.github/workflows/release.yml@refs/tags/v1.0.0-beta.0
cosign requires --certificate-identity to match the SAN exactly (or be matched via
--certificate-identity-regexp), so the documented value is rejected even after fixing
problem (1). This is consistent with the release workflow, which is workflow_dispatch
taking a tag input (complyctl/.github/workflows/release.yml) — releases are cut per
tag, so the identity is always a tag ref, never main.
Expected
Following the recommended path verbatim verifies the release and prints Verified OK.
Actual
The command errors on the missing .pem file and never reaches signature verification.
After fixing the file references it still fails on the identity mismatch.
Suggested fix
Replace the block with the bundle form and a tag-templated identity. Verified to print
Verified OK against the real v1.0.0-beta.0 bundle:
cosign verify-blob \
--bundle complyctl_<VERSION>_checksums.txt.sigstore.json \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
--certificate-identity-regexp='^https://github.com/complytime/complyctl/\.github/workflows/release\.yml@refs/tags/' \
complyctl_<VERSION>_checksums.txt
The signing infrastructure itself is sound — this is purely a documentation fix. Consider
adding a copy/paste test of this exact command to CI against the just-built release so the
documented command cannot drift from the published artifact again.
Related: #66
Issue created with the help of Claude Opus 4.6
Summary
The "recommended" install path in the getting-started guide tells users to verify the
download with a
cosign verify-blobcommand that fails against every shipped release. Itreferences signature files that the release does not contain and pins a signing identity
that does not match the certificate.
Affected
content/docs/getting-started/_index.md(lines 46–55), rendered athttps://complytime.dev/docs/getting-started/
complytime/complyctlv1.0.0-beta.0Documented command
What the release actually ships
Two independent problems
No
*.pemand no*.sigexist. The release signs the checksums into a single*_checksums.txt.sigstore.jsonbundle. The--certificate complyctl_*_checksums.txt.pemand
--signature complyctl_*_checksums.txt.sigglobs expand to nothing, so the commanderrors before it checks a signature:
The pinned identity is wrong. The documented
--certificate-identityends in@refs/heads/main. The SAN identity in the signing certificate inside the bundle is:cosignrequires--certificate-identityto match the SAN exactly (or be matched via--certificate-identity-regexp), so the documented value is rejected even after fixingproblem (1). This is consistent with the release workflow, which is
workflow_dispatchtaking a
taginput (complyctl/.github/workflows/release.yml) — releases are cut pertag, so the identity is always a tag ref, never
main.Expected
Following the recommended path verbatim verifies the release and prints
Verified OK.Actual
The command errors on the missing
.pemfile and never reaches signature verification.After fixing the file references it still fails on the identity mismatch.
Suggested fix
Replace the block with the bundle form and a tag-templated identity. Verified to print
Verified OKagainst the realv1.0.0-beta.0bundle:The signing infrastructure itself is sound — this is purely a documentation fix. Consider
adding a copy/paste test of this exact command to CI against the just-built release so the
documented command cannot drift from the published artifact again.
Related: #66
Issue created with the help of Claude Opus 4.6