
Automated security analysis pipeline that runs CodeQL queries on GitHub repositories and uses LLMs to classify and filter true vulnerabilities from false positives.
For a detailed overview of the research and motivation behind Vulnhalla, see the official CyberArk Threat Research blog post:
Vulnhalla: Picking the True Vulnerabilities from the CodeQL Haystack
Before starting, ensure you have:
Python 3.10 – 3.13 (Python 3.11 or 3.12 recommended)
CodeQL CLI
codeql is in your PATH, or you'll set the path in .env (see Step 2)(Optional) GitHub API token
LLM API key
All configuration is in a single file: .env
git clone https://github.com/cyberark/Vulnhalla
cd Vulnhalla
.env.example to .env:cp .env.example .env # macOS / Linux
Copy-Item .env.example .env # Windows (PowerShell)
.env and fill in your values:Example for OpenAI:
CODEQL_PATH=codeql
GITHUB_TOKEN=ghp_your_token_here
PROVIDER=openai
MODEL=gpt-4o
OPENAI_API_KEY=your-api-key-here
LLM_TEMPERATURE=0.2
LLM_TOP_P=0.2
# Optional: Logging Configuration
LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR
LOG_FILE= # Optional: path to log file (e.g., logs/vulnhalla.log)
LOG_FORMAT=default # default or json
# LOG_VERBOSE_CONSOLE=false # If true, WARNING/ERROR use full format (timestamp - logger - level - message)
📖 For complete configuration reference: See Configuration Reference below for all supported providers (OpenAI, Azure, Gemini, Bedrock), required/optional variables, and detailed examples.
Windows (PowerShell):
# List available Python versions
py -0p
# Pick any supported Python: 3.10 / 3.11 / 3.12 / 3.13
py -3.12 -m pip install --user -U pipx
py -3.12 -m pipx ensurepath
# Close and reopen terminal (required)
pipx install poetry
poetry --version
macOS / Linux:
# Check your Python version
python3 --version
# Use any supported Python: 3.10 / 3.11 / 3.12 / 3.13
python3 -m pip install --user -U pipx
python3 -m pipx ensurepath
# Restart terminal (required)
pipx install poetry
poetry --version
Windows (PowerShell):
# Pick one supported version you have: 3.10 / 3.11 / 3.12 / 3.13
poetry env use 3.12 # Force Poetry to use a supported Python version if you have multiple versions installed
poetry install
poetry run vulnhalla-setup
macOS / Linux:
# Pick one supported version you have: 3.10 / 3.11 / 3.12 / 3.13
poetry env use 3.12 # Force Poetry to use a supported Python version if you have multiple versions installed
poetry install
poetry run vulnhalla-setup
# Analyze a specific repository, for example:
poetry run vulnhalla redis/redis
# Re-download even if database already exists
poetry run vulnhalla redis/redis --force
# Show help
poetry run vulnhalla --help
This will automatically:
output/results/If you already have a CodeQL database on disk (e.g., created manually or from a previous run), you can skip the GitHub fetch step using the --local / -l flag:
Windows (PowerShell):
poetry run vulnhalla --local C:\path\to\my-codeql-db
macOS / Linux:
poetry run vulnhalla --local /path/to/my-codeql-db
Note: The
--localflag expects a CodeQL database directory, not a source code folder. You can verify by checking that the folder contains acodeql-database.ymlfile.
# Open UI to view existing results (without running analysis)
poetry run vulnhalla-ui
# Validate configuration: CodeQL, LLM, Logging (without running analysis)
poetry run vulnhalla-validate
# List analyzed repositories and their issue counts
poetry run vulnhalla-list
# Run example pipeline (analyzes videolan/vlc and redis/redis)
poetry run vulnhalla-example
Vulnhalla includes a full-featured User Interface for browsing and exploring analysis results.
poetry run vulnhalla-ui
The UI displays a two-panel top area with a controls bar at the bottom:
Top Area (side-by-side, resizable):
Left Panel (Issues List):
Right Panel (Details):
Bottom Controls Bar:
↑/↓ - Navigate issue list (row-by-row)Tab / Shift+Tab - Switch focus between panelsEnter - Show details for selected issue/ - Focus search input box (in left panel)Esc - Clear search and return focus to issues tabler - Reload results from disk[ / ] - Resize left/right panels (adjust split position)q - Quit application[ to move divider left, ] to move divider rightAfter running the pipeline, results are organized in output/results/<LANG>/<ISSUE_TYPE>/: