-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define immutable tags #320
Conversation
ac80c44
to
5b48abb
Compare
Should a tag delete be allowed, or deleting the manifest that the tag points to? If it is, could the tag be deleted and recreated to point to different content? And if it's not, is this a potential attack where an attacker with short term access to a repository is able to force that repository to permanently host their content? I'm also conflicted if we should be defining a standard tag naming scheme vs only defining the http response to various API calls when an immutable tag is encountered. The latter would leave the decision of when to enforce immutability up to individual registries. E.g. many users may only want their release tag with a version to be immutable, without needing to change their versioning tag to match this. |
One difficulty with this convention is that it's not clear whether the registry will enforce it -- today, no registries enforce it, and rolling out support will inevitably be slow, especially to all the on-prem registries. Some registries will just never support it. The only thing worse than mutable tags is the illusion of immutable tags. 😆 Perhaps we should have the format of an immutable tag be something that's not a currently valid tag, so it's clear to users that any registry that accepts the tag will definitely enforce that it's immutable. Throwing out ideas: a tag can't start with
The downside of course is that clients would have to update their image reference validation logic to accept and understand these new semantics, and rollout of that would also be slow. At least support for the feature would be unambiguous. |
@sudo-bmitch deletion is an interesting one. I would say no, but for legal reasons, you probably have to allow some form of delete. Instead of normal deletion, once "deleted" the tag could return an error. Which means you have to keep track of old tags. Also, it's arguably not immutable... |
Something I've wanted to do for a while is improve the tag listing API, outputting a map of tags to descriptors instead of only an array of tag names. Perhaps adding a way for registries to indicate a tag is immutable in that list would be useful. This would be more of a long term option since updating that API would take time. |
Deletion is allowed, but a deleted tag shouldn't be repurposed to refer to another content.
Immutability has to be known ahead of calling the HTTP API, so it has to be encoded in the tag strings.
Nothing will be enforced by this spec. E.g., a future version of But it will never raise such an error for images that do not have
Looks too cryptic 😅 |
5b48abb
to
1a292e8
Compare
Updated PR for rewording |
I think this is a fundamental flaw with this approach. If you want to enforce that
Sure, but a future version of I'm not saying it's ideal, it's definitely a large undertaking for both registries and clients to rollout support (and again, some never will!), but if the goal is immutable image refs, I don't see any other way to safely and unambiguously support that. |
1a292e8
to
8e79821
Compare
The immutability isn't really expected to be enforceable by the registry, as the registry nodes may have a distributed database that does not guarantee serializable consistency. And even if the registry claims to be capable of enforcing immutability, the client should't trust that claim.
Registries do have conformance bugs. I updated the PR to let the
Rolling out the new spec will probably take more than 3 or 5 years 😕 |
A tag MAY be recreated to refer a diferrent content. However, a tag with "-immutable" suffix, such as "1.2.3-immutable", SHOULD NOT be recreated with a different content. (Not "MUST NOT", because a registry implementation might not be aware of the history of the tag) Closes issue 241 Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
8e79821
to
f5231f9
Compare
Sure, but I'd say that becomes an issue between the user and their registry vendor at that point. Same as if a registry claims to reliably persist data, and doesn't. If a registry doesn't (or can't) reliably enforce immutability, it shouldn't advertise that it does.
That's true, but I'd prefer to have data to suggest that, rather than rely on speculation when discussing this change. I think the extension idea is a step in the right direction. The extension mechanism might even mean this is something that doesn't need to be specified in this exact spec, but only in some "official" extension defined... somewhere? |
I've been thinking over this one a bit. Is there a need for the client to know the tag is immutable without contacting the registry? I.e. does it need to be in the syntax of the tag, or can it be discovered by an API? If discovery by API is enough, then I'd lean towards not defining the tag schema, and instead having the extension API to identify which tags are immutable, update the tag listing API, or even do both. That gives the flexibility of defining which tags can be immutable back to the user and registry operators. |
Yes, this should be in the syntax of the tag just like Otherwise we will have to update a bunch of other specs to support pulling an image tag that does not match the foreknown digest.
e.g.,
$ docker run --immutable-tag example.com/foo:1.2.3@sha256:deadbeef...
services:
foo:
image: "example.com/foo:1.2.3@sha256:deadbeef..."
immutable_tag: true
FROM --immutable-tag example.com/foo:1.2.3@sha256:deadbeef...
apiVersion: v1
kind: Pod
metadata:
name: foo
annotations:
# Eventually this will be moved from an annotation to the regular Pod spec
immutable-tags.security.alpha.kubernetes.io/foo: true
spec:
containers:
- name: foo
image: "example.com/foo:1.2.3@sha256:deadbeef..."
$ trivy image --immutable-tag example.com/foo:1.2.3@sha256:deadbeef...
It should be noted that even if the immutability is discoverable via the OCI Distribution Spec API, the CLIs and the YAMLs have to have "immutable-tag: true" field as the OCI registry server might be compromised and might return false information about immutability. |
Implementing the current proposal for containerd:
|
Thinking through the containerd example, I think there are some other options to consider: Option 1:
This is probably the easiest to implement since we just need to define something like an annotation. Security isn't perfect since a malicious registry could still change what the tag points to. The other option, since we may not want to pull the manifest twice (e.g. rate limit concerns): Option 2:
This isn't great since we'd be stuck waiting for the registry to support a new header. The last option that I like the best is to not handle this with immutability. Instead, defer to signing solutions: Option 3:
|
Late to the party. I agree with @sudo-bmitch -
Tags have been opaque strings. Introducing semantics like that is technically a breaking change. People shouldn't name mutable tags as "xxx-immutable", but we really cannot control how they have used containers. |
Thank you @sudo-bmitch The background of my proposal is to let The option 1 might be acceptable if we can store that immutability annotation in the digest database, but I still think it is easier to use when the immutability is encoded in the image reference string. Option 4: encode immutability into the “query” part of the image ref string, e.g., |
Regarding the pinning use case, shouldn't the immutability enforced by the end user who write Dockefile and Dockerfile.pin? Let's say I'm writing Dockerfile and want to enforce immutability regarding images, I don't want to wait registries and image vendors to support the immutable notation. Clients such as Docker Engine could enforce that without waiting them. |
Option 4 doesn’t need any modification to the reg and the images, but clients should share the same reference spec. |
Maybe a dumb question but why can't we trust the registry server about tag immutability? Registries could deny pushes to tags it knows as immutable, ensuring they stay that way. If this is a security problem, then @sudo-bmitch's option 3 seems better suited. If this is about pinning images on a Dockerfile then why not refer to their digest instead? I'm late to the discussion so probably missing something. |
Because the registry server can be compromised
This is actually expected to be used with the digest, either manually or automatically with human-friendly digest locking utilities such as |
Would you mind elaborating? What kinds of risks do you see?
I wonder if we really need immutability to accomplish this? Does matching the digest of a manifest pulled with image:tag@digest against the provided digest accomplish the same thing? I.e pulling golang:latest@sha256:a2b3 and getting anything other than the manifest with digest sha256:a2b3 causes an error. Immutability could then be tackled separately, and used together with the above referencing "style". To clarify my position: I like the idea of tag immutability - it's something we have discussed in Quay and want to eventually support - I'm just trying to understand this. |
It may help to define the various scenarios for immutable tags:
And those scenarios have various use cases:
What other scenarios/use cases am I missing? Drawing these out and identifying the possible attacker scenarios may help identify the different options we have to implementing a soltuion. |
that's very helpful @sudo-bmitch, thanks! |
A tag MAY be recreated to refer to a diferrent content.
However, a tag with
-immutable
suffix, such as1.2.3-immutable
, SHOULD not be recreated with a different content.(Not "MUST not", because a registry implementation might not be aware of the history of the tag)
Closes #241