Immutable Tags

Immutable Tags

What Are Immutable Tags?

Immutable tags are a registry feature that refuses to overwrite a tag once it has been written, so a reference such as app:1.4.2 always resolves to the same manifest. The tag becomes a permanent name for one build. A second push to that name is rejected rather than quietly accepted.

The default is the opposite. Under the OCI image specification an image is referenced either by a mutable tag or by a content-addressed digest, the sha256 of its manifest, and only the digest means one thing forever.

A tag is otherwise an ordinary pointer that anyone with push rights may move. Immutability removes that freedom deliberately, making the tag behave more like a digest without asking every consumer to handle digests directly. The guarantee is enforced by the registry rather than by convention, which is what an auditor can rely on.

How Tag Immutability Works

The setting changes one narrow behaviour in the registry, and leaves the rest of the model alone.

  • The push is rejected. When a tag already exists, a second push to that name fails instead of repointing it.
  • The digest stays the anchor. Immutability does not change how content is addressed; it constrains which name may point where.
  • Scope is configurable. Most registries apply the rule per repository, and some allow patterns so release tags freeze while development tags move.
  • Deletion is separate. A registry may still permit deletion; the setting prevents overwriting, not removal.

The practical effect is that a tag becomes evidence. If app:1.4.2 cannot move, a deployment record naming it identifies one manifest, months later.

Without the setting, that record identifies only whatever the tag pointed to at the moment of the pull.

What Immutability Buys, and What It Costs

Auditability is the clearest gain. A build log, a change ticket and a running workload reconcile against each other, because the names in all three resolve to the same content.

Incident response benefits for the same reason. When an advisory lands, the question is which builds contain the affected layer — answerable only if historical references still mean what they meant.

The cost falls on teams relying on a tag that moves. A latest tag, or a patch-level tag that silently refreshes, is a deliberate convenience: consumers pull it and receive the newest build. Freezing every tag removes that.

The usual resolution keeps both behaviours:

  • Frozen version tags. Full versions such as 1.4.2 are written once and never moved.
  • A separate moving alias. A tag such as 1.4 or stable is explicitly mutable, documented as a pointer, not an identity.
  • Digest pinning where it must be absolute. Deployments needing a cryptographic guarantee reference the manifest digest directly.
  • Rebuild, do not retag. A fix produces a new version rather than a replacement of an old one.

How to Enforce Tag Immutability in Production Environments

Rollout is easiest repository by repository, starting where release artifacts live.

  • Enable it first on repositories holding released images, not scratch space.
  • Keep a documented list of tags allowed to move, and treat everything else as frozen.
  • Resolve tags to digests in CI and record the digest beside the tag.
  • Make every change produce a new version, so nobody must overwrite a tag.
  • Apply the same rule to registry mirroring and caches, so copies cannot drift from the original.

How Hardened Container Images Depend on Stable References

A hardened image is only as useful as your ability to say which one you ran. Frozen references make that answer durable, which is why rebuild cadence and tagging policy are worth asking a provider about together.

Providers differ in how they name rebuilds: some issue a new version for every change, others move a floating tag. Both are defensible, but only the first is self-documenting for anyone reading a deployment record months later. Echo states that its images are continuously rebuilt and updated, and that workloads can stay on versions that fit their needs without forced migrations (echo.ai/product).

Echo publishes hardened minimal base images, and the adjacent verification step is covered in container image signing.

FAQs

What happens if someone pushes to an existing tag?

The registry rejects the push and returns an error, and the existing manifest stays in place. Build pipelines that previously overwrote a tag will fail until they are changed to emit a new version instead. That failure is the point: it surfaces an overwrite that would otherwise have happened silently.

Is a digest still needed when tags cannot be overwritten?

Often, yes. The setting is a registry policy, and policies can be changed, misconfigured or absent on a mirror. A digest is a cryptographic property of the content itself, so it holds regardless of configuration. Use frozen tags for readability, and digests wherever the guarantee has to be absolute and independently verifiable by whoever pulls the image.

Can a team keep a moving latest tag?

Yes, by exempting it. Most registries let you freeze some tags and leave others mutable, so release versions stay fixed while a documented alias keeps moving. The important part is that consumers know which category a tag belongs to, because the two offer very different guarantees about what will be pulled tomorrow.

What is the difference between immutability and deletion protection?

Immutability stops a tag being repointed to different content. Deletion protection stops a tag or manifest being removed entirely. They are separate registry settings solving separate problems: one prevents a reference quietly changing meaning, the other prevents it disappearing. An auditable history generally needs both enabled together, on the same repositories.

Does the OCI specification require tags to be stable?

No. The specification describes a tag as a mutable reference and a digest as the content-addressed, immutable one. Stability at the tag level is a registry feature layered on top, not a guarantee of the format. That is why tooling that needs certainty resolves to a digest rather than trusting a name.

Ready to eliminate CVEs at the source?