containers / image

Work with containers' images
Apache License 2.0
869 stars 381 forks source link

Request for Sigstore signature verification enhancement and flexibility in cosign verify. #2027

Open zhaoyonghe opened 1 year ago

zhaoyonghe commented 1 year ago

Currently, we are able to verify container images with sigstore signatures using public key/Fulcio/Rekor, as described here. However, there are additional verifications supported by cosign, such as verifying signatures using non-Fulcio roots, as demonstrated in this pull request.

An example of the cosign command for verifying signatures using non-Fulcio roots is:

SIGSTORE_ROOT_FILE="certificate_bundle.pem" cosign verify \
  --certificate-identity-regexp "identity-.*" \
  --certificate-oidc-issuer-regexp ".*" \
  --timestamp-certificate-chain tsa_ca_chain.pem \
  "${image}"

Is it possible to add support for this functionality? Moreover, could we take a step further and match fields in /etc/containers/policy.json with the cosign verify parameters to enable the execution of all forms of cosign verify?

/cc @mtrmac Thank you for your attention to this matter.

mtrmac commented 1 year ago

Thanks for reaching out.

We are, for the foreseeable future, very unlikely to include all of cosign features (that would essentially require including much of cosign codebase, and c/image is used in size-constrained tools like Podman).

Individual features can be added (and I expect more Fulcio-matching features in particular), but that would probably be on a feature-by-feature basis, if they are necessary and supportable.

As some random few comments

lkatalin commented 10 months ago

It sounds like this request needs to be broken down into specific, individual feature requests that can be evaluated and implemented:

@zhaoyonghe @dmitris Did I miss any?

@mtrmac Would it be useful to file these as separate issues?

zhaoyonghe commented 10 months ago

Thanks @lkatalin for bringing up this issue again.

We use cosign internally, signing internal images without relying on public sigstore infrastructure to comply with company policies. To achieve keyless signing, we are inspired by Chainguard's "Keyless" Code Signing Without Fulcio - Nathan Smith, which outlines setting up a private sigstore with three entities:

  1. Identity provider for signers
  2. Certificate authority
  3. Timestamp Authority

We use Athenz and Crypki (OIDC provider and CA infra already existed in our company) and the sigstore timestamp authority to match this grocery list. Our blog provides more details on our sigstore infra and cosign verify usage.

In general, it would be great to support the equivalent check as:

SIGSTORE_ROOT_FILE=codesigning.ca.cert.pem \
cosign verify \
--insecure-ignore-tlog \
--insecure-ignore-sct \
--certificate-identity-regexp "^spiffe://screwdriver.proj/sa/sd.*$" \
--certificate-oidc-issuer-regexp "https://athenz.example.org" \
--timestamp-certificate-chain tsa.ca.cert.pem  \
"registry.example.org/myorg/myrepo@sha256:123456"

These five flags are essential from our perspective and can be separate requests!

mtrmac commented 10 months ago
  • [ ] Functionality for passing in signing certificate identity on the CLI during verification with --certificate-identity-regexp

It is a fairly strongly-held design decision of c/image that all verification configuration is set up in policy.json; that way we don’t have to add a few dozen/hundred individual options to the CLI of every single tool (e.g. podman/buildah/skopeo, and CLI options are outright impossible to use with Kubernetes Pods). Typically the policy should be the same throughout the relevant organization, so copy&pasting the arguments should be much less convenient and less maintainable.

I am also still pretty skeptical about regexes, because they encourage imprecise identities. Compare the detailed design discussion and concerns in https://github.com/containers/image/pull/2235 .

  • [ ] Functionality for passing in OIDC issuer identity on the CLI during verification with --certificate-identity-regexp

Same here; that should be in policy.json. And I’d like to see a real use case documented (not .*, and not a match that doesn’t need to be a regex).

  • [ ] Functionality for passing in the timestamp authority (not necessarily tlog) certificate chain on the CLI during verification with --timestamp-certificate-chain

Again, not a CLI option.

Supporting a timestamp authority instead of Rekor does seem quite valuable to me, I don’t think most users actually benefit from the complexity of Rekor.

  • [ ] Functionality for passing in the signing certificate chain on the CLI during verification with --signing-certificate-chain

A root of trust belongs in policy.json. Why would an image signature not contain all the intermediates required to accept that signature against the anticipated policy?

@mtrmac Would it be useful to file these as separate issues?

There seems to be a shared theme around policy.json, but other than that, yes, I’d prefer to track every feature/option separately.


Our blog provides more details on our sigstore infra and cosign verify usage.

(Added to my reading list, but I didn’t read it yet; it’s possible that resolves some of my concerns.)

mtrmac commented 2 months ago

2432 is working on supporting non-Fulcio PKIs.

dmitris commented 2 months ago

2432 is working on supporting non-Fulcio PKIs.

@mtrmac but that issue was closed as "not planned" - does it mean it was closed because of being a duplicate of this one (#2027)?

mtrmac commented 2 months ago

My mistake, https://github.com/containers/image/pull/2579 is where the work has started.

dmitris commented 2 months ago

@mtrmac one related question, in the spirit of "where the pack is going" 😄: the cosign tool and the underlying libraries such as sigstore-go are moving toward the Trust Root mechanism for "bundling" all the necessary public keys (identity, timestamp server CAs etc.). Should we consider supporting that format?

mtrmac commented 2 months ago

Currently c/image doesn’t have the ambition to support all options that exist in cosign, or that may be added in the future; so it’s not immediately applicable.

Conversely, the policy.json file exists to describe different policies based on various namespace scopes, which seems not possible in that trust bundle format.

Also c/image has a strong opinion that the signed image identity critically matters, unlike cosign — so the two tools would, often enough, not evaluate “the same” policy the same way.

It would be possible to add a policy.json option to specify some options by that trust root file, rejecting any files with unknown options… there’s some value in that (e.g. system configuration tools would only specify/update the policy once), but it would have significant limitations, and users would have to test the two tools’ handling of the updated policy separately, in either case. So I’m not sure this would be all that helpful, a bit of convenience bundled with a risk of several unwelcome surprises.