KEY TAKEAWAYS
- An Immutable label describes release protections. It does not show that anyone compared the file on your machine with an attested release asset. [1] [2]
- Use an explicit repository and tag for both checks: gh release verify checks the release attestation; gh release verify-asset compares a supplied local file's digest with the attestation for that release. [4] [5]
- Generated source-code zip/tar downloads cannot use this asset-verification path. Record NOT APPLICABLE and a separate evidence gap, rather than a failed check or a safe verdict. [2]
Start with the file you intend to use
When choosing a binary for an agent workflow, keep an acceptance record for the exact file before allowing it to run. An Immutable label on its release page is useful evidence about the published release. It is not a result for the copy you have locally. GitHub documents separate checks for the release and for a local artifact. [1] [2]
After an immutable release is published, its Git tag is locked to a specific commit and its attached assets cannot be modified or deleted. The tag cannot be deleted while the release exists; deleting the release does not allow reuse of the tag name. Title, notes and pre-release/latest designation can still change. Identify the release by repository and explicit tag, rather than by its title or whichever release is currently called latest. [1]
Check the particular release, not just a repository setting. GitHub's enabling guide says immutability applies only to future releases. Turning it on today does not establish that an older release is immutable. [3]
A release attestation is a cryptographically verifiable record containing the tag, commit SHA and release assets. The CLI's release check validates a signed attestation and displays attested asset metadata, including digests. The local-asset check compares your file's digest with the subject in a valid attestation associated with that release. Keep those results in separate fields. [1] [4] [5]
Copy this acceptance record
Use one record per intended local asset and repository/tag. Define mandatory criteria before checking, then replace blanks with exact values and evidence locations. UNKNOWN means evidence is missing; NOT RUN means a check was not performed. These are worksheet labels, not GitHub configuration syntax. Keep completed records private if they contain sensitive paths, and never include credentials.
- Decision owner: ____ | Intended task and environment: ____
- Check/decision time with timezone: ____ | Mandatory acceptance criteria: ____
- Tool/version and access prerequisites established: ____ / UNKNOWN
| Field | Exact value or evidence | Status / unresolved question |
|---|---|---|
| Origin | OWNER/REPO: ____ | Repository URL: ____ | Is this the intended publisher/repository? UNKNOWN / evidence: ____ |
| Release | Explicit tag: ____ | Release-page URL: ____ | Specific release's Immutable label or verification evidence: ____ / UNKNOWN. A repository switch alone is insufficient. [1] [3] |
| Local file | Attached asset filename: ____ | Local path: ____ | Platform/architecture: ____ | Uploaded release asset / generated source archive / UNKNOWN: ____ |
| Release attestation | Evidence location: ____ | Attested tag: ____ | Commit SHA: ____ | Asset entry and digest: ____ | NOT RUN / UNKNOWN / observed evidence: ____. Commit association alone is not build provenance. [1] [6] |
| Release check | Exact command, repository/tag, time, exit status and output location: ____ | NOT RUN / valid observed result / error / UNKNOWN: ____. This check does not compare the local file. [4] |
| Local asset check | Exact command, file/repository/tag, time, exit status and output location: ____ | NOT RUN / observed match / observed mismatch / error / NOT APPLICABLE: ____. Preserve the actual result. [2] [5] |
| Generated source archive | If applicable, intended commit/content identity and separate evidence method: ____ | verify-asset NOT APPLICABLE; separate evidence UNKNOWN until supplied. [2] |
| Build provenance | If required: separate build-attestation identity, source/workflow/commit and policy-evaluation evidence: ____ | NOT RUN / UNKNOWN / evidence: ____. Do not substitute a release attestation. [1] [6] |
| Safety and fitness | Required dependency/vulnerability/behavior, platform and runtime-restriction evidence: ____ | UNKNOWN / evidence: ____. An attestation is not a security guarantee. [6] |
| Decision | ACCEPT for stated use / HOLD: ____ | Reason and remaining limits: ____ | Unmet or unknown mandatory criteria: ____ | Responsible person, next action and next check time: ____ |
For an uploaded release asset, the local match is one input to acceptance. It does not establish that the original published binary was benign, reproducibly built or suitable for your task. GitHub's build-provenance documentation describes attestations about where and how software was built and explicitly warns that attestations do not guarantee security. Require separate evidence for the build and safety criteria your use demands. [1] [6]
Two documented checks, with explicit identity
The following commands are unexecuted examples. Replace OWNER/REPO, RELEASE-TAG and ARTIFACT-PATH deliberately; quote a real path if it contains spaces. Both CLI references document --repo and JSON output. They also say omitting a tag selects the latest release, which is why these examples name one. Installed CLI compatibility and access prerequisites still need checking in the reader's environment. [4] [5]
- Release attestation: gh release verify RELEASE-TAG --repo OWNER/REPO --format json
- Local file match: gh release verify-asset RELEASE-TAG ARTIFACT-PATH --repo OWNER/REPO --format json
The first asks whether the specified release has a valid signed attestation and reports its assets and digests. The second checks the supplied file's digest against the attestation and its release association. These verification examples do not install or execute the artifact. We provide no output because neither command was run for this resource. [4] [5]
Preserve the actual command context, tool version, time, exit status and output, then record the attested commit and asset digest without shortening them. A release-check success must not fill in the local-match field. A filename, a manually recorded hash or a page label is not a substitute for the documented attestation comparison.
Source code (zip/tar) needs a separate evidence path
GitHub's integrity guide says verify-asset cannot verify a release's generated source-code zip file or tarball because those assets are created when a download is requested. If that is your input, mark this check NOT APPLICABLE. Leave separate commit/content evidence UNKNOWN until you have it; do not turn the exception into either a failed integrity check or an approval to use the archive. [2]
The distinction is how the archive was supplied, not its extension. An ordinary uploaded .zip or .tar release asset is not excluded merely because it is an archive: the immutable-release overview includes attached archives, and the asset CLI reference uses an uploaded .zip in its example. Record whether you chose the generated Source code link or an attached asset. [1] [5]
This resource does not supply an equivalent command for verifying generated archives. Ask the responsible owner to define and document a suitable separate evidence method. Keep acceptance on HOLD while a mandatory identity requirement remains unresolved.
A completed record can still say HOLD
Our proposed rule is to ACCEPT only for the stated use when the intended origin, repository/tag and local-file identity are established, applicable verification evidence is recorded, and mandatory build/safety/fitness criteria are satisfied. Record residual limits and the person making that decision. A verified identity is not universal permission to run software.
HOLD when a mandatory requirement is unknown, a local match fails, the evidence points to a different file/repository/tag, or an unresolved tool error prevents the check. NOT RUN is not success. An error is not automatically evidence of tampering; a mismatch calls for preserving evidence and resolving identity, rather than declaring a company-wide security incident.
- Hypothetical filled record, NOT RUN: a team is considering an agent helper. Repository: OWNER/REPO placeholder; actual origin UNKNOWN. Tag: RELEASE-TAG placeholder; release page not recorded.
- Asset: agent-helper-PLATFORM-ARCH.tar.gz placeholder; path: ARTIFACT-PATH placeholder. No file downloaded. Release immutability, attested commit and digest: UNKNOWN.
- Release check: NOT RUN. Local asset check: NOT RUN. Exit status/output: absent. Required build, safety and fitness evidence: UNKNOWN.
- Decision: HOLD. Next action: the responsible reader establishes exact origin/tag/file and required evidence in their own authorized workflow. Nothing in this example is an observed verification result.
If the same hypothetical team selects the generated Source code (zip) link instead, its local-asset field becomes NOT APPLICABLE, not a mismatch. Separate commit/content evidence stays UNKNOWN and the decision stays HOLD pending required evidence. The worksheet's value is the unresolved field and its owner, not the appearance of a completed checklist. [2]
Sources & scope
Document-based acceptance aid for a team selecting one GitHub release asset, such as a tool for an agent workflow. Official sources checked 4 October 2026 KST; their publication/update dates and a minimum CLI version were not established. No repository, release, attestation or downloaded file was verified for this article. Command examples and the filled record are hypothetical and unexecuted. The worksheet proposes a decision record, not a security certification or an installation procedure.
- GitHub Docs: Immutable releases ↗
Checked 4 October 2026 KST. Official explanation of tag/attached-asset protections, mutable release metadata and release attestations. Publication/update dates not established; documentation, not a test of a particular release.
- GitHub Docs: Verifying the integrity of a release ↗
Checked 4 October 2026 KST. Distinct release/local-asset checks and generated source-code zip/tar exception. Publication/update dates not established. Commands were read, not executed.
- GitHub Docs: Preventing changes to your releases ↗
Checked 4 October 2026 KST. Enabling immutability applies to future releases only. Publication/update dates not established; no repository setting was changed.
- GitHub CLI manual: gh release verify ↗
Checked 4 October 2026 KST. Signed release-attestation check, reported asset digests, latest default, --repo and JSON output. No minimum client version established; server Last-Modified is not treated as a publication or launch date. Not executed.
- GitHub CLI manual: gh release verify-asset ↗
Checked 4 October 2026 KST. Local digest/attestation/release association, repository selection and uploaded .zip example. No minimum client version or publication/update date established. Not executed.
- GitHub Docs: Artifact attestations ↗
Checked 4 October 2026 KST. Separate build-provenance context and explicit warning that attestations are not a security guarantee. Publication/update dates not established; no build or safety test performed.
Publication history
- — Prepared the document-based consumer asset worksheet and unexecuted command/hold examples from official sources checked 4 October 2026.
Have a correction or a different perspective? Contact Palanthos.