Description
Summary
Docker Compose should support an opt-in minimum release age for images referenced by mutable tags. During docker compose pull or docker compose up, Compose should resolve the tag to the newest digest that has remained associated with that tag for at least the configured duration.
Conceptually, this is uv exclude-newer for container images:
services:
redis:
image: redis:latest
minimum_release_age: 14d
This is intentionally a runtime policy, not a lock-file feature. Pinning a digest is already possible, but it does not let users follow a mutable channel such as latest, stable, or 7 with a deliberate delay.
Why this matters
Automated updates can deploy a compromised, broken, or prematurely published release within minutes. If it is removed or replaced a few hours later, immediate consumers have already run it. A minimum-age policy provides an observation window in which maintainers, scanners, users, and registries can detect and retract a bad release before it becomes eligible.
This mitigation has become common in package tooling:
Existing Compose pull_policy values such as daily or weekly only control when Compose checks. They do not ensure that the digest found at that moment has existed for a minimum amount of time.
Proposed behavior
For redis:latest with a 14-day minimum, Compose should inspect the history of that exact tag:
- Digest A was assigned for 30 days: eligible.
- Digest B replaced A but was removed after two days: never eligible.
- Digest C is currently assigned but only eight days old: not yet eligible.
Compose should continue pulling A until C has remained assigned for 14 days. This prevents a short-lived or retracted digest from becoming eligible merely because its original timestamp is now old.
Important semantics:
- Age must be based on the registry-recorded tag-to-digest assignment, not the publisher-controlled image build timestamp. Retagging old content must not bypass the waiting period.
- Registries must retain at least the last eligible digest and its blobs while a successor is maturing. Explicitly withdrawn or revoked digests must not be selected.
- Multi-platform tags should be resolved at the manifest-list/image-index digest.
- If trustworthy tag history or a retained eligible digest is unavailable, configured enforcement should fail closed rather than silently pulling the newest image.
- An explicit one-shot CLI override should allow urgent security updates.
pull_policy should decide whether to check the registry; minimum_release_age should constrain which digest may be pulled.
The feature should be opt-in and backward compatible. The exact Compose schema and override name are open for discussion.
Existing foundation and implementation scope
The standard OCI Distribution API can list tags and retrieve manifests, but it does not currently provide portable history for a mutable tag. The optional org.opencontainers.image.created annotation describes build time and is not a safe substitute for registry-recorded tag history.
Relevant work already exists:
That OCI proposal is a strong foundation, but the complete feature also needs retention and revocation semantics: a historical digest is useless if its manifest or blobs have been garbage-collected, and normal supersession must be distinguishable from withdrawal of a previously matured digest.
I expect the work to span:
- OCI Distribution and registries: standardize and implement tag history, withdrawal, and sufficient content retention.
- Docker Engine/API: authenticate to registries, resolve the newest eligible digest, and expose that result to clients. Engine is the appropriate layer because it already handles credentials, mirrors, proxies, custom CAs, platforms, and pulling.
- Compose Specification and Docker Compose: add the service policy, apply it to
pull and up, show the selected digest and skipped newer assignments, provide the emergency override, and test the behavior.
Implementing registry-specific history clients directly in Compose would duplicate Engine responsibilities and would not produce an interoperable solution. This issue could serve as the user-facing umbrella for coordinated work across those projects.
This is defense in depth, not a replacement for signatures, attestations, scanning, digest pinning, or trusted registries. It primarily protects against releases that are detected and withdrawn within the configured observation window.
Description
Summary
Docker Compose should support an opt-in minimum release age for images referenced by mutable tags. During
docker compose pullordocker compose up, Compose should resolve the tag to the newest digest that has remained associated with that tag for at least the configured duration.Conceptually, this is
uv exclude-newerfor container images:This is intentionally a runtime policy, not a lock-file feature. Pinning a digest is already possible, but it does not let users follow a mutable channel such as
latest,stable, or7with a deliberate delay.Why this matters
Automated updates can deploy a compromised, broken, or prematurely published release within minutes. If it is removed or replaced a few hours later, immediate consumers have already run it. A minimum-age policy provides an observation window in which maintainers, scanners, users, and registries can detect and retract a bad release before it becomes eligible.
This mitigation has become common in package tooling:
exclude-newerfilters candidates by upload time.min-release-ageandbeforeresolve only versions old enough to qualify and support explicit exclusions.minimumReleaseAge, YarnnpmMinimalAgeGate, and BunminimumReleaseAgeimplement the same supply-chain safety pattern.minimumReleaseAgealready applies to Docker updates when a release timestamp is available, although its Docker datasource currently documents timestamp support only for Docker Hub.cooldownsupports both Docker and Docker Compose version updates.Existing Compose
pull_policyvalues such asdailyorweeklyonly control when Compose checks. They do not ensure that the digest found at that moment has existed for a minimum amount of time.Proposed behavior
For
redis:latestwith a 14-day minimum, Compose should inspect the history of that exact tag:Compose should continue pulling A until C has remained assigned for 14 days. This prevents a short-lived or retracted digest from becoming eligible merely because its original timestamp is now old.
Important semantics:
pull_policyshould decide whether to check the registry;minimum_release_ageshould constrain which digest may be pulled.The feature should be opt-in and backward compatible. The exact Compose schema and override name are open for discussion.
Existing foundation and implementation scope
The standard OCI Distribution API can list tags and retrieve manifests, but it does not currently provide portable history for a mutable tag. The optional
org.opencontainers.image.createdannotation describes build time and is not a safe substitute for registry-recorded tag history.Relevant work already exists:
That OCI proposal is a strong foundation, but the complete feature also needs retention and revocation semantics: a historical digest is useless if its manifest or blobs have been garbage-collected, and normal supersession must be distinguishable from withdrawal of a previously matured digest.
I expect the work to span:
pullandup, show the selected digest and skipped newer assignments, provide the emergency override, and test the behavior.Implementing registry-specific history clients directly in Compose would duplicate Engine responsibilities and would not produce an interoperable solution. This issue could serve as the user-facing umbrella for coordinated work across those projects.
This is defense in depth, not a replacement for signatures, attestations, scanning, digest pinning, or trusted registries. It primarily protects against releases that are detected and withdrawn within the configured observation window.