syft icon indicating copy to clipboard operation
syft copied to clipboard

Upload SBOM directly to OCI registry

Open developer-guy opened this issue 2 years ago • 16 comments

What would you like to be added:

cosign supports attaching SBOMs to OCI registries[^1] (also has a spec for it [^2]), so we (w/@dentrax) thought that it would be nice to have the same one for Syft, here is the design that we thought.

$ syft packages <image> -o oci://<repository>/<image>

Why is this needed:

Additional context: [^1]: https://github.com/sigstore/cosign/blob/1f67ea73113f76c62429aa605d75105d77c370fa/cmd/cosign/cli/attach.go#L57 [^2]: https://github.com/sigstore/cosign/blob/main/specs/SBOM_SPEC.md

cc: @dlorenc @luhring

developer-guy avatar Oct 26 '21 09:10 developer-guy

we (w/@dentrax) are the volunteers of this issue, btw 😍

developer-guy avatar Oct 26 '21 10:10 developer-guy

we (w/@Dentrax) are the volunteers of this issue, btw

Awesome!!!!

luhring avatar Oct 26 '21 11:10 luhring

I think this feature would be related to #510 — having Syft perform a Cosign-style attest operation, and putting the attestation into the OCI registry.

As far as CLI syntax, for #510 we realized that we want this to be separate from the format flag (-o), since users still might need a choice for format of the SBOM. We landed on introducing a new attest subcommand, to which we could attach relevant configuration for performing the attestation.

My two cents: a similar approach would make sense for Syft following the cosign attach sbom ... process:

syft attach <image>

Thinking that <image> would specify a container image URL, Syft could use this reference to know where to push the attachment, similar to what happens in Cosign.

What do you think?

luhring avatar Oct 26 '21 11:10 luhring

yeah, SGTM, we (w/@dentrax) can make it happen if you all agree on this attach command. We can start working on it ASAP.

Let me summarize the steps that we are going to take:

  1. Create a new command called attach.
  2. Take a container image URL as an argument.
  3. Generate an SBOM file for an image, and upload it to the OCI registry (maybe using cosign under the hood)

is that all we need @luhring, WDYT?

developer-guy avatar Dec 01 '21 17:12 developer-guy

@developer-guy I think so! If we think of any more considerations, we'll put them here 😃

Thanks for taking this on. 🙏

Reach out at any point if it's not obvious to how use the existing patterns or Syft API for what you're doing and we'll jump in to take a look ❤️

luhring avatar Dec 01 '21 23:12 luhring

My two cents: a similar approach would make sense for Syft following the cosign attach sbom ... process:

syft attach <image>

I think making attach as a separated command would be making logic a bit hard to implement since packagesExec() function in packages.go file requires an image as an input argument. (We expect an SBOM to be generated before pass into cosign/attach command.)

The better UX IMHO would be passing a --attach flag in packages command. By this design, it'd be easier to call cosign/attach (if bool flag passed) just after bus.Publish in packagesExecWorker() func.

By the way, a new attach command could be useful in case we want to pass a pre-generated SBOM file. So we would not be necessary to generate SBOM in the attach command.

cc: @developer-guy

Dentrax avatar Dec 07 '21 20:12 Dentrax

(We expect an SBOM to be generated before pass into cosign/attach command.)

Absolutely. On the implementation side, we can generate an SBOM in multiple execution paths. So we could make sure the attach command has an SBOM created before we invoke cosign's "attach" functionality, which should be all we need to do.

Another reason why attach makes sense as a new command is that it has its own distinct configuration needs, such as "write" access to registries (Syft's other commands don't require this), whether or not to override an existing attachment, etc.

I think the attest and attach functions should probably look the same on the command line, meaning they should either both be subcommands or they should both be flags, or else it might be confusing to users. IMHO, choosing to implement these as subcommands is more inline with the direction Syft is heading (see #516). cc: @wagoodman and @spiffcs for fact-checking me on this! 😄

By the way, a new attach command could be useful in case we want to pass a pre-generated SBOM file. So we would not be necessary to generate SBOM in the attach command.

I'm not sure I understand this part. If an SBOM has already been generated, why would users want to do the "attach" with syft instead of just using cosign attach?

luhring avatar Dec 08 '21 13:12 luhring

This was discussed in the Anchore community WG meeting today (notes available at https://docs.google.com/document/d/1ZtSAa6fj2a6KRWviTn3WoJm09edvrNUp4Iz_dOjjyY8/edit ) -

These were the options that were proposed -

  1. We could implement this in syft
    • it could potentially leverage the multi-output syntax being introduced by https://github.com/anchore/syft/pull/732 to have something like -o json=registry://my/image:latest
    • syft could potentially import cosign as a library using the logic at https://github.com/sigstore/cosign/blob/f19f4f754de43e8151b941ed2307374dae55381d/cmd/cosign/cli/attach/sbom.go#L34-L61
  2. We could continue to let cosign handle SBOM/attachment
    • we could explicitly document how the two tools interact in the syft docs (or even in the cosign docs?) so as to let users know that they can work with each other
    • Since cosign accepts sbom via stdin, this would allow syft to directly upload an sbom to the registry via syft packages <image> -o json | cosign attach sbom <image> --sbom - --type syft. This also follows the unix philosophy of one tool doing one thing well, while being able to be chained with other tools

In the WG meeting, people were leaning towards the latter + clear documentation to note that syft is compatible with cosign unless there are some other advantages to natively supporting cosign in syft that we missed.

samj1912 avatar Jan 06 '22 18:01 samj1912

The cosign behavior is documented here as a "spec", with the intention of being interoperable!

https://github.com/sigstore/cosign/blob/main/specs/SBOM_SPEC.md

Either approach sounds great to me.

dlorenc avatar Jan 06 '22 18:01 dlorenc

Added https://github.com/sigstore/cosign/pull/1278 to update the spec as well

samj1912 avatar Jan 06 '22 18:01 samj1912

Just catching up — if we're going with option 2 from the comment above, does that mean there's no work in Syft code for this any more, and it's just documentation? (of the flow for syft ... | cosign attach sbom ...?)

luhring avatar Feb 02 '22 22:02 luhring

@luhring that's correct :) https://github.com/sigstore/cosign/pull/1137 and https://github.com/sigstore/cosign/pull/1278 handle the syft support and documentation on the cosign side. We just need to do the same at https://github.com/anchore/syft#adding-an-sbom-to-an-image-as-an-attestation to also mention sbom attachments

samj1912 avatar Feb 02 '22 22:02 samj1912

Perfect, thanks @samj1912!

luhring avatar Feb 02 '22 22:02 luhring

Hi folk, as @samj1912 said, syft is now capable of uploading SBOM in form of in-toto attestation format to the registries, also, there is another option like "cosign attach", but AFAIK, there is still no direct support for uploading SBOMs to the OCI registries. Maybe, we could add another output option like "oci" to support this, the UX would be:

# will upload SBOM in a json format by using "application/vnd.syft+json" mediaType
$ syft packages alpine:latest -o json --upload/export oci://devopps/my-sbom-img 

@dentrax @luhring

developer-guy avatar Jun 12 '22 10:06 developer-guy

We could not decide which UX is better @developer-guy:

$ syft packages alpine:latest -o json --upload/export/attach oci://devopps/my-sbom-img
-- or --
$ syft packages alpine:latest --attach

BREAKING CHANGE: Introduce --format flag

If we add oci in the --output as a new type, we lost the format information since we only select one output format. (i.e., json, xml)

That's why we need to introduce a new flag called: --format:

  • formats: syft-json cyclonedx-xml cyclonedx-json spdx-json table text github-json spdx-tag-value
  • outputs: file github oci

Some help needed here! @luhring

Dentrax avatar Jun 13 '22 20:06 Dentrax

kindly ping

developer-guy avatar Sep 20 '22 06:09 developer-guy