diff --git a/docs/docs/supply-chain/vex/index.md b/docs/docs/supply-chain/vex/index.md index 4f8d59abe126..d42d8d57de29 100644 --- a/docs/docs/supply-chain/vex/index.md +++ b/docs/docs/supply-chain/vex/index.md @@ -12,6 +12,7 @@ Trivy currently supports two methods for utilizing VEX: 1. [VEX Repository](./repo.md) 2. [Local VEX Files](./file.md) +3. [VEX Attestation](./oci.md) ### Enabling VEX To enable VEX, use the `--vex` option. @@ -19,12 +20,13 @@ You can specify the method to use: - To enable the VEX Repository: `--vex repo` - To use a local VEX file: `--vex /path/to/vex-document.json` +- To enable VEX attestation discovery in OCI registry: `--vex oci` ```bash $ trivy image ghcr.io/aquasecurity/trivy:0.52.0 --vex repo ``` -You can enable both methods simultaneously. +You can enable these methods simultaneously. The order of specification determines the priority: - `--vex repo --vex /path/to/vex-document.json`: VEX Repository has priority diff --git a/docs/docs/supply-chain/vex/oci.md b/docs/docs/supply-chain/vex/oci.md new file mode 100644 index 000000000000..a5305a32d8ac --- /dev/null +++ b/docs/docs/supply-chain/vex/oci.md @@ -0,0 +1,121 @@ +# VEX Attestation + +!!! warning "EXPERIMENTAL" + This feature might change without preserving backwards compatibility. + +Trivy can discover VEX attestations for container images. +This feature allows you to automatically use VEX during container image scanning. + +## How It Works + +Trivy can automatically discover and utilize VEX attestations for container images during scanning by using the `--vex oci` flag. +This process enhances vulnerability detection results by incorporating the information from the VEX attestation. + +To use this feature, follow these three steps: + +1. Create a VEX document +2. Generate and upload a VEX attestation to an OCI registry +3. Use the VEX attestation with Trivy + +Steps 1 and 2 are not necessary if you are trying to scan a third-party container image and already have VEX attestation attached. + +Let's go through each step in detail. + +!!! note + In the following examples, the `cosign` command will write an attestation to a target OCI registry, so you must have permission to write. + If you want to avoid writing an OCI registry and only want to see an attestation, add the `--no-upload` option to the cosign command. + +### Step 1: Create a VEX Document + +Currently, Trivy does not have a built-in feature to create VEX documents, so you need to create them manually. +You can refer to the [OpenVEX section](./file.md#openvex) for guidance on creating VEX files. + +For container image vulnerabilities, the product ID should be the OCI type in the [PURL][purl] format. +For example: + +``` +pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy +``` + +This product ID applies the VEX statement to all tags of the `ghcr.io/aquasecurity/trivy` container image. +If you want to declare a statement for a specific digest only, you can use: + +``` +pkg:oci/trivy@sha256:5bd5ab35814f86783561603ebb35d5d5d99006dcdcd5c3f828ea1afb4c12d159?repository_url=ghcr.io/aquasecurity/trivy +``` + +!!! note + Using an image tag, like `pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy&tag=0.50.0`, is not supported in the product ID at the moment. + +Next, specify vulnerable packages as subcomponents, such as `pkg:apk/alpine/busybox`. +You can also include the package version and other [qualifiers][qualifiers] (e.g., `arch`) to limit statements, like `pkg:apk/alpine/busybox@1.36.1-r29?arch=x86`. + +Lastly, include the vulnerability IDs. + +Here's an example VEX document: + +```json +{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://openvex.dev/docs/public/vex-2e67563e128250cbcb3e98930df948dd053e43271d70dc50cfa22d57e03fe96f", + "author": "Aqua Security", + "timestamp": "2024-07-30T19:07:16.853479631-06:00", + "version": 1, + "statements": [ + { + "vulnerability": { + "name": "CVE-2023-42363" + }, + "products": [ + { + "@id": "pkg:oci/trivy?repository_url=ghcr.io/aquasecurity/trivy", + "subcomponents": [ + {"@id": "pkg:apk/alpine/busybox"}, + {"@id": "pkg:apk/alpine/busybox-binsh"} + ] + } + ], + "status": "not_affected", + "justification": "vulnerable_code_cannot_be_controlled_by_adversary", + "impact_statement": "awk is not used" + } + ] +} +``` + +You can also refer to [Trivy's example](https://github.com/aquasecurity/trivy/blob/4e54a7e84c33c1be80c52c6db78c634bc3911715/.vex/oci.openvex.json) for more inspiration. + +### Step 2: Generate and Upload a VEX Attestation to an OCI Registry + +You can use the [Cosign command](https://docs.sigstore.dev/verifying/attestation/) to generate and upload the VEX attestation. +Cosign offers methods both with and without keys. +For detailed instructions, please refer to the Cosign documentation. + +To generate and attach a VEX attestation to your image, use the following command: + +``` +$ cosign attest --predicate oci.openvex.json --type openvex +``` + +Note that this command attaches the attestation only to the specified image tag. +If needed, repeat the process for other tags and digests. + +### Step 3: Use VEX Attestation with Trivy + +Once you've attached the VEX attestation to the container image, Trivy can automatically discover and use it during scanning. +Simply add the `--vex oci` flag when scanning a container image: + +``` +$ trivy image --vex oci +``` + +To see which vulnerabilities were filtered by the VEX attestation, use the `--show-suppressed` flag: + +``` +$ trivy image --vex oci --show-suppressed +``` + +The `` specified in these commands must be the same as the one to which you attached the VEX attestation. + +[purl]: https://github.com/package-url/purl-spec +[qualifiers]: https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index f61ccdf7161d..9585c8341f94 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -131,6 +131,7 @@ nav: - Overview: docs/supply-chain/vex/index.md - VEX Repository: docs/supply-chain/vex/repo.md - Local VEX Files: docs/supply-chain/vex/file.md + - VEX Attestation: docs/supply-chain/vex/oci.md - Compliance: - Built-in Compliance: docs/compliance/compliance.md - Custom Compliance: docs/compliance/contrib-compliance.md diff --git a/pkg/vex/oci.go b/pkg/vex/oci.go index c68ba2f6840b..17b827fe4fbd 100644 --- a/pkg/vex/oci.go +++ b/pkg/vex/oci.go @@ -43,11 +43,11 @@ func RetrieveVEXAttestation(p *purl.PackageURL) (*OpenVEX, error) { return nil, xerrors.Errorf("failed to probe the package URL: %w", err) } if len(vexDocuments) == 0 { - logger.Info("No VEX documents found") + logger.Info("No VEX attestations found") return nil, nil } - logger.Debug("VEX document found, taking the first one") + logger.Debug("VEX attestation found, taking the first one") return &OpenVEX{ vex: *vexDocuments[0], source: fmt.Sprintf("VEX attestation in OCI registry (%s)", p.String()),