Skip to main content

Autonomous CVE remediation — patches build files and source code, verifies the build, opens a PR

Project description

Sentinel — Autonomous CVE Remediation

License: Apache 2.0 Python 3.11+ PyPI Ecosystems

Sentinel closes the "last mile" of CVE remediation.
Most tools tell you what's vulnerable. Sentinel fixes it — opening a verified, build-passing pull request with no human in the loop.

CVE detected → fork repo → resolve full dep tree → query OSV →
patch build files + source code → verify build in sandbox → open PR

Live demo PRs opened by Sentinel:


Install

pip install sentinel-remediation

Requires Docker running locally. Set credentials in a .env file (see Quick start).


Usage

# Fix CVEs in any public GitHub repo
sentinel fix-cve --repo https://github.com/org/repo

# Target a specific branch
sentinel fix-cve --repo https://github.com/org/repo --branch develop

# Force a specific LLM provider
sentinel fix-cve --repo https://github.com/org/repo --llm gemini

# Override the model
sentinel fix-cve --repo https://github.com/org/repo --llm anthropic --model claude-sonnet-4-6

Sentinel forks the repo, opens a sandbox container, scans, patches, verifies, and opens a PR — typically in under 3 minutes.


Why this is different

Tool Detects Patches build file Patches source code Verifies build Opens PR
Dependabot
Snyk Partial
Renovate
Sentinel

Dependabot bumps versions. Sentinel bumps versions and fixes the dangerous call sites in your code — then proves the build still passes before touching your repo.


What Sentinel does

Three-layer remediation

Layer 1 — Transitive CVE detection
Resolves the complete dependency tree (not just declared deps) using the native build tool, then queries the OSV REST API for every package including transitively pulled dependencies. Catches CVEs that arrive silently through frameworks.

Layer 2 — Build file patching
LLM upgrades pom.xml, build.gradle, build.gradle.kts, gradle/libs.versions.toml, requirements.txt, and pyproject.toml to the minimum safe version. Handles version variables, BOM imports, Kotlin DSL, and Gradle version catalogs.

Layer 3 — Source code patching
Greps source files for dangerous call-site patterns — both CVE-specific and a built-in set of always-checked anti-patterns:

Python anti-patterns (always checked):

Pattern Risk
yaml.load( RCE via unsafe deserialization
pickle.loads( / pickle.load( RCE via deserialization

Java anti-patterns (always checked):

Pattern Risk
new ObjectInputStream( Java deserialization RCE
Runtime.getRuntime().exec( OS command injection
new ProcessBuilder( OS command injection
MessageDigest.getInstance("MD5" Weak hashing
MessageDigest.getInstance("SHA-1" Weak hashing
new Random( Insecure randomness
DocumentBuilderFactory.newInstance( XML External Entity (XXE)
XMLInputFactory.newInstance( XML External Entity (XXE)

PR audit trail

Every PR opened by Sentinel includes a structured evidence trail:

  • CVEs addressed
  • Files changed with patterns found
  • Build verification status and attempt count
  • Truncated build output (collapsible)
  • Timestamp

Verify before merge

Every patch is tested in an isolated Docker sandbox (JDK 17 + Maven/Gradle, Python 3 + pip) before the PR is opened. If the build fails, Sentinel extracts the error, feeds it back to the LLM, and retries up to 3 times.

Fallback when PR can't be opened

If the GitHub API is unavailable or rate-limited, Sentinel extracts the diff from the container and saves it as sentinel-patch-<timestamp>.diff locally with apply instructions. The fix is never lost.


Supported ecosystems

Build system Detection Transitive scan Source patching Verify command
Maven (pom.xml) mvn dependency:list .java mvn clean compile
Gradle Groovy gradle dependencies .java gradle compileJava
Gradle KTS gradle dependencies .java gradle compileJava
Gradle version catalog gradle dependencies .java gradle compileJava
requirements.txt pip install + pip list .py pip install && pytest
pyproject.toml pip install + pip list .py pip install && pytest

Quick start

# 1. Install
pip install sentinel-remediation

# 2. Set credentials
cp .env.example .env
# Edit .env — add GITHUB_TOKEN and at least one LLM key:
#   ANTHROPIC_API_KEY  (Claude — recommended, best accuracy)
#   GEMINI_API_KEY     (Gemini Flash — cost-effective alternative)

# 3. Build the sandbox image (one-time, ~5 min)
docker build -t cve-fixer-sandbox:latest sandbox/

# 4. Run
sentinel fix-cve --repo https://github.com/anupamojha-eng/vulnerable-data-pipeline

Running via API (FastAPI server)

python3 orchestrator/driver.py  # starts on :8080

curl -X POST http://localhost:8080/remediate \
  -H "Content-Type: application/json" \
  -d '{"repo_url": "https://github.com/org/repo", "target_tag": "main"}'

Architecture

┌─────────────────────────────────────────────────────────┐
│                    orchestrator/                         │
│                                                         │
│  cli.py           `sentinel` CLI entry point            │
│  driver.py        FastAPI service — HTTP entry point    │
│  factory.py       RemediationFactory                    │
│    ├─ _detect_build_system()   Maven/Gradle/Python      │
│    ├─ _scan_internal()         resolve deps → OSV API   │
│    │    └─ _scan_with_osv_scanner()  fallback           │
│    ├─ _get_verify_command()    build tool selector      │
│    └─ retry loop (MAX=3)       smart error routing      │
│                                                         │
│  remediator.py    RemediationActor                      │
│    ├─ get_vulnerable_code_files()  grep → source files  │
│    ├─ get_affected_java_files()    parse compile errors  │
│    ├─ autonomous_patch()           LLM → write → verify │
│    ├─ create_pull_request()        branch → push → PR   │
│    ├─ _build_pr_body()             audit trail          │
│    └─ _patch_fallback()            save diff locally    │
│                                                         │
│  llm_client.py    SecurityAgentClient                   │
│    ├─ _AnthropicProvider  Claude Opus 4.8 (default)     │
│    ├─ _GeminiProvider     Gemini 2.5 Flash (alt)        │
│    ├─ get_vulnerable_patterns()    CVE → grep strings   │
│    └─ get_remediation_plan()       full patch plan      │
└─────────────────────────────────────────────────────────┘
                           │
                           │ Docker SDK
                           ▼
┌─────────────────────────────────────────────────────────┐
│               sandbox/  (Docker image)                   │
│                                                         │
│  JDK 17 · Maven 3.9 · Gradle 9.4 · OSV-Scanner         │
│  Python 3 · pip3 · git                                  │
│                                                         │
│  Isolated per-run: no shared state between remediations │
└─────────────────────────────────────────────────────────┘

Running tests

# Fast unit tests (no Docker, no API keys)
pytest tests/test_python_support.py tests/test_patching.py \
       tests/test_build_detection.py tests/test_scanner.py -v

# Docker e2e — needs Docker + LLM key
pytest tests/test_e2e_docker.py -v -s              # Java
pytest tests/test_e2e_python_docker.py -v -s       # Python

# Source patching e2e
pytest tests/test_java_source_patching_e2e.py -v -s
pytest tests/test_python_source_patching_e2e.py -v -s

# Full pipeline — needs Docker + LLM key + GITHUB_TOKEN
pytest tests/test_real_repo_e2e.py -v -s           # Java
pytest tests/test_real_python_repo_e2e.py -v -s    # Python

Technical stack

  • CLI: Click — sentinel fix-cve --repo <url>
  • Orchestrator: Python / FastAPI — container lifecycle, retry loop, GitHub API
  • Sandbox: Docker (JDK 17, Maven 3.9.15, Gradle 9.4.1, OSV-Scanner, Python 3 + pip)
  • Scanning: mvn dependency:list / gradle dependencies / pip list + OSV REST API; OSV-Scanner (fallback)
  • Reasoning: Multi-provider — Anthropic Claude (default) or Google Gemini
  • Version control: PyGithub — fork, branch, commit, PR

LLM provider comparison

Claude Opus 4.8 (default) Gemini 2.5 Flash
Complex multi-file patches Excellent Good
JSON output reliability Excellent Good
Prompt caching on retries Yes (~80% savings) No
Speed Moderate Fast
Cost per run Higher Lower

Set ANTHROPIC_API_KEY for Claude, GEMINI_API_KEY for Gemini, or both (Claude wins when both set).
Override with ANTHROPIC_MODEL=claude-sonnet-4-6 or GEMINI_MODEL=gemini-2.5-pro.


Roadmap

  • sentinel fix-antipatterns — standalone anti-pattern fixing without a CVE trigger
  • Local LLM mode — Ollama + quantized model for air-gapped / zero-cost runs
  • OSV offline cache — local SQLite built from OSV data dumps, no API calls
  • Go (go.mod) and Rust (Cargo.toml) ecosystem support
  • GitHub Actions integration — trigger on Dependabot alert webhook
  • Container image scanning — pair with Chainguard Wolfi or distroless base images

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md for vulnerability disclosure policy.

License

Apache License 2.0 — see LICENSE.
Copyright 2026 Anupam Ojha

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sentinel_remediation-0.1.0.tar.gz (53.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sentinel_remediation-0.1.0-py3-none-any.whl (35.0 kB view details)

Uploaded Python 3

File details

Details for the file sentinel_remediation-0.1.0.tar.gz.

File metadata

  • Download URL: sentinel_remediation-0.1.0.tar.gz
  • Upload date:
  • Size: 53.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for sentinel_remediation-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e6a40a960a9418775944f290304f908fc4b21f2047dc5eaf20b084bad7e2dd6f
MD5 1ac4792066af15b32809cbb37560c111
BLAKE2b-256 be36825bf0dee47c9b774783156dcd47f76e33bae4ce271aa76cfd925a34416e

See more details on using hashes here.

File details

Details for the file sentinel_remediation-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sentinel_remediation-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 53cd2975698967da89e1cff1101ef014e0ca3046a42b1089682b78ae1e89e44d
MD5 079eac4e35014a85b550b03e27799c32
BLAKE2b-256 9ba528ce36cb8aeeec50facd11247911a37757f7713f36052cbf5ac34fcc748f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page