Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to sign or attest the generated SBOM #510

Closed
luhring opened this issue Sep 20, 2021 · 8 comments · Fixed by #785
Closed

Ability to sign or attest the generated SBOM #510

luhring opened this issue Sep 20, 2021 · 8 comments · Fixed by #785
Assignees
Labels
enhancement New feature or request I/O Describes bug or enhancement around application input or output

Comments

@luhring
Copy link
Contributor

luhring commented Sep 20, 2021

Background

Syft can already generate SBOMs in a variety formats (SPDX, CycloneDX, lossless Syft JSON, etc.). These SBOMs can be saved and used in a number of downstream tasks, such as vulnerability scanning w/ Grype.

We recently looked at a supply chain security workflow that leverages Cosign to sign the SBOM from Syft before it's used downstream. This workflow was published as a blog post: https://anchore.com/blog/drop-an-sbom-how-to-secure-your-software-supply-chain-using-open-source-tools/

Ideally, there would be no opportunity for the SBOM to be tampered with before it's signed.

The new feature

Syft could have an option to sign (or even attest) the SBOM immediately as it's produced, using an identity provided by the user, to avoid any chance of tampering with the SBOM.

Implementation

This could be implemented by integrating Cosign into Syft. By doing so, this could allow Syft users to pass Cosign-related keys and/or configuration to Syft.

A simple case would be to use Cosign's sign-blob functionality to sign the SBOM:

syft example:latest -o spdx --sign ./cosign.key

Syft could even leverage Cosign's Keyless Signatures workflow (creating keys via OIDC auth and publishing the signature to Rekor), to avoid the need for users to specify any keys:

syft example:latest -o spdx --sign-keyless

Alternatively (or in addition), Syft could create an in-toto attestation for the SBOM (as the "predicate") with respect to the image (as the "subject"), akin to Cosign's attest command:

syft example:latest -o spdx --attest ./cosign.key

Open questions

  1. What CLI syntax makes the most sense to the user for these operations?
  2. Should Syft just be able to sign the SBOM? Attest the SBOM? Both?
  3. Should Syft always push the signatures or attestations to the registry?
  4. Should Syft output the signature/attestation somewhere local, and if so, where to? (the SBOM itself is already being sent to stdout)
  5. Should Syft refuse to sign/attest images not in a registry? (The input to the signing is a registry manifest.)
  6. Should signing/attesting be supported for all of Syft's output formats, or just a select subset? And how should these formats be mapped into an attestation's predicateType value?
  7. Should Syft support Cosign's Keyless Signatures?
  8. How many of Cosign's supported key sources should Syft support (e.g. cloud KMSes, hardware keys, etc.)?
  9. Should Syft pick up on Cosign's configuration directly (both tools use Viper), or is it better if the user is required to explicitly use Syft's own configuration model for all Cosign-related values?
@luhring luhring added the enhancement New feature or request label Sep 20, 2021
@hectorj2f
Copy link
Contributor

Should Syft just be able to sign the SBOM? Attest the SBOM? Both?

@luhring I like this new feature of signing reports and I find it useful. But I believe an attestation would give more value and metadata than a signature. So I'd vote for supporting attestations :).

@luhring
Copy link
Contributor Author

luhring commented Oct 10, 2021

I've started taking a look at this. First, I'll say I'm excited about the work described in sigstore/cosign#844 — I can tell that's going to help make this implementation MUCH cleaner.

Here's my latest thinking on what would make sense for a first iteration of this functionality (answering the "Open Questions" above):

  1. What CLI syntax makes the most sense to the user for these operations?

It probably makes sense to introduce a new subcommand here: attest. This should align nicely with the Syft command structure updates described in #516.

So, something like this could work well:

$ syft attest --key ./cosign.key my-image@sha256:abc123...
  1. Should Syft just be able to sign the SBOM? Attest the SBOM? Both?

I agree with the above comment — let's target attestation only at first.

  1. Should Syft always push the signatures or attestations to the registry?

The automatic pushing that Cosign does provides a very nice user experience. Let's have Syft do that, too, but have configuration available for turning this off. Also, note: registry write access will be new to Syft, and more thought is needed around how this should work.

  1. Should Syft output the signature/attestation somewhere local, and if so, where to? (the SBOM itself is already being sent to stdout)

With the choice to introduce a new command, there's no longer an obligation to write the raw SBOM to stdout. It might make sense to write the attestation envelope to stdout. Users can redirect this somewhere (including /dev/null) if they want to.

  1. Should Syft refuse to sign/attest images not in a registry? (The input to the signing is a registry manifest.)

Not sure about longer term, but for the short term, I think it makes sense to apply this constraint.

  1. Should signing/attesting be supported for all of Syft's output formats, or just a select subset? And how should these formats be mapped into an attestation's predicateType value?

There's no technical need to restrict the SBOM formats to support, but some of Syft's formats just don't make sense here since they aren't designed to be machine-readable (e.g. table output). Perhaps we could start with a subset of supported formats, specifically: spdx-json, spdx-tag-value, and json (Syft's lossless JSON), defaulting to spdx-json. We can add the other formats in response to concrete needs.

  1. Should Syft support Cosign's Keyless Signatures?

Yes, this is very nice workflow from Cosign, and it'd be great to show it off to Syft users.

  1. How many of Cosign's supported key sources should Syft support (e.g. cloud KMSes, hardware keys, etc.)?

To start with, let's just support Cosign's basic key files (e.g. cosign.key) and the Keyless workflow.

  1. Should Syft pick up on Cosign's configuration directly (both tools use Viper), or is it better if the user is required to explicitly use Syft's own configuration model for all Cosign-related values?

We're not sure yet. We think it could be a nice user experience for existing Cosign users to start using Syft and not have to re-configure attestation-related things just because they introduced a new tool. On the other hand, if Cosign's config is meant to be internal and/or unstable, we'd probably be better off creating a wholly independent config for attestation within Syft's existing app config. This would be a good discussion topic with the Sigstore folks!

  1. (new) Should Syft upload signatures to Rekor?

Yes, by default. And this can be disabled via configuration.


Curious for others' thoughts! 😃

@dlorenc
Copy link
Contributor

dlorenc commented Oct 10, 2021

Wow, missed this! Thanks for opening it!

The cosign/pkg work is flying by thanks to @mattmoor. Adding him in here for FYI.

@mattmoor
Copy link

The OCI package is looking pretty good @dekkagaijin is tackling the signing and verification bits now 🎉

@luhring luhring added the I/O Describes bug or enhancement around application input or output label Oct 28, 2021
@luhring luhring self-assigned this Oct 28, 2021
@developer-guy
Copy link
Contributor

We recently made a similar effort on projects like nerdctl, conftest. But, instead of using cosign as Go module to avoid extra dependencies, we've used cosign executable file under the hood to sign and verify container image.

Here is the summary of what we have done so far:

@luhring
Copy link
Contributor Author

luhring commented Dec 1, 2021

Thanks @developer-guy, I'll check those out! On my side, this issue has been on the back burner for a few weeks, but hopefully it gets more attention here shortly. It's absolutely the direction we want to take Syft.

@spiffcs
Copy link
Contributor

spiffcs commented Feb 10, 2022

Update

We're about to land the first PR for this issue and I wanted to update the scope a bit here to give people a quick summary of where we are and where we are going RE: Attestations.

  1. What CLI syntax makes the most sense to the user for these operations?

The format from the initial comment is what we have adopted. We've also taken into account using multiple formats for the predicate.

$ syft attest --key ./cosign.key my-image@sha256:abc123...

See the final PR here for a summary of the SBOM formats supported

  1. Should Syft just be able to sign the SBOM? Attest the SBOM? Both?

For the initial implementation, we have settled on producing a signed attestation that can be attached to an image using the SBOM as the predicate.

  1. Should Syft always push the signatures or attestations to the registry?

The automatic pushing that Cosign does provides a very nice user experience. Because we are not attaching the attestation as part of the syft command pushing/attaching will not be scoped under the attest command at this time.

  1. Should Syft output the signature/attestation somewhere local, and if so, where to? (the SBOM itself is already being sent to stdout)

With the choice to introduce a new command, there's no longer an obligation to write the raw SBOM to stdout. We have chosen to write the attestation envelope to stdout so users can proceed with that artifact in their respective workloads.

  1. Should Syft refuse to sign/attest images not in a registry? (The input to the signing is a registry manifest.)

We have chosen to keep with the above so make sure we are still using the manifest and digests as part of the attestation inputs.

  1. Should signing/attesting be supported for all of Syft's output formats, or just a select subset? And how should these formats be mapped into an attestation's predicateType value?

We have chosen to support all input formats that syft currently supports, specifically:

	JSONOption          Option = "json"
	TextOption          Option = "text"
	TableOption         Option = "table"
	CycloneDxXMLOption  Option = "cyclonedx"
	CycloneDxJSONOption Option = "cyclonedx-json"
	SPDXTagValueOption  Option = "spdx-tag-value"
	SPDXJSONOption      Option = "spdx-json"

If we need to size these down, make additions, or update this list in the future PRs will be added.

  1. Should Syft support Cosign's Keyless Signatures?

This feature will be added in a follow-up PR along with Rekor integration for uploading signatures.

  1. How many of Cosign's supported key sources should Syft support (e.g. cloud KMSes, hardware keys, etc.)?

To start with, let's just support Cosign's basic key files (e.g. cosign.key) and the Keyless workflow. These will be merged with the first two PR focused on attestations. As we get more feedback the other cloud-native solutions will be integrated.

  1. Should Syft pick up on Cosign's configuration directly (both tools use Viper), or is it better if the user is required to explicitly use Syft's own configuration model for all Cosign-related values?

Currently, syft will support the COSIGN_PASSWORD for keys that require password inputs. Furthur cosign configuration integration will be added as needed to support the use of cloud-native, keyless, and other attestation workflows.

@spiffcs
Copy link
Contributor

spiffcs commented Feb 17, 2022

See this comment re BINARY size increase:
#785 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request I/O Describes bug or enhancement around application input or output
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants