Verifying a release¶
Every OSS IQ artifact is built by a reusable GitHub Actions workflow that signs SLSA build provenance over the bytes it produced. This page shows how to check that what you installed is what those workflows built.
You need gh 2.49 or newer. Replace X.Y.Z with the version
you are verifying.
Why --signer-workflow matters¶
--signer-workflow is the part that makes this a Build L3 check rather than a Build L2
one. OSS IQ builds artifacts inside reusable workflows (reusable-build-*.yml) and
publishes them from separate top-level workflows. The signing identity in the certificate
is the reusable workflow, which the publishing workflow cannot impersonate — so
provenance cannot be forged by anyone who can only edit the release plumbing.
Verifying without --signer-workflow still proves the artifact came from this repository,
but not that it came from the isolated builder. Always pass it.
Warning
These workflow filenames are part of OSS IQ’s public interface. If a verification command here ever fails with an identity mismatch after an upgrade, check this page for the release you are verifying rather than assuming the artifact is bad.
PyPI (wheel and sdist)¶
pip download --no-deps --only-binary :all: ossiq==X.Y.Z # wheel
pip download --no-deps --no-binary :all: ossiq==X.Y.Z # sdist
gh attestation verify ossiq-X.Y.Z-py3-none-any.whl \
--repo ossiq/ossiq \
--signer-workflow ossiq/ossiq/.github/workflows/reusable-build-dist.yml
gh attestation verify ossiq-X.Y.Z.tar.gz \
--repo ossiq/ossiq \
--signer-workflow ossiq/ossiq/.github/workflows/reusable-build-dist.yml
PyPI also stores its own PEP 740 attestations, shown
per file on the release page at https://pypi.org/project/ossiq/X.Y.Z/#files. Those are a
weaker claim — see what each attestation proves.
Standalone binaries¶
gh release download vX.Y.Z --repo ossiq/ossiq \
--pattern 'ossiq-*.tar.gz' --pattern SHA256SUMS
sha256sum -c SHA256SUMS
gh attestation verify ossiq-linux-x64.tar.gz \
--repo ossiq/ossiq \
--signer-workflow ossiq/ossiq/.github/workflows/reusable-build-binaries.yml
Repeat for whichever of darwin-arm64, darwin-x64, linux-x64, linux-arm64 or
win32-x64 you downloaded.
npm¶
# npm's own registry provenance, for everything in the install tree
npm audit signatures
# Re-download the published tarball and check OSS IQ's build provenance over it
npm pack @ossiq/cli@X.Y.Z
gh attestation verify ossiq-cli-X.Y.Z.tgz \
--repo ossiq/ossiq \
--signer-workflow ossiq/ossiq/.github/workflows/reusable-build-npm.yml
npm pack re-downloads the registry tarball byte for byte, which is why the attestation
made at build time still matches. The platform packages verify the same way — for example
npm pack @ossiq/cli-linux-x64@X.Y.Z giving ossiq-cli-linux-x64-X.Y.Z.tgz.
SBOM¶
Each Python artifact also carries a CycloneDX 1.5 SBOM, generated from uv.lock and so
describing exactly the hash-pinned dependency set the artifact was built against.
gh attestation verify ossiq-X.Y.Z-py3-none-any.whl \
--repo ossiq/ossiq \
--predicate-type https://cyclonedx.org/bom
# Read it
gh attestation download ossiq-X.Y.Z-py3-none-any.whl \
--repo ossiq/ossiq --predicate-type https://cyclonedx.org/bom
What each attestation proves¶
Claim |
Signed by |
Covers |
Level |
|---|---|---|---|
|
GitHub / Sigstore, identity = the reusable workflow |
The exact sdist and wheel bytes |
Build L3 |
|
GitHub / Sigstore, identity = the reusable workflow |
Each platform’s |
Build L3 |
|
GitHub / Sigstore, identity = the reusable workflow |
Each published |
Build L3 |
CycloneDX SBOM attestation |
GitHub / Sigstore |
The dependency set, from |
— |
PyPI PEP 740 attestation |
Sigstore, identity = |
The uploaded files |
Build L2 |
npm registry provenance |
Sigstore, via npm’s infrastructure, identity = |
The published tarball |
Build L2 |
The last two are signed by workflows OSS IQ’s maintainers edit directly, which is what
makes them L2: the signing identity is not isolated from the people who control the build
definition. They are kept because they are what registry tooling checks natively
(npm audit signatures, PyPI’s file listing), and because they are useful corroboration.
The L3 claim rests on the reusable-build-*.yml attestations.
Not covered¶
The Docker image (
ossiq/ossiq-cli) is built by installingossiq==X.Y.Zfrom PyPI, so it is outside this chain. Verify the wheel instead: the image contains it, but the image’s own build does not attest it.Reproducibility. These attestations say who built an artifact and from what source, not that rebuilding reproduces identical bytes. The build is deterministic in the inputs that matter —
uv.lockis hash-pinned, the SPA template is committed rather than rebuilt, andSOURCE_DATE_EPOCHis the commit time — but bit-for-bit reproducibility is not a claim OSS IQ currently makes.
If verification fails¶
gh attestation verify failing is not automatically evidence of tampering. In order of
likelihood:
Wrong version. The attestation is over specific bytes; a different version fails.
Wrong
--signer-workflowfor that release. Check this page as of the version you are verifying.A repackaged artifact. A wheel rebuilt by a mirror or a corporate proxy is a different file and will not match.
No attestation exists. Releases before the SLSA L3 work have none. Verify with
gh attestation list --repo ossiq/ossiqbefore concluding a check failed.
If none of those explain it, please report it — see SECURITY.md.