Skip to content
LatchkeyLatchkey home

gh attestation verify: Verify Build Provenance

gh attestation verify confirms that an artifact was built by the expected GitHub Actions workflow via its signed attestation.

Supply-chain gates verify provenance before deploying; gh attestation verify proves an artifact came from a trusted workflow, not an attacker.

What it does

gh attestation verify checks the Sigstore-signed build provenance attestation for an artifact. You give it the artifact and the expected --owner or --repo; it verifies the signature and that the attestation references that source, printing the verified policy.

Common usage

Terminal
gh attestation verify ./myapp --owner my-org
gh attestation verify ./myapp --repo my-org/myapp
gh attestation verify oci://ghcr.io/my-org/app:1.0 --owner my-org
gh attestation verify ./myapp --repo my-org/myapp --bundle attestation.jsonl

Flags

FlagWhat it does
-o, --owner <name>Expected owner of the source repository
-R, --repo <owner/repo>Expected source repository
-b, --bundle <file>Verify against a local attestation bundle
--predicate-type <uri>Filter attestations by predicate type
--format jsonOutput the verification result as JSON

In CI

Set GH_TOKEN with permissions: { contents: read } so gh can fetch attestations from the API; for offline verification supply --bundle and no token call is made. Either --owner or --repo is required so the check is bound to a trusted source.

Common errors in CI

"failed to verify attestation: no attestations found" means the artifact has none published, or --owner/--repo does not match. "gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable" means GH_TOKEN is unset when fetching from the API. A digest mismatch means the file differs from what was attested.

Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached

Frequently asked questions

gh attestation verify: Verify Build Provenance?
Supply-chain gates verify provenance before deploying; gh attestation verify proves an artifact came from a trusted workflow, not an attacker.
What it does?
gh attestation verify checks the Sigstore-signed build provenance attestation for an artifact. You give it the artifact and the expected --owner or --repo; it verifies the signature and that the attestation references that source, printing the verified policy.
In CI?
Set GH_TOKEN with permissions: { contents: read } so gh can fetch attestations from the API; for offline verification supply --bundle and no token call is made. Either --owner or --repo is required so the check is bound to a trusted source.
Common errors in CI?
"failed to verify attestation: no attestations found" means the artifact has none published, or --owner/--repo does not match. "gh: To use GitHub CLI in a GitHub Actions workflow, set the GH_TOKEN environment variable" means GH_TOKEN is unset when fetching from the API. A digest mismatch means the file differs from what was attested.

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card