support OciDirectory for syft attest cmd
What would you like to be added:
We (w/@dentrax) encountered the following error when we export an OCI layout into a directory with skopeo tool:
$ skopeo copy docker://docker.io/alpin:3.16 oci:oci-layout
$ syft attest --key cosign.key oci-layout -o spdx-json > att.json
2022/06/24 08:25:45 error during command execution: attest command can only be used with image sources fetch directly from the registry, but discovered an image source of "OciDirectory" when given "oci-layout"
The errors come from this line here, we couldn't make sure whether it is intended but it'd be better to support OCI directories in attest command.
Why is this needed:
We don't want to make a network connection several times to the container registries, so, we pulled the image once into an OCI directory and use it everywhere hence we need to run attest command against this directory.
Additional context: If this is in your TODO list, we're willing to help, just assign it to us.
We deep dived into code a bit and found a switch condition where error thrown from:
switch si.ImageSource {
case image.UnknownSource, image.OciRegistrySource:
si.ImageSource = image.OciRegistrySource
default:
return nil, fmt.Errorf("attest command can only be used with image sources fetch directly from the registry, but discovered an image source of %q when given %q", si.ImageSource, userInput)
}
The idea is to support OciDirectorySource but we need to find a way to calculate oci-layout folder that we have exported.
Tried "golang.org/x/mod/sumdb/dirhash" package using hD, err := dirhash.HashDir(si.Location, "", dirhash.DefaultHash) function, but the calculation quite different from what I expected.
Are there any good way to calculate digest from oci-layout folder to get exact same result of how crane digest foo:bar did. If there isn't we might think of introducing a new flag smth like --digest <string> to pass manually.
cc @spiffcs
The content hash in the attestation should be addressable in practical sense, otherwise users of the attestation would not be able to check if the payload they are validating is the same as what's described in the payload. The registry is the single authority that determines what the digest is, though the OCI spec does indicate how the digest is calculated, there are implementation details that follow the OCI spec but could resolve in different digests.
Today we only support sources which the image digest can be positively fetched from for use in the attestation. This is to the benefit of the user: it is difficult to generate attestations with incorrect/unusable content hashes.
I feel if there is a need for an attestation using a local OCI layout directory you could combine syft + cosign on the CLI to achieve this (but not recommended).
Is there a specific use case that would motivate needing to create an attestation from a local OCI layout directory instead of from a registry? (in your example the first step pulls from a registry)
Hey @developer-guy, we are going through some old tickets and I wondered if this is still an issue for you, or if we can close it out? Thanks!