Skip to content

openshift-assisted/cve-automation

Repository files navigation

CVE Automation

A system that scans Go repositories for known vulnerabilities, generates patches to fix them, and monitors the progress of fixes. The tool identifies vulnerable Go dependencies in your codebase, automatically creates pull requests with the necessary updates, and tracks their status through JIRA tickets.

What It Does

  1. Vulnerability Scanning: Scans configured Go repositories to identify dependencies with known CVEs. Checks all configured branches and cross-references with JIRA tickets.

  2. Automated Patching: Attempts to fix each CVE using multiple strategies, creates pull requests with detailed explanations of what was done and why.

  3. PR and JIRA Monitoring: Tracks pull request status, handles rebases when base branches update, and closes PRs when vulnerabilities are fixed manually.

Design Choices

Why Jujutsu (jj) Instead of Git

The system uses Jujutsu for repository operations instead of plain Git. This enables safe concurrent operations on the same repository:

  • Multiple CVE patches can be developed in parallel using jj workspaces
  • Each workspace operates independently without interfering with others
  • A single cached clone serves multiple concurrent patch operations
  • Workspace cleanup is atomic and doesn't affect other active workspaces

This is critical for performance when processing dozens of CVEs across multiple branches simultaneously.

Transparent Strategy Selection

Every pull request includes a Strategy Selection section explaining:

  • Which strategies were considered but not applicable (and why)
  • Which strategy succeeded
  • What versions were attempted

This transparency helps reviewers understand why a particular fix approach was chosen. For example:

## Strategy Selection

### Strategies Not Applicable

- **SimpleDirectUpdate**
  Dependency is indirect, not directly imported

- **IntroducerUpdate**
  No introducer brings in a fixed version

### ✓ Successful Strategy: ReplaceDirective

Configuration

Environment Variables

Required:

export JIRA_API_TOKEN=your_jira_api_token

GitHub Authentication (choose one):

Option 1 - GitHub App (used by the automation when running as a service):

export GITHUB_APP_ID=your_github_app_id
export GITHUB_APP_PRIVATE_KEY=your_github_app_private_key
export GITHUB_APP_INSTALLATION_ID=your_installation_id

Option 2 - Personal Access Token (simpler for local development or fork mode):

export GH_TOKEN=your_github_token

Optional:

export FORK_MODE=true  # Push to fork_url instead of origin (requires fork_url in targets)

targets.yaml

The targets.yaml file defines which repositories and branches to scan. Each target maps Git branches to their corresponding JIRA release names.

targets:
- repo_url: https://github.com/your-org/your-repo.git

  # Names used to find CVE tickets in JIRA (component names, container names, etc.)
  names:
  - your-repo
  - your-repo-rhel9

  # JIRA projects to search for CVE tickets
  jira_projects:
  - OCPBUGS
  - ACM

  # Map Git branches to JIRA release names
  # The scanner uses jira_name to correlate CVEs with the correct branch
  branches:
  - name: main           # Git branch name
    jira_name: mce-2.11  # How this release is named in JIRA tickets
  - name: release-2.10
    jira_name: mce-2.10
  - name: release-2.9
    jira_name: mce-2.9

  # Optional: paths containing Konflux/Tekton pipeline definitions
  # Used to track CI configuration changes
  konflux_paths:
  - .tekton

  # Optional: JIRA versions that are archived (EOL)
  # CVEs for these versions will be skipped
  archived_branches_in_jira:
  - mce-2.5
  - mce-2.4

  # Optional: commands to run after patching specific modules
  # Useful for regenerating code, updating manifests, etc.
  post_patch_commands:
    api/go.mod:
    - make generate
    models/go.mod:
    - make generate

  # Optional: label management for PRs by module
  label_rules:
    api/go.mod:
      add: []
      remove:
      - api-review  # Remove api-review label for api module changes

  # Optional: fork URL for FORK_MODE
  # When FORK_MODE=true, PRs are created from this fork
  fork_url: https://github.com/your-fork/your-repo.git

Branch to JIRA Mapping

The most important configuration is the branches mapping. This tells the system how Git branches correspond to JIRA release versions:

branches:
- name: main           # The actual Git branch
  jira_name: mce-2.11  # The release name in JIRA ticket summaries
- name: release-ocm-2.15
  jira_name: mce-2.10

JIRA tickets typically have summaries like:

CVE-2024-1234 your-repo: vulnerability description [mce-2.10]

The jira_name field must match the bracketed version in JIRA ticket summaries.

Multi-Module Repositories

For repositories with multiple Go modules (monorepos), you can configure per-module behavior:

post_patch_commands:
  api/go.mod:
  - make generate-api
  client/go.mod:
  - make generate-client

label_rules:
  api/go.mod:
    add:
    - needs-api-review
    remove: []

Usage

# Scan for vulnerabilities
python cve_fetcher.py

# Create patches
python cve_patcher.py

# Monitor PRs and JIRA
python pr_monitor.py

Or using Make (handles GitHub App token generation):

make fetch   # Scan
make patch   # Patch
make monitor # Monitor

Onboarding Your Repository

To get automated CVE patches for your Go repository:

  1. Fork this repository or clone it locally

  2. Add your target to targets.yaml:

    - repo_url: https://github.com/your-org/your-repo.git
      names:
      - your-repo-name-in-jira
      jira_projects:
      - YOUR_JIRA_PROJECT
      branches:
      - name: main
        jira_name: your-release-name
  3. Submit a pull request with your new target configuration

Once merged, the automation will:

  • Scan your repository for vulnerable dependencies
  • Create PRs when fixes are available
  • Track PR status and handle rebases
  • Close PRs if vulnerabilities are fixed manually

Contributing

Code Style

  • Types - type hints, named parameters, anything that can make reading your code easier
  • Fail fast - no fallbacks, no silent defaults, crash with clear error messages
  • Single happy path - one way to do things, anything that diverges from the happy path - fail fast.

Tooling

ruff check .   # Lint
ruff format .  # Format
basedpyright   # Type check
pytest         # Test

All of the above keep the code self-documenting - types show intent, named parameters explain themselves, and the absence of fallbacks helps to reason about bugs faster.

Prerequisites

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages