I am trying to verify container images using Cosign.
Let's use the image csi-node-driver-registrar as an example. (the image doesn't matter as long as it is signed by the author)
I tried the following CLI command and it successfully verified the image:
cosign verify registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.9.3 --certificate-identity [email protected] --certificate-oidc-issuer https://accounts.google.com
However, I got the working values for "certificate-identity" and "certificate-oidc-issuer" by running the command with random wrong values. (so I saw the correct values in the error message) This is like a joke, isn't it?
So I really need some explanations about the following points:
- How does Cosign sign and verify images in the "keyless" mode?
I read the official document but it completely lost me. I understand the basic concept about signature (the private key encrypted hash code of the original data) and the verification (decrypt by the public key and compare the 2 pieces of hash code).
- How do I find the correct "certificate-identity" and "certificate-oidc-issuer" in case the image is not created/signed by me?
Many thanks!! I spent much time on Googling without any luck.
After a few hours searching, reading, and guessing, now I try to answer my own question.
When an image was signed by Cosign in the "keyless" mode, the private key in Fulcio's "root trust" bundle was used to create the signature, so the corresponding public key should also be used for the verification.
In other words, regarding signature creation, "keyless" doesn't mean no key is used. It just means users aren't required to provide a key --- an "official" private key will be used instead.
Based on the above, to verify such image signatures, Cosign will also request the private key from Fulcio. However, when creating the signature, some extra information is also added in as well as the hash code, so when verifying the signature, the extra information can also be verified as an additional layer of security.
The extra information is the so-called "certificate identity" and "certificate oidc issuer". When Cosign is signing an image that is stored in a container registry, it expects the container registry to be an "IDP", from which it retrieves an ID Token providing the user can successfully logon to the container registry (The "cosign sign" command will open a web browser window and take you to the logon page of the container registry).
After that, Cosign extracts the "id" claim from the ID Token, and save it along with the "IPD"'s URL into the signature.
The verification process will compare the saved "id" with the one you specified through the "certificate-identity" argument to make sure the image comes from the expected author. You can use "--certificate-identity-regexp '.*'" to walk around this check, but of course it's insecure to do so.
Anyone please correct me if I'm wrong. Thanks.