Product Docs
Open Source
Education
The vexctl CLI is a tool to make VEX work. As part of the open source OpenVex project, vexctl enables you to create, apply, and attest VEX (Vulnerability Exploitability eXchange) data in order to filter out false positive security alerts.
vexctl
The vexctl tool was built to help with the creation and management of VEX documents, communicate transparently to users as time progresses, and enable the “turning off” of security scanner alerts of vulnerabilities known not to affect a given product. Using VEX, software authors can communicate to their users that an otherwise vulnerable component has no security implications for their product.
This tutorial will walk you through some common commands in vexctl.
If you would like to install vexctl on your local or virtual machine, you will need Go 1.16 or higher. You can install by following the official Go documentation.
Using Go, run the following to install vexctl:
go install github.com/openvex/vexctl@latest
Alternately, you can follow along with this tutorial on the embedded browser terminal, which has vexctl already installed.
You can confirm that vexctl was installed and is ready to use by running the following command, which you can run on the embedded terminal.
vexctl version
You should receive output similar to the following.
_ _ _____ __ __ _____ _____ _ | | | || ___|\ \ / // __ \|_ _|| | | | | || |__ \ V / | / \/ | | | | | | | || __| / \ | | | | | | \ \_/ /| |___ / /^\ \| \__/\ | | | |____ \___/ \____/ \/ \/ \____/ \_/ \_____/ vexctl: A tool for working with VEX data GitVersion: ... ... Platform: ...
This indicates the current version of vexctl on your working machine. You are ready to proceed with working with vexctl.
With vexctl, VEX data can be created to a file on disk, or it can be captured in a signed attestation that can be attached to a container image. You can create a VEX document by using the vexctl create command.
vexctl create
For example, to create a VEX document with a single statement asserting that the WolfiOS package git-2.38.1-r0 is not affected by a given common vulnerability and exposure (CVE) — let’s say, CVE-2014-123456 — because it has already been mitigated in the distribution, you can run the following.
git-2.38.1-r0
CVE-2014-123456
vexctl create --product="pkg:apk/wolfi/git@2.38.1-r0?arch=x86_64" \ --vuln="CVE-2014-123456" \ --status="not_affected" \ --justification="inline_mitigations_already_exist"
This command notes the following:
product
vuln
status
not_affected
affected
fixed
under_investigation
justification
inline_mitigations_already_exist
component_not_present
The vexctl create command above renders the following document.
{ "@context": "https://openvex.dev/ns", "@id": "https://openvex.dev/docs/public/vex-cfaef18d38537412a0307ec266bed56aa88fa58b7c1f2c6b8c9ef997028ba4bd", "author": "Unknown Author", "role": "Document Creator", "timestamp": "2023-01-10T20:24:50.498233798-06:00", "version": "1", "statements": [ { "vulnerability": "CVE-2014-123456", "products": [ "pkg:apk/wolfi/trivy@0.36.1-r0?arch=x86_64" ], "status": "not_affected", "justification": "component_not_present" } ] }
You can also create a VEX document with abbreviated information. For instance, when a given CVE was addressed in the image and you want to attest that it has been fixed.
vexctl create "pkg:apk/wolfi/git@2.39.0-r1?arch=x86_64" CVE-2023-12345 fixed
The above workflow demonstrates how to create a VEX document with vexctl on the command line.
When more than one stakeholder is issuing VEX metadata about a piece of software, vexctl can merge the documents to get the most up-to-date impact assessment of a vulnerability.
Let’s begin with two test documents. You can create these two test documents with a CLI editor such as nano.
The first document is document1.vex.json:
document1.vex.json
{ "id": "my-vexdoc", "format": "text/vex+json", "author": "John Doe", "role": "vex issuer", "statements": [ { "timestamp": "2022-12-22T16:36:43-05:00", "products": ["pkg:apk/wolfi/bash@1.0.0"], "vulnerability": "CVE-1234-5678", "status": "under_investigation", "status_notes": "" } ] }
The second document is document2.vex.json:
document2.vex.json
{ "id": "my-vexdoc", "format": "text/vex+json", "author": "John Doe", "role": "vex issuer", "statements": [ { "timestamp": "2022-12-22T20:56:05-05:00", "products": ["pkg:apk/wolfi/bash@1.0.0"], "vulnerability": "CVE-1234-5678", "status": "fixed" } ] }
The two files are generated from a known rule set, also known as “golden data” or a “golden file,” which is reused and reapplied to new releases of the same project.
We can merge the two VEX documents with the vexctl merge command:
vexctl merge
vexctl merge --product=pkg:apk/wolfi/bash@1.0.0 \ document1.vex.json \ document2.vex.json
The resulting document combines the VEX statements that express data about bash@1.0.0 into a single document.
bash@1.0.0
{ "@context": "", "@id": "merged-vex-67124ea942ef30e1f42f3f2bf405fbbc4f5a56e6e87684fc5cd957212fa3e025", "author": "Unknown Author", "role": "Document Creator", "timestamp": "2023-02-03T21:48:39.582648-05:00", "version": "", "statements": [ { "vulnerability": "CVE-1234-5678", "timestamp": "2022-12-22T16:36:43-05:00", "products": [ "pkg:apk/wolfi/bash@1.0.0" ], "status": "under_investigation" }, { "vulnerability": "CVE-1234-5678", "timestamp": "2022-12-22T20:56:05-05:00", "products": [ "pkg:apk/wolfi/bash@1.0.0" ], "status": "fixed" } ] }
This final document tells the whole story of how CVE-2014-123456 was under_investigation and then fixed four hours later, all documented in a single VEX file that was merged with vexctl.
To attest to and attach VEX statements within a given document to a container image, you can use the vexctl attest command with the --attach and --sign flags.
vexctl attest
--attach
--sign
For example, if you have a container image your-username/your-container-image:latest in a container registry, and a related VEX document hello.vex.json, you can run the following command to attest to that document, attach the document and sign that attestation. If you want to try this example, make sure to replace your-username/your-container-image:latest with the path to your container.
your-username/your-container-image:latest
hello.vex.json
vexctl attest --attach --sign hello.vex.json your-username/your-container-image:latest
Upon running this command, you’ll be taken through a signing workflow with Sigstore. Your terminal output will indicate your progess.
Generating ephemeral keys... Retrieving signed certificate...
A browser window will open for you to select an OIDC provider. When the attestation is complete, you’ll receive feedback that it was successful.
Successfully verified SCT... {"payloadType":"application/vnd.in-toto+json","payload":"e...o=","signatures":[{"keyid":"","sig":"MEY...z"}]}
This attestation with .att extension will now live in the container registry as an attachment to your container.
.att
Assessing the impact of CVEs on a software product is process that takes time and the status will change over time. VEX is designed to communicate with users as the status changes, and there may therefore be multiple VEX documents associated with a product.
To understand how this may work in practice, below is an example timeline for the VEX documents associated with a given product and CVE.
vulnerable_code_not_in_execute_path
When analyzing the VEX documents associated with Inky App, vexctl will review them chronologically and “replay” the known impact statuses in the order they were found, effectively computing the not_affected status.
If a SARIF report is formatted as a VEX document with vexctl, any entries alerting of CVE-2014-123456 will be filtered out.
The vexctl tool is open source, you can review the vexctl repository on GitHub, as well as the go-vex Go library for generating, consuming, and operating on VEX documents.
go-vex
The following blog posts have some background about VEX and OpenVEX:
The OpenVEX Specification is owned and steered by the community. You can find the organization page with additional repostiories at openvex.dev.