Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Signature specification #214
Signature specification #214
Changes from all commits
2ef1b90
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh, how are they going to actually do that?
(In a single public key root of trust, I agree that supported schemes/algorithms are a property of that root of trust along with the raw public key, and should be a part of the same root-of-trust configuration set up by users. But with certificate chains that gets more difficult; x.509 certificates AFAICS include a public key signature algorithm, but not really a specific signature form/encoding scheme.)
I don’t have a better proposal, just noting that this is difficult.
Essentially this hinges on the hash algorithm choice; given that, things like the OpenPGP design include the algorithms inside the signed data, so maliciously modifying that would require breaking the signer-chosen public key algorithm or hash (both trusted by assumption), substituting the public key algorithm for a weaker one (fixed in client configuration for simple roots of trust, or included in X.509 certificates), or substituting the hash algorithm for a weaker one (no defense?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice the scheme is as you described - they're either stored a property of the public key itself or somewhere adjacent to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s practical short-term but problematic longer-term if we ever need to transition from SHA256:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I agree - we should think through and document what the migration from sha256 to something else might look like.
My understanding though is that copying an image from a sha256 registry to a post-sha256 one would result in a new image. Since there are unique images for each registry, we would need unique signatures for each registry. But exactly what that copy/migration process would look like is really a guess at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My hypothesis is that, in order to avoid a flag day and breaking digest references entirely, there will be some mechanism to represent manifests that contain both the SHA256 digest and the new digest of each blob (e.g. by using SHA256 in the designated descriptor field, and the new digest in an annotation). So it should in principle be possible to have a byte-for-byte identical image in two different registries, accessible using the same
@sha256:…
digest on both, and using some@new-digest:…
on the updated registry — and it would be nice to keep signatures working when copying the image across.OTOH it might be possible for the signer to create two separate signatures using the two hash algorithms, and publish both along with the image, so this would not be a deal-breaker.
Another concern in such a situation is that the hash algorithm is essentially registry-chosen: given a
repo:tag
reference, I understand “digest be calculated using the SAME algorithm as the OCI registry” to mean “use the algorithm returned by the registry in theDocker-Content-Digest
header of https://github.com/distribution/distribution/blob/main/docs/spec/api.md#existing-manifests ”, or something like that. The signature scheme should protect against malicious registries, and giving registries this point of influence feels risky.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very very good point. I was imagining the algorithm would actually be user controlled in this scenario, but this reinforces that we need to think through it with the OCI folks a bit more. The responsibility on digest calculation is sort of split between users and registries today - the Header from the registry is one place that is registry controlled, I was imagining it would be the one set by clients on upload though: https://docs.docker.com/registry/spec/api/#pushing-an-image
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quickly skimming docker/distribution , it seems that the implementation can’t look up by arbitrary digests (that would be hard), it essentially chooses its own digest algorithm during blob upload, the clients then must use that one for references.
But that’s not very relevant to the future migration scenarios; many implementations probably hard-code SHA256 in various places, and we don’t know for sure which components will be responsible for which choices in the future.
More to the point, even if the process will end up as uploader-controlled, a malicious registry can just lie and return a different digest (or an attacker with unwanted write access to the repo can upload an image with the uploader-chosen different digest).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that a malicious registry can return different content to different victims.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mitigated by pulling by digest, which is an independent UX issue. Even pulling by tag, assuming clients verify signatures, we'd only need to ensure that the content being pushed to the registry is what we're actually signing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neither the signatures nor their metadata are protected by the image digest. (And any end-user of the signed image doesn’t know the digest already, otherwise signatures wouldn’t be necessary.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I agree with this part - signatures are useful even when pulling by digest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My mistake, the non-repudiation property of the signature (and perhaps any associated metadata) could still be useful, apart from the minimal (signer, name/purpose/identity, binding) essential to the signature.