Skip to content

CONCEPT Cited by 1 source

Publish-time immutability

Publish-time immutability is the semantics in which a composite software artifact — a release, a package version, a container tag — is locked at the moment of publication so no actor (including the original publisher) can later modify, replace, or delete its contents. It is a publish-time one-way door: the decision to make this release immutable is committed atomically with the release itself.

Distinguished from related immutability shapes:

Shape Locked at Scope Who can unlock
Publish-time immutability (this page) publish composite (tag + assets + metadata) nobody, for the life of the release
Immutable object storage write single blob / object nobody — objects are individually WORM
Retention policy time-based per-object or per-bucket policy admin (time-bounded)
Mutable-with-audit write any anyone; audit log preserved

The difference matters for supply-chain policy. An object-lock guarantee (S3 Object Lock, Azure Blob immutability) protects a single blob. A retention policy is a temporal rule. Publish-time immutability protects a coherent named aggregate — the specific thing a consumer names when they say "version 1.4.2 of this software" — across the blob, the name that points to it (the Git tag), and the metadata bundle.

Canonical instance: GitHub immutable releases (2025-10-28)

GitHub's GA feature is the wiki's canonical production instance:

  • Lock scope: assets + Git tag + release metadata, as one aggregate.
  • Lock trigger: publishing the release while the repo/org setting is on.
  • Unlock mechanism: none — "disabling immutability doesn't affect releases created while it was enabled."
  • Enforcement surface: GitHub's own release/tag-update code paths reject modifications on immutable releases.
  • Off-platform verification: a release attestation in Sigstore bundle format ships with the release, so mirrors and air-gapped consumers can verify integrity without re-contacting GitHub.

(Source: sources/2025-10-31-github-immutable-releases-ga)

Why publish-time and not later

Publish-time is the only time the publisher's intent is unambiguous. "I am publishing version X with these bytes" is a deliberate act. Any later modification — even by the same account — is by definition a different intent ("I want the bytes for X to now be Y"). Immutability refuses to execute that second intent: if the assets for X need to change, a new release Y has to be published.

The alternative — retention-policy or mutable-with-audit immutability — can't distinguish "legitimate correction" from "compromised-account asset swap" at policy-evaluation time, so it provides weaker supply-chain guarantees.

Why non-retroactive disable is definitional

The "once immutable, always immutable" property is not a GitHub implementation quirk — it is what makes publish-time immutability meaningful. If disabling the setting retroactively unlocked prior releases, then an attacker with control of the setting toggle (an admin credential, a compromised OAuth app with org-admin scope) could swap any release's assets after the fact, and downstream consumers' prior verifications would be invalidated. Non-retroactive disable pushes the trust boundary from is this setting currently on? to was this setting on at publish time? — a historical fact that the attestation itself encodes.

Architectural implications

  • Scope must be new-artifacts-only on rollout. Applying publish-time immutability to an existing catalogue would either require re-publishing every release (operational nightmare, breaks existing consumers' cached hashes) or treating old releases as retroactively-immutable (captures back-catalogue errors no one can fix). GitHub's "existing releases remain mutable unless republished" is the standard dodge — backward compatibility via scope-to-new-objects.

  • Control-plane enforcement, data-plane outputs. The repo/org setting that enforces immutability is a control-plane invariant; the attestation bundle is the data-plane output. Consumers verify the data-plane output without re-reading the control-plane state.

  • Composes with tag protection and attestation, not competes. Publish-time immutability is the policy. concepts/tag-protection is one of its enforcement clauses (tag can't be re-pointed). concepts/release-attestation is the portable receipt.

Seen in

Last updated · 200 distilled / 1,178 read