-
Notifications
You must be signed in to change notification settings - Fork 1.1k
image: serialize RegistryImageReferences when checking signatures #8605
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
image: serialize RegistryImageReferences when checking signatures #8605
Conversation
| // Such image references are supported by docker but, due to their ambiguity, explicitly not by containers/image. | ||
| // | ||
| // This should only be called from internal/storage. | ||
| func RegistryImageReferenceFromRawSerialized(rawNamed reference.Named) (RegistryImageReference, error) { |
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.
not crazy about this name, @mtrmac do you have any suggestions?
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.
See the other comment for a bit higher-level view…
… which still leaves open the naming of this canonicalization. My starting point is canonicalize{TagDigest,DockerLike} somewhere in the name, but that might get awfully long.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #8605 +/- ##
==========================================
- Coverage 48.91% 48.85% -0.07%
==========================================
Files 153 153
Lines 17372 17371 -1
==========================================
- Hits 8498 8486 -12
- Misses 7807 7819 +12
+ Partials 1067 1066 -1 |
|
/retest |
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.
ACK to the overall functionality this achieves.
WRT the implementation … my question is “what rules are implied by the RegistryImageReference data type”? I think it should be one of:
- :tag@digest references are unambiguously allowed by the data type.
- In that case the mapping of :tag@digest to @digest-only must be in consumers of
RegistryImageReference, i.e. inPullImage/IsRunningImageAllowed(and what value should be used inMetricImagePullsSuccessesInc, with or without the tag?) - or maybe
RegistryImageReferenceshould have aRawCanonicalizedmethod that returns a value suitable for c/image, and most callers ofRawshould migrate
- In that case the mapping of :tag@digest to @digest-only must be in consumers of
- :tag@digest references are unambiguously invalid in the data type. In that case
- the constructor of
RegistryImageReferenceFromRawshould reject that value to enforce the rule - It would be consistent for
ParseRegistryImageReferenceFromOutOfProcessDatato reject the data as well - We’d probably need some kind of
…FromRawCanonicalizingandParse…CanonicalizingFromOutOfProcesss…helpers, so that top-level callers don’t manipulate values directly.
- the constructor of
The current PR is ambiguous about the permissibility of such values — the text parser canonicalizes them, but …FromRaw does not.
I weakly prefer the variant where :tag@digest values are invalid in RegistryImageReference, forcing its users to explicitly choose, by the constructor they call, whether they want to accept such values or not. If nothing else, the parseImageParent/parseImageChild RPC should never generate such values, and it can use the stricter parser/constructor.
| // Such image references are supported by docker but, due to their ambiguity, explicitly not by containers/image. | ||
| // | ||
| // This should only be called from internal/storage. | ||
| func RegistryImageReferenceFromRawSerialized(rawNamed reference.Named) (RegistryImageReference, error) { |
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.
See the other comment for a bit higher-level view…
… which still leaves open the naming of this canonicalization. My starting point is canonicalize{TagDigest,DockerLike} somewhere in the name, but that might get awfully long.
| [[ "$output" == *"SignatureValidationFailed"* ]] | ||
| } | ||
|
|
||
| @test "allow signed image with restrictive policy on container creation7 if already pulled (by tag and ID)" { |
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 fundamentally confusing things. “Image ID” (StorageImageID) is, historically (nowadays not always) the sha256 digest of the config, and usually expressed without the leading sha256:.
“image digest” is the sha256 of the manifest. The two are ~never the same for a single image.
In busybox:latest@sha256:…, the second value is the manifest digest. So assuming the value from crictl images -q is an image ID, using it in the manifest digest syntax should never find a match; and the test name is misleading.
(Also for the other added test.)
d5053b0 to
0841f69
Compare
|
I agree the library should take care of canonicalizing. In fact, I just replaced *FromRaw with this behavior. Also i believe I updated the test to test digest and not storage ID. PTAL again @mtrmac |
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’d prefer two variants of constructors, one only in the “XOR” form, one canonicalizing — but this works, up to you.
Assuming this design, code LGTM, just some documentation suggestions.
| // It does two validations on rawNamed: | ||
| // - It validates the image either has a tag or a digest, but not both (preferring digest) | ||
| // - Verifies the image is not only a name. |
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.
(The first one is a silent fix-up, and the second one causes an error; the phrasing suggests to me that both are treated equally.)
| if isTagged && isDigested { | ||
| canonical, err := reference.WithDigest(reference.TrimNamed(rawNamed), canonical.Digest()) | ||
| if err != nil { | ||
| return RegistryImageReference{}, err |
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.
(The only way this can fail is if canonical.Digest() is invalid, and that shouldn’t have happened by induction, so I’d be fine with a panic here. But returning an error explicitly is perfectly valid as well.)
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 better because then I don't need to change the function signature
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.
Also using panic does not leave around (supposedly) 100% unreachable error handling code paths, considering that CRI-O is measuring code coverage.
| } | ||
| ref = reference.TagNameOnly(ref) | ||
| return RegistryImageReferenceFromRaw(ref), nil | ||
| return RegistryImageReferenceFromRaw(ref) |
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.
The documentation of ParseRegistryImageReferenceFromOutOfProcessData should document that it removes the tag from tag@digest inputs.
| // Strip the tag from ambiguous image references that have a | ||
| // digest as well (e.g. `image:tag@sha256:123...`). Such | ||
| // image references are supported by docker but, due to their | ||
| // ambiguity, explicitly not by containers/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.
(Absolutely non-blocking: Consider preserving some form of this comment, to have a documentation for the reason we modify the inputs.)
0841f69 to
2a3a5fc
Compare
| // It is only intended for communication with OUT-OF-PROCESS APIs, | ||
| // like registry references provided by CRI by Kubelet. | ||
| // It will modify the reference if both digest and tag are specified, stripping the tag and leaving the digest. | ||
| // It will also verifies the image is not only a name. If it is only a name, the function errors. |
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.
The function does not fail in such a situation: The TagNameOnly call turns name-only references into name:latest
2a3a5fc to
b7c5e6d
Compare
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.
Do you also want to fix the linter-highlighted typo?
LGTM either way.
So we can check a signature of an image that has both a tag and a digest Signed-off-by: Peter Hunt <[email protected]>
b7c5e6d to
4a2d29e
Compare
|
whoops, fixed! |
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.
/lgtm
|
/cherry-pick release-1.31 |
|
@haircommander: once the present PR merges, I will cherry-pick it on top of release-1.31 in a new PR and assign it to you. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: haircommander, kwilczynski The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/retest |
2 similar comments
|
/retest |
|
/retest |
|
@haircommander: new pull request created: #8618 In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
What type of PR is this?
/kind bug
What this PR does / why we need it:
So we can check a signature of an image that has both a tag and a digest
Which issue(s) this PR fixes:
fixes #8603
Special notes for your reviewer:
Does this PR introduce a user-facing change?