CVE Fix
Automated CVE remediation for Python dependencies. Queries Jira for CVEs, updates Pipfile and Pipfile.lock, creates MRs, and updates Jira.
Critical Lessons Learned
These are hard-won from production use. Follow them strictly:
- •Dependency cascade: Upgrading one package often breaks others (e.g., aiohttp 3.13+ broke gql, urllib3 2.x broke boto3). Always check compatibility.md BEFORE updating.
- •Both files must update: Always update Pipfile AND Pipfile.lock together. Missing Pipfile changes causes CI failures.
- •Branch isolation: Always create branches from
origin/main, never from another feature branch. Cross-contamination has caused multiple MR issues. - •Error handling: Use
isinstance()checks before.get()on variables that might be error strings instead of dicts (e.g., when pipenv lock fails). - •Local validation: Build container + run
pytest --collect-onlyto catch import errors from missing transitive dependencies before CI. - •Rebase conflicts: When multiple CVE fixes are in flight, document which packages were modified to help resolve conflicts.
Required MCP Tools
Load the developer persona first:
persona_load("developer")
Tools used: jira_search, jira_view_issue, jira_assign, jira_transition, jira_add_comment, git_fetch, git_branch_list, git_branch_create, git_checkout, git_add, git_commit, git_push, gitlab_mr_list, gitlab_mr_create, podman_build, podman_run, memory_session_log, jira_attach_session
Workflow
Phase 1: Discovery and Filtering
- •
Query Jira for CVEs:
codejira_search(jql='"Downstream Component Name" ~ "<component>" AND type = Vulnerability AND resolution = Unresolved ORDER BY created DESC', max_results=50)
Default component:
automation-analytics-backend - •
Fetch latest from origin with prune to get up-to-date refs.
- •
Check git log on
origin/main(last 500 commits) to find already-merged fixes. - •
Check all branches for in-progress CVE work.
- •
Check open MRs for existing CVE fix MRs.
- •
Classify each CVE into one of:
- •Merged to main - skip (already fixed)
- •Has open MR - skip (fix in review)
- •Has branch, no MR - resumable (prioritize these)
- •Unfixed - needs work from scratch
- •
Select CVEs to process: Prioritize resumable CVEs over new ones. Default: process 1 at a time.
Phase 2: CVE Details and Validation
- •
Get CVE details from Jira using
jira_view_issue. - •
Extract CVE info - see cve-parsing.md for detailed extraction strategies. Need:
- •CVE ID (e.g.,
CVE-2024-12345) - •Affected package name (normalized to lowercase with hyphens)
- •Summary, CVSS score, severity
- •CVE ID (e.g.,
- •
Validate the CVE:
- •Must have both CVE ID and affected package
- •Reject non-pip packages (python, linux, glibc, java, nodejs, gcc, etc.) - these need different remediation (base image update)
- •
Check compatibility requirements - consult compatibility.md for known breaking changes when upgrading the affected package.
Phase 3: Resume Logic (for existing branches)
If resuming a CVE that already has a branch:
- •Find the existing branch name by searching branch list for the issue key.
- •Check it out (try local first, then
origin/<branch>). - •Check commits ahead of
origin/mainto detect what's already done. - •Check if Pipfile/Pipfile.lock are already committed.
- •Check if branch is already pushed to remote.
- •Skip completed steps in subsequent phases.
Phase 4: Jira Updates
- •Resolve Jira username from config (must be email format, e.g.,
user@redhat.com). - •Assign issue to current user.
- •Set acceptance criteria if not already present:
code
* CVE-XXXX vulnerability in <package> is remediated * <package> is updated to a version that fixes CVE-XXXX * Pipfile and Pipfile.lock are updated with the new version * No regressions in existing functionality * CI pipeline passes
- •Transition to In Progress.
Phase 5: Branch Creation
Skip this phase if resuming (already on feature branch).
- •Verify working directory is clean - abort if uncommitted changes exist.
- •Checkout main and hard reset to
origin/main(critical for branch isolation). - •Create feature branch:
<ISSUE_KEY>-<cve-id>-<package>(e.g.,AAP-12345-cve-2025-69223-aiohttp). - •Verify branch base matches
origin/mainexactly (merge-base check).
Phase 6: Update Pipfile and Pipfile.lock
Skip if already committed (resume case).
This uses a container-based approach to resolve package versions with the correct Python version:
- •
Read Python version from the project's Pipfile
[requires]section. - •
Map to UBI container image:
Python Image 3.9 registry.access.redhat.com/ubi9/python-393.11 registry.access.redhat.com/ubi9/python-3113.12 registry.access.redhat.com/ubi9/python-312 - •
Create temp workspace in
/tmp/cve-fix-*with:- •Minimal Pipfile containing just the target package (and any companion packages)
- •Containerfile based on the UBI image
- •
Build container with
podman_build(installs pip + pipenv). - •
Run
pipenv lockinside the container with the temp dir volume-mounted. - •
Extract new version and hashes from the generated Pipfile.lock.
- •
Update project Pipfile:
- •If package exists: update to
>= <new_version>with CVE comment - •If package missing: add after
[packages]header - •Update companion packages too if needed
- •If package exists: update to
- •
Update project Pipfile.lock:
- •Update version and hashes for main package
- •Update companion packages
- •Preserve all other packages unchanged
- •
Clean up temp directory.
Phase 7: Commit and Push
- •Build commit message using format:
<ISSUE_KEY> - fix(deps): update <package> <old> -> <new> to fix <CVE-ID> - •Stage Pipfile and Pipfile.lock.
- •Commit the changes.
- •Push branch to origin with
--set-upstream.
Phase 8: Create MR
- •
Build MR title:
<ISSUE_KEY> - fix(security): fix <CVE-ID> in <package> - •
Build MR description with sections:
- •Summary (security fix for CVE in package)
- •CVE Details (ID, package, severity, CVSS with NVD link)
- •Changes (Pipfile and Pipfile.lock updates, companion packages)
- •Compatibility Notes (if applicable)
- •Jira link
- •Testing checklist
- •Completion checklist
- •
Create MR via
gitlab_mr_create(not draft).
Phase 9: Post-MR Actions
- •Add Jira comment with MR link and change summary.
- •Notify team via Slack using the
notify_teamskill withcve_fixtemplate. - •Log to session memory.
- •Attach session context to the Jira issue for audit trail.
- •Scan fixed image via
scan_vulnerabilitiesskill (if commit SHA available). - •Restore developer persona after scan.
Dry Run Mode
When dry_run is true, show what would be done without making any changes. Display the CVE status summary table and planned steps.
Output Summary
Present results as a markdown table:
| Status | Count | Issues |
|---|---|---|
| Merged to main | N | AAP-... |
| Has Open MR | N | AAP-... |
| Resumable | N | AAP-... |
| Needs Work | N | AAP-... |
For each processed CVE, show:
- •Issue key, CVE ID, package, severity, CVSS
- •Branch name, Python version
- •Pipfile changes (old version -> new version)
- •Companion package updates
- •MR link
Additional Resources
- •Package compatibility requirements: See references/compatibility.md for known breaking changes between packages
- •CVE info extraction from Jira: See references/cve-parsing.md for multi-strategy parsing of CVE IDs and affected packages from Jira issue text