Files
starter-workflows/agentic/vex-generator.md
T

208 lines
6.9 KiB
Markdown

---
description: >
Auto-generates an OpenVEX statement for a dismissed Dependabot alert.
Provide the alert details as inputs — the agent generates a standards-compliant
OpenVEX document and opens a PR.
on:
workflow_dispatch:
inputs:
alert_number:
description: "Dependabot alert number"
required: true
type: string
ghsa_id:
description: "GHSA ID (e.g., GHSA-xvch-5gv4-984h)"
required: true
type: string
cve_id:
description: "CVE ID (e.g., CVE-2021-44906)"
required: true
type: string
package_name:
description: "Affected package name (e.g., minimist)"
required: true
type: string
package_ecosystem:
description: "Package ecosystem (e.g., npm, pip, maven)"
required: true
type: string
severity:
description: "Vulnerability severity (low, medium, high, critical)"
required: true
type: string
summary:
description: "Brief vulnerability summary"
required: true
type: string
dismissed_reason:
description: "Dismissal reason"
required: true
type: choice
options:
- not_used
- inaccurate
- tolerable_risk
- no_bandwidth
permissions:
contents: read
issues: read
pull-requests: read
env:
ALERT_NUMBER: ${{ github.event.inputs.alert_number }}
ALERT_GHSA_ID: ${{ github.event.inputs.ghsa_id }}
ALERT_CVE_ID: ${{ github.event.inputs.cve_id }}
ALERT_PACKAGE: ${{ github.event.inputs.package_name }}
ALERT_ECOSYSTEM: ${{ github.event.inputs.package_ecosystem }}
ALERT_SEVERITY: ${{ github.event.inputs.severity }}
ALERT_SUMMARY: ${{ github.event.inputs.summary }}
ALERT_DISMISSED_REASON: ${{ github.event.inputs.dismissed_reason }}
tools:
bash: true
edit:
safe-outputs:
create-pull-request:
title-prefix: "[VEX] "
labels: [vex, automated]
draft: false
engine:
id: copilot
---
# Auto-Generate OpenVEX Statement on Dependabot Alert Dismissal
You are a security automation agent. When a Dependabot alert is dismissed, you generate a standards-compliant OpenVEX statement documenting why the vulnerability does not affect this project.
## Context
VEX (Vulnerability Exploitability eXchange) is a standard for communicating that a software product is NOT affected by a known vulnerability. When maintainers dismiss Dependabot alerts, they're making exactly this kind of assessment — but today that knowledge is lost. This workflow captures it in a machine-readable format.
The OpenVEX specification: https://openvex.dev/
## Your Task
### Step 1: Get the Dismissed Alert Details
All alert details are available as environment variables. Read them with bash:
```bash
echo "Alert #: $ALERT_NUMBER"
echo "GHSA ID: $ALERT_GHSA_ID"
echo "CVE ID: $ALERT_CVE_ID"
echo "Package: $ALERT_PACKAGE"
echo "Ecosystem: $ALERT_ECOSYSTEM"
echo "Severity: $ALERT_SEVERITY"
echo "Summary: $ALERT_SUMMARY"
echo "Dismissed reason: $ALERT_DISMISSED_REASON"
```
The repository is `${{ github.repository }}`.
Verify all required fields are present before proceeding. Also read the package.json (or equivalent manifest) to get this project's version number.
### Step 2: Map Dismissal Reason to VEX Status
Map the Dependabot dismissal reason to an OpenVEX status and justification:
| Dependabot Dismissal | VEX Status | VEX Justification |
|---|---|---|
| `not_used` | `not_affected` | `vulnerable_code_not_present` |
| `inaccurate` | `not_affected` | `vulnerable_code_not_in_execute_path` |
| `tolerable_risk` | `not_affected` | `inline_mitigations_already_exist` |
| `no_bandwidth` | `under_investigation` | *(none - this is not a VEX-worthy dismissal)* |
**Important**: If the dismissal reason is `no_bandwidth`, do NOT generate a VEX statement. Instead, skip and post a comment explaining that "no_bandwidth" dismissals don't represent a security assessment and therefore shouldn't generate VEX statements.
### Step 3: Determine Package URL (purl)
Construct a valid Package URL (purl) for the affected product. The purl format depends on the ecosystem:
- npm: `pkg:npm/<package>@<version>`
- PyPI: `pkg:pypi/<package>@<version>`
- Maven: `pkg:maven/<group>/<artifact>@<version>`
- RubyGems: `pkg:gem/<package>@<version>`
- Go: `pkg:golang/<module>@<version>`
- NuGet: `pkg:nuget/<package>@<version>`
Use the repository's own package version from its manifest file (package.json, setup.py, go.mod, etc.) as the product version.
### Step 4: Generate the OpenVEX Document
Create a valid OpenVEX JSON document following the v0.2.0 specification:
```json
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://github.com/<owner>/<repo>/vex/<ghsa-id>",
"author": "GitHub Agentic Workflow <[email protected]>",
"role": "automated-tool",
"timestamp": "<current ISO 8601 timestamp>",
"version": 1,
"tooling": "GitHub Agentic Workflows (gh-aw) VEX Generator",
"statements": [
{
"vulnerability": {
"@id": "<GHSA or CVE ID>",
"name": "<CVE ID if available>",
"description": "<brief vulnerability description>"
},
"products": [
{
"@id": "<purl of this package>"
}
],
"status": "<mapped VEX status>",
"justification": "<mapped VEX justification>",
"impact_statement": "<human-readable explanation combining the dismissal reason and any maintainer comment>"
}
]
}
```
### Step 5: Write the VEX File
Save the OpenVEX document to `.vex/<ghsa-id>.json` in the repository.
If the `.vex/` directory doesn't exist yet, create it. Also create or update a `.vex/README.md` explaining the VEX directory:
```markdown
# VEX Statements
This directory contains [OpenVEX](https://openvex.dev/) statements documenting
vulnerabilities that have been assessed and determined to not affect this project.
These statements are auto-generated when Dependabot alerts are dismissed by
maintainers, capturing their security assessment in a machine-readable format.
## Format
Each file is a valid OpenVEX v0.2.0 JSON document that can be consumed by
vulnerability scanners and SBOM tools to reduce false positive alerts for
downstream consumers of this package.
```
### Step 6: Create a Pull Request
Create a pull request with:
- Title: `Add VEX statement for <CVE-ID> (<package name>)`
- Body explaining:
- Which vulnerability was assessed
- The maintainer's dismissal reason
- What VEX status was assigned and why
- A note that this is auto-generated and should be reviewed
- Link to the original Dependabot alert
Use the `create-pull-request` safe output to create the PR.
## Important Notes
- Always validate that the generated JSON is valid before creating the PR
- Use clear, descriptive impact statements — these will be consumed by downstream users
- If multiple alerts are dismissed at once, handle each one individually
- The VEX document should be self-contained and not require external context to understand