containers / image

Work with containers' images
Apache License 2.0
845 stars 366 forks source link

support multiple sigstore keys #2319

Open msmeissn opened 4 months ago

msmeissn commented 4 months ago

Feature request description

At SUSE we currently want to transition the sigstore signing key from a RSA 2048 to 4096 bit key. During the transition time, there might exist containers signed with either of the keys. Currently, podman seems to be able to only configure 1 key for sigstore signing, not multiple ones.

Suggest potential solution

Support multiple sigstore keys, or perhaps reading from an index directory.

Have you considered any alternatives?

A clear and concise description of any alternative solutions or features you've considered.

Additional context

Add any other context or screenshots about the feature request here.

Luap99 commented 4 months ago

@mtrmac PTAL

mtrmac commented 4 months ago

Thanks for reaching out. Yes, that should eventually happen. Transferring to c/image.

dcermak commented 1 month ago

We've had a thought with @danishprakash about how this could be implemented. A very simple way would be to change the loop in https://github.com/containers/image/blob/6caf212454493ef1979393c398ac705aebb393a6/signature/policy_eval.go#L281

to accept a signature if at least one policy matches instead of requiring all policies to match.

That would allow you to write the following policy.json:

{
    "default": [
        {
            "type": "insecureAcceptAnything"
        }
    ],
    "transports": {
        "docker-daemon": {
            "": [{"type":"insecureAcceptAnything"}]
        },
        "docker": {
            "registry.suse.com/bci": [{
                "type": "sigstoreSigned",
                "keyPath": "/usr/share/pki/containers/suse-container-key.pem",
                "signedIdentity": {
                    "type": "matchRepository"
                }
            },
            {
                "type": "sigstoreSigned",
                "keyPath": "/usr/share/pki/containers/old-suse-container-key.pem",
                "signedIdentity": {
                    "type": "matchRepository"
                }
            }]
        }
    }
}

And the container image would validate, if it is signed by either /usr/share/pki/containers/suse-container-key.pem or /usr/share/pki/containers/old-suse-container-key.pem.

The big advantage is, that you get support for multiple GPG keys as well "for free". Or you can now have a part of your images signed by sigtore and a part by GPG.

However, this is a breaking change in the behavior and has other ramifications. E.g. you can no longer enforce sigstore and GPG signatures to match. I am unsure whether that is actually used in production anywhere, but the behavior would change.

We can of course convert keyPath to keyPaths (or add support for both fields), but this would be a bigger code change and it would have the disadvantage, that it would have to be implemented for every policy type (sigstore, GPG, etc.).

Any thoughts/opinions?

mtrmac commented 1 month ago

The semantics of multiple requirements is already defined to be an AND, and users might rely on that for security.

It‘s just not an option to silently change that behavior.

If we absolutely had to, we would need a format change that breaks all users so that they have to read the documentation and update, but that’s very likely to unexpectedly break systems on an upgrade … and what would the users who designed their system around an AND do if we removed the AND feature?


As a, let’s say, vague intuition: I don’t think OR in a policy language, as a general feature, is a very good idea.

I really don’t want the policy to be Turing-complete, because that makes any automated policy enforcement / audit impossible.

And policies with OR mixing different kinds of policy requirements… are hard to reason about. What does that mean / what objective does that achieve? Sure, we can probably construct some situations where that would be useful, but usually a policy has some set of objectives that should directly map to PolicyRequirement objects. And then there may be a bit of complexity inside that PolicyRequirement.

If we add OR, pretty soon someone is going to ask for NOT… when, vaguely speaking, what is missing is quite likely to be a single feature that could be added as a native condition, with good documentation, end-user guidance, and error checking, instead.

Compare Polkit — which has had a JavaScript interpreter added, and now we can’t get rid of it (for a structurally similar reason why we can’t change the AND to an OR here — removing the interpreter could stop enforcing an important policy, or it would have to break systems to force administrators to update).


We have already added keyPaths to type: signedBy, as an alternative to keyPath; adding that field to type: sigstoreSigned would make the two more similar, so that’s very attractive to me.

(Alternatively, there is a RFE floating around to support specifying a CA which issues certificates, instead of raw keys. That might work for the migration, but then we would need to worry about revoking the old key. So, even if we did add a support for a CA, I think we would still want the simple keyPaths.)

msmeissn commented 1 month ago

we could also think of having a key file including multiple PEM keys, but it feels more hacky even and is not well defined.

Still I would ask to somehow have these kind of transition possibilities.

mtrmac commented 1 month ago

Yes, this is definitely a feature we also need for our customers.

I don’t know when exactly I’ll get to work on it, though — my best guess is weeks to months.