opencontainers / artifacts

OCI Artifacts
https://opencontainers.org
Apache License 2.0
224 stars 54 forks source link

WIP generic object spec #37

Closed justincormack closed 1 year ago

justincormack commented 3 years ago

Previously at https://gist.github.com/justincormack/523dc229f0dd7b882edf19c60aed1581

Here for more detailed comments.

Signed-off-by: Justin Cormack justin@specialbusservice.com

SteveLasker commented 3 years ago

I also don't see any discussion of how to roll this out. It's great that this might prevent us from having to make breaking changes in the future, but this proposal itself is a pretty large change. Given that there are clients around still pushing and pulling schema 1 images, I'm somewhat reluctant to sign up for another migration.

The idea of implementing a new manifest schema is it allows artifact clients to opt-into them.

Here's the inverse question: How do we enable artifact signing, including image signing, without changing the existing image toolchains?

The premise of signing verification is its opt-in. The existing container runtimes continue to function, without changes. If you want to implement gated execution, you'll need some signing verification to occur.

This can be done:

  1. By a gate, before the host is asked to run net-monitor:v1. This is the OPA/Gatekeeper validation. If the gate says it's ok to run (ingress controller validation), the k8s host is requested to run the image. The only change to the existing tool chains is an ingress controller validation, which is new code, new flows, and non-breaking to the existing image runtimes.
  2. By a client/host, which means it's new code to be deployed, which would know to check for signatures and verify them. Let's say containerd supported signature validation. A containerd plug-in could be added that does the same thing as the opa/gatekeeper validation. As the request comes to containerd, the signature is requested and verified. Only if it passes, does the containerd host run the image. The host code that pulls and runs the image didn't change, it was the plug-in that saw the request for net-monitor:v1 and used the /v2/_ext/oci-artifacts/v1/<repo>/manifests/<digest>/references?artifact-type=vnd.cncf.notaryv2 API to find signatures, pull them, verify them, before allowing the host to proceed.

This allows us to proceed with:

  1. storing signatures
  2. linking signatures to the thing they're signing
  3. tracking for garbage collection of content
  4. image toolchains to have zero change, zero risk of breaking them
  5. when image toolchains want to start using this format, they can.

Image toolchain updates:

We know folks want to add new compression formats. As those folks want to experiment, they can use this new format. This will likely take more time, and that's ok, as we've at least given them a way forward, as it appears there are more problems than answers for the compression format discussions at current.

There are some thoughts about how we can down-convert the new format to the existing format, but I don't think we know everything here. It's an example of what we need to validate.

However, the new manifest approach allows us to decouple any existing client changes, with the ability for the existing clients to opt-in.

The biggest change is really for existing registries to implement this change.

By adding a new manifest, or anything new including a new version of the image-spec, the registry can make an explicit statement of whether it supports the new behavior.

This is actually the biggest positive, as the most expensive change for a registry to implement is garbage collection. If we're going to implement new garbage collection and ref-counting semantics, it would be nice to have some focus on one change that enables a few scenarios. Today, we have garbage collection loosely defined (at best) for two manifests (image-manifest, image-index). Wouldn't it be nice to start defining the user expectations around GC?

vbatts commented 3 years ago

@justincormack might we split sentences out to their own line, please

lumjjb commented 3 years ago

Was pointed here from https://github.com/opencontainers/artifacts/pull/15 for image encryption. I think this aligns pretty well with image encryption, especially since we do have this requirement of wanting to be able to add more key authorizations via wrapped keys after an image is already encrypted (for example, giving access to a image scanner by wrapping a key with the service's public key)... Right now, its done via a list in annotations, but this will be much easier to manage the wrapped keys.

On a totally separate note, I think the story around signing and verification may become a little more complex. Disclaimer: ​I haven't been on top of the latest discussions on this, so maybe @SteveLasker or someone else can educate me on the thoughts around this

My concerns around signing/verification are:

SteveLasker commented 3 years ago

Hey @lumjjb,

Signing a manifest would be difficult if it is designed to keep changing (if I understood the proposal correctly).

Are you inferring it can keep changing because a single manifest can support multiple versions of an artifact?

Due to the content-addressable storage, we're still designing around every manifest is a fixed object, with a digest. If you want add new version support, you'd push a new manifest with the previous versioned content (meaning non-encrypted) and the new versioned content, encrypted. You would sign the new digest, and associate it with an existing tag. So, the user that pulls a specific tag: net-monitor:v1 could, over time, get encrypted content without changing the original content. A downstream client could pull the non-encrypted content, and a client that understands the newer version could opt-into the new content.

The Notary v2 proposal and I believe cosign as well, is to push a detached signature that references the artifact it's signing. You can push multiple signatures, or multiple referenced objects as below:

lumjjb commented 3 years ago

I see. Yea that is the issue i'm thinking about (but not including encryption), and I suppose the validity of a manifest would be based on some value in the metadata/SBOM that is signed, so checking is on that level instead of having snapshot signatures (like in TUF) to invalidate older signatures.

I think this clarifies my question around the manifest. Thanks @SteveLasker !

SteveLasker commented 3 years ago

validity of a manifest would be based on some value in the metadata

The Notary v2 model signs the digest of the manifest, which is why it's so important the digest doesn't change. And, you can submit multiple, independent, signatures on the same image. For instance, content promotion within or across registries.

We'll have the ability to invalidate a key or a signature, and the ability to sign a tag.

cmoulliard commented 3 years ago

When is it planned to approve this spec and implement it ?

SteveLasker commented 3 years ago

Hi @cmoulliard, Can you tell us a bit about what use cases you’re looking for?

SteveLasker commented 3 years ago

ahh, I see. The build pack reference. I’ll read through the above PR. This PR wound up getting paused as it has some challenges. We have started implementing an evolution of pr#29 at https://github.com/oras-project/artifacts-spec The latest release has links to a distribution and oras based reference implementation

mikebrow commented 1 year ago

FYI artifacts mission is moving to opencontainers/image-spec this repo is being archived, great ideas in here btw!

mikebrow commented 1 year ago

closing for now due to pending archive action.. pls reopen if archive is not completed and/or if you believe this close to be in error