The Supply Chain Risk in GitHub Releases
GitHub Releases launched July 2, 2013. Supply chain security wasn’t part of the conversation then. In the last 30 days, developers published over 7 million distinct releases with more than 10 million attached assets. Every one of them was fully mutable: maintainers could swap the tag, add files, delete files, or overwrite assets after publishing.
“there’s no guarantee that you’re consuming the same thing, right?” — Brian DeHamer
A consumer pinning a Go module or GitHub Action to v1 had no promise that v1 pointed at the same commit a week later. That’s the problem Immutable Releases was built to fix.
What Immutable Releases Locks Down
Immutable Releases locks a release the moment it is published. The tag cannot move. No assets can be added, updated, or deleted. NPM and PyPI have offered this guarantee for years; GitHub now brings it to its own release distribution layer. GitHub also generates a cryptographically signed Sigstore attestation automatically and attaches it to the release page. The feature is opt-in per repository because a blanket rollout would break existing automation. Recommended workflow: create a draft, assign the tag, upload all assets, then publish. Title and release notes can still be edited after publishing; the tag and artifacts cannot.
Enabling the Feature: Repo and Org Controls
Enabling Immutable Releases takes one checkbox in Repository Settings. Organizations can push the policy across every repo or select a subset; once set at the org level, individual maintainers cannot disable it without org-admin privileges. New API endpoints cover both scopes. When a maintainer goes to create a release on an immutable-enabled repo, a banner warns them before they publish. After publishing, the release page shows a lock icon. The signed attestation file appears automatically in the assets table alongside the source archives and any uploaded binaries.
Enforcement and Attestation Verification
The GitHub CLI tamper-proof enforcement demo (11:45) shows four blocked operations: uploading a new asset, deleting an existing asset, moving the tag from v1 to v2, and deleting the tag via git push. Each call returns an error citing immutability.
“This release is marked as immutable.” — Brian DeHamer
Deleted releases burn the tag permanently. V1 cannot be reused on a new release. The Sigstore attestation verification demo (13:03) decodes the bundle payload to show the tag, commit SHA, and per-artifact hashes, then runs gh attestation verify-asset to confirm whether a local file matches the published record.
Notable Quotes
there’s no guarantee that you’re consuming the same thing, right? Brian DeHamer · ▶ 5:17
This release is marked as immutable. Brian DeHamer · ▶ 11:58
Your consumers will thank you. Brian DeHamer · ▶ 14:58
Key Takeaways
- GitHub Releases were fully mutable for 12 years, letting maintainers silently swap tags and assets after publishing.
- Immutable Releases freezes the tag, commit, and all artifacts at publish; deleted tags are burned and cannot be reused.
- Every immutable release gets a Sigstore-format attestation you can verify locally with the GitHub CLI.