jederhion/vulnscan-ai
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
VulnScan AI
Multi-agent system that scans any GitHub repository for security vulnerabilities. Give it a repo URL, get back an actionable vulnerability report with severity ratings, CWE classifications, and suggested fixes.
Built with LangGraph, OpenAI Agents SDK, MCP (Model Context Protocol), and RAG.
Architecture
GitHub Repo URL
|
[Input Guardrails] --> validate URL, size, rate limits, prompt injection
|
[Orchestrator Agent - LangGraph] --> clone, detect language, fan out, collect, deduplicate, rank
|
+--------------------+--------------------+--------------------+
| | | |
| Static Analysis | Dependency Audit | Config/Secrets |
| Agent | Agent | Agent |
| | | |
+--------------------+--------------------+--------------------+
|
[Report Generator Agent]
|
[Output Guardrails] --> validate CVEs, CWE IDs, file paths, redact secrets
|
Vulnerability ReportMCP Servers
Three FastMCP servers (stdio transport) that provide tools for the scanner agents:
GitHub Server (mcp_servers/github_server.py)
Handles repo access — cloning, file listing, reading source code, and language detection.
clone_repo— shallow-clones a GitHub repo to a temp directorylist_files— lists source/config files, skipping irrelevant files (images, node_modules, etc.)read_file— reads file contents with line numbers for scanner referencedetect_languages— counts file extensions to determine repo languages
CVE/NVD Server (mcp_servers/cve_server.py)
Queries the National Vulnerability Database for known vulnerabilities in packages.
search_cves— search by package name + version, returns CVEs with severity scoresget_cve_details— full details for a specific CVE including CWE IDs and references
OWASP Patterns Server (mcp_servers/owasp_server.py)
Fast regex/heuristic pattern matching for OWASP Top 10 vulnerability patterns.
scan_code— scans source code against 13 vulnerability patterns (SQLi, XSS, command injection, hardcoded secrets, weak crypto, etc.)list_patterns— lists all available detection patterns with CWE mappings
Report Generator
OpenAI Agents SDK agent (report/report_generator.py) that produces the final vulnerability report.
- Deduplicates findings from multiple scanners (same file + line + CWE = one finding)
- Ranks by severity (Critical > High > Medium > Low) and confidence
- Generates structured JSON report with summary, findings, and prioritized remediation recommendations
Setup
# Install dependencies
uv sync
# Add your OpenAI API key
cp .env.example .env
# Edit .env with your key
# Run tests
PYTHONPATH=. uv run python tests/test_github_server.py
PYTHONPATH=. uv run python tests/test_cve_server.py
PYTHONPATH=. uv run python tests/test_owasp_server.py
PYTHONPATH=. uv run python tests/test_report_generator.pyvulnscan-ai
Agents module (/agents) This directory contains the specialized LLM scanning engines. Each agent is responsible for traversing a specific subset of files in a target directory, applying security analysis, and enriching the findings via the RAG Knowledge Base.
Exported Agents The module exposes three agent classes via _init_.py:
CodeAnalysisAgent: Scans core application logic (.py, .js, .go, etc.) for CWEs and SANS Top 25 flaws.
DependencyAuditAgent: Scans package manifests (requirements.txt, package.json, etc.) for vulnerable or outdated libraries.
SecretsAgent: Scans configuration and IaC files (.env, .yaml, Dockerfiles) for hardcoded credentials and severe misconfigurations.
🛠️ Interface & Integration Guide To use these agents in the Orchestrator (graph.py), follow these rules:
- Initialization Requirements Every agent must be initialized with an instance of the DynamicSecurityKnowledgeBase (from the rag/ module) so it can perform its own CVE enrichment.
- The Execution Method Every agent exposes a single public asynchronous method:
Method: await scannode(sourcepath: str)
Input: The absolute path to the directory being scanned. (The agent handles its own file filtering and directory ignoring internally).
Output: List[VulnerabilityFinding] (from shared.schemas). Returns an empty list [] if no vulnerabilities are found.
Example Orchestrator Integration from shared.schemas import VulnerabilityFinding from rag.retrieve import DynamicSecurityKnowledgeBase from agents import CodeAnalysisAgent, DependencyAuditAgent, SecretsAgent
async def runscanners(targetdir: str): # 1. Initialize the shared Knowledge Base ONCE kb = DynamicSecurityKnowledgeBase()
# 2. Instantiate the agents and inject the KB sastagent = CodeAnalysisAgent(kb=kb) depagent = DependencyAuditAgent(kb=kb) secrets_agent = SecretsAgent(kb=kb)
# 3. Execute the agents (can be done concurrently via asyncio.gather) codefindings = await sastagent.scannode(targetdir) depfindings = await depagent.scannode(targetdir) secretfindings = await secretsagent.scannode(targetdir)
# 4. Aggregate findings return codefindings + depfindings + secret_findings AI-assisted vulnerability scanning pipeline built with a LangGraph orchestrator and guardrails.
Overview
vulnscan-ai scans a target GitHub repository through a staged workflow:
- Validate request input (URL and prompt-injection checks)
- Clone repository
- Detect languages/files
- Run scanner agents
- Deduplicate and rank findings
- Validate and sanitize output findings
The project is organized so contributors can extend scanner agents without changing the full orchestration flow.
Workflow Diagram
Person A - LangGraph Orchestrator.
This is the master workflow. Think of it like a conveyor belt:
START
↓
[validate_input] <- guardrails check the URL
↓
[clone_repo] <- download the repo to a temp folder
↓
[detect_language] <- figure out Python? JS? Java?
↓
[scan_agents] <- run Person B's 3 agents in parallel
↓
[collect_findings] <- gather all results
↓
[deduplicate] <- remove duplicate findings
↓
[rank_findings] <- sort by severity
↓
[validate_output] <- guardrails check the results
↓
END -> return reportProject Structure
orchestrator/- workflow graph, state shape, and input/output guardrailsshared/- shared schemas (Finding,ScanState)agents/- security scanner agent implementations (static analysis, dependency audit, config/secrets)test_guardrails.py- quick smoke test for input guardrail behaviorrequirements.txt- pinned Python dependencies
Setup
From the repository root:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txtQuick Start
Run the guardrails smoke test:
python test_guardrails.pyRun the orchestrator directly:
python orchestrator/graph.pyOr run as a module:
python -m orchestrator.graphHow To Test Your Changes
Use this checklist before opening a PR:
- Environment
- Activate venv:
source .venv/bin/activate - Confirm interpreter:
which python - Guardrails
- Run:
python test_guardrails.py - Expect:
- valid GitHub URL passes
- non-GitHub URL fails
- prompt-injection-like URL fails
- Orchestrator smoke run
- Run:
python -m orchestrator.graph - Verify it starts workflow and exits cleanly for your test scenario
- Optional import sanity checks
python -c "from orchestrator.graph import run_scan; print('ok')"python -c "from orchestrator.guardrails import input_guardrails; print('ok')"
Notes For Contributors
- Keep
Findingschema fields backward compatible unless intentionally versioning. - If you add a new scanner agent, integrate it in
run_scan_agents()insideorchestrator/graph.py. - Guardrails are mandatory boundaries:
input_guardrails()before clone/scanoutput_guardrails()before returning final findings- Repositories cloned during scans are stored under
collected_repos/(gitignored).
Troubleshooting
- `Import "langgraph.graph" could not be resolved`
- Ensure IDE uses
.venvinterpreter for this workspace. - Reinstall dependencies:
python -m pip install -r requirements.txt - `ModuleNotFoundError: No module named 'orchestrator'`
- Run from repo root.
- Prefer module mode:
python -m orchestrator.graph - Slow/large repo scans
- Start with smaller target repos while developing.
- Consider adding/adjusting repo-size guardrails.
Git Hygiene
Common local artifacts are ignored via .gitignore, including:
.venv/__pycache__/collected_repos/- local cache/log files
License
Add your project license here (for example, MIT).
