May 29, 2026
How to install and configure Vigolium for vulnerability scanning
Security teams have always operated in a bind: either spend weeks running manual audits and miss half the attack surface, or deploy aโฆ

By Mealer Mike
12 min read
Security teams have always operated in a bind: either spend weeks running manual audits and miss half the attack surface, or deploy a scanner that fires off a thousand alerts and buries the real issues under noise. Vigolium steps into that gap with a different posture. It is an open-source vulnerability scanner that pairs a deterministic multi-phase pipeline with an agentic AI runtime, giving operators a tool that can both follow a fixed playbook and think through unexpected targets on its own.
The project went public in May 2026 and already ships with 235+ scanner modules, an in-process agent runtime called olium, and a JavaScript extension engine that lets teams write their own scan hooks. That is a substantial surface area for a first open-source release. This guide walks through every step of getting it running, from system requirements to tuning the AI agent budget caps, so you are not left guessing at defaults.
What Vigolium actually does
Before touching a terminal, it is worth knowing what distinguishes Vigolium from older scanners like Nikto or OpenVAS.
Classic scanners run a fixed list of checks. They are deterministic, predictable, and fast. They are also blind to anything outside their ruleset. Vigolium keeps that deterministic path โ the vigolium scan command โ but adds a second path: vigolium agent. The agent hands control to a large language model that selects modules, rewrites scan logic mid-run, generates custom JavaScript extensions on the fly, and performs source-code audits alongside dynamic probing.
Two scanning paths, two different risk profiles. The deterministic path is appropriate for CI pipelines where you need consistent, budget-capped runs. The agent path suits deep dives where a human analyst would normally be burning hours chasing one target.
The project is licensed under AGPL-3.0, which means modifications and forks must be published. The commercial Cloud Console sits on top as an operational layer โ scheduling, multi-user collaboration, hosted infrastructure โ but the detection logic stays in the open repository. Jessie Ho, the tool's author, has been explicit about this: the day detection capability migrates to a paid tier, the project's credibility collapses. That public commitment matters when evaluating whether to build workflows around the tool.
System requirements
Vigolium is written in Go, which means the binaries are self-contained and cross-platform. You do not need to manage a Python virtual environment or wrestle with system library versions.
Minimum requirements:
- 64-bit operating system: Linux, macOS, or Windows
- 2 GB RAM for basic deterministic scans
- 4 GB RAM if you plan to use the agent runtime
- Internet access for initial module fetches and LLM API calls
- A valid API key for your chosen LLM provider if using
vigolium agent
For CI environments, the Docker image is the cleanest path. For local workstations and dedicated security VMs, the pre-built binary is faster to get started.
Installation
Option 1: Pre-built binary (recommended for most users)
Head to the releases page and grab the archive that matches your platform. The naming convention is straightforward:
vigolium_linux_amd64.tar.gz
vigolium_darwin_arm64.tar.gz
vigolium_windows_amd64.zipvigolium_linux_amd64.tar.gz
vigolium_darwin_arm64.tar.gz
vigolium_windows_amd64.zipOn Linux or macOS:
# Download and extract (adjust version and platform as needed)
curl -LO https://github.com/vigolium/vigolium/releases/latest/download/vigolium_linux_amd64.tar.gz
tar -xzf vigolium_linux_amd64.tar.gz
# Move the binary to your PATH
sudo mv vigolium /usr/local/bin/
sudo chmod +x /usr/local/bin/vigolium
# Verify the install
vigolium --version# Download and extract (adjust version and platform as needed)
curl -LO https://github.com/vigolium/vigolium/releases/latest/download/vigolium_linux_amd64.tar.gz
tar -xzf vigolium_linux_amd64.tar.gz
# Move the binary to your PATH
sudo mv vigolium /usr/local/bin/
sudo chmod +x /usr/local/bin/vigolium
# Verify the install
vigolium --versionOn Windows, extract the zip and either add the folder to your PATH environment variable or run the binary directly from the extracted directory.
Option 2: Build from source
If you want the absolute latest commits or need to modify internals, build from source. You need Go 1.22+ installed.
git clone https://github.com/vigolium/vigolium.git
cd vigolium
go build -o vigolium ./cmd/vigolium
sudo mv vigolium /usr/local/bin/git clone https://github.com/vigolium/vigolium.git
cd vigolium
go build -o vigolium ./cmd/vigolium
sudo mv vigolium /usr/local/bin/The build step compiles cleanly with no external C dependencies. The golangci.yml in the repo enforces lint rules, so the codebase is tidy if you plan to read it.
Option 3: Docker
The Docker image works well for isolated runs or when you want to keep the scanner off your host filesystem entirely.
docker pull ghcr.io/vigolium/vigolium:latest
# Basic scan using Docker
docker run --rm ghcr.io/vigolium/vigolium:latest vigolium scan --target https://example.comdocker pull ghcr.io/vigolium/vigolium:latest
# Basic scan using Docker
docker run --rm ghcr.io/vigolium/vigolium:latest vigolium scan --target https://example.comFor the agent mode, you will need to pass LLM API credentials as environment variables:
docker run --rm \
-e OPENAI_API_KEY=your_key_here \
ghcr.io/vigolium/vigolium:latest \
vigolium agent --target https://example.comdocker run --rm \
-e OPENAI_API_KEY=your_key_here \
ghcr.io/vigolium/vigolium:latest \
vigolium agent --target https://example.comBasic configuration
Vigolium picks up a configuration file from ~/.vigolium/config.yaml by default. You can override this with the --config flag. The file is YAML and controls everything from proxy settings to output formats.
A minimal config:
output:
format: jsonl
file: ./results.jsonl
http:
timeout: 30s
retries: 3
user_agent: "Vigolium/1.0"
proxy:
url: "" # Set to http://127.0.0.1:8080 for Burp Suite interceptionoutput:
format: jsonl
file: ./results.jsonl
http:
timeout: 30s
retries: 3
user_agent: "Vigolium/1.0"
proxy:
url: "" # Set to http://127.0.0.1:8080 for Burp Suite interceptionSetting up a proxy for traffic inspection
Pairing Vigolium with Burp Suite or OWASP ZAP lets you inspect and replay every request the scanner generates. This is particularly useful when tuning custom extensions or debugging why a specific finding did not trigger.
proxy:
url: "http://127.0.0.1:8080"
insecure: true # Required to accept Burp's self-signed certificateproxy:
url: "http://127.0.0.1:8080"
insecure: true # Required to accept Burp's self-signed certificateWith Burp running in the background on port 8080, every Vigolium request will appear in the HTTP history panel. You can then replay modified versions of those requests directly from Burp, which saves significant time compared to reconstructing requests by hand.
Running your first scan
Deterministic scan
The deterministic pipeline runs content discovery, browser-based spidering, and passive plus active auditing in sequence. Start with a simple target:
vigolium scan --target https://testphp.vulnweb.comvigolium scan --target https://testphp.vulnweb.comtestphp.vulnweb.com is a deliberately vulnerable PHP application maintained by Acunetix for testing purposes โ a safe and legal target for learning.
For a real engagement, specify the output format upfront:
vigolium scan \
--target https://your-target.com \
--output ./findings.jsonl \
--format jsonl \
--depth 3 \
--threads 10vigolium scan \
--target https://your-target.com \
--output ./findings.jsonl \
--format jsonl \
--depth 3 \
--threads 10The --depth flag controls spidering depth. Three is a reasonable starting point for most web applications. Push it to five or six for SPAs with deep routing structures, but expect significantly longer runtimes.
Filtering output by severity
By default, Vigolium reports everything. On large targets, that output is overwhelming. Filter by severity:
vigolium scan \
--target https://your-target.com \
--severity high,criticalvigolium scan \
--target https://your-target.com \
--severity high,criticalThis drops informational and low-severity findings from the output without affecting the underlying scan logic. The scanner still runs all checks; it just suppresses the noise during reporting.
Scoping the scan
Vigolium respects scope definitions. Pass a scope file to restrict the scanner to specific paths or subdomains:
vigolium scan \
--target https://your-target.com \
--scope ./scope.txtvigolium scan \
--target https://your-target.com \
--scope ./scope.txtThe scope file accepts one pattern per line, with glob syntax:
https://your-target.com/api/*
https://admin.your-target.com/*https://your-target.com/api/*
https://admin.your-target.com/*Anything outside the defined scope gets skipped at the request level. This is not just a post-filter โ Vigolium uses the scope during discovery, so it does not spider out-of-scope URLs in the first place.
Configuring the AI agent
The vigolium agent command is where the tool separates itself from conventional scanners. The agent uses an LLM backend to plan attacks, select which modules to run against specific endpoints, generate JavaScript extensions mid-scan, and triage findings autonomously.
LLM provider setup
Vigolium supports multiple LLM backends. Set your provider and key in the configuration file or via environment variables:
agent:
provider: openai # openai, anthropic, or local
model: gpt-4o
api_key: "${OPENAI_API_KEY}"agent:
provider: openai # openai, anthropic, or local
model: gpt-4o
api_key: "${OPENAI_API_KEY}"For teams concerned about data residency, the local provider connects to any Ollama instance running on-premises. Smaller models like Mistral 7B work for triage tasks, though the module-generation quality drops noticeably compared to frontier models.
agent:
provider: local
base_url: http://localhost:11434
model: mistralagent:
provider: local
base_url: http://localhost:11434
model: mistralBudget caps โ the most important setting
The agent is autonomous. Left uncapped, it will keep re-planning and re-probing until it runs out of time or money. Vigolium exposes four caps that every operator should set explicitly.
agent:
budget:
max_tokens: 200000 # Total LLM tokens across the run
max_tool_calls: 150 # Total tool invocations
max_triage_iterations: 20 # How many times it re-checks a finding
max_wall_clock: "45m" # Hard time limit for the entire runagent:
budget:
max_tokens: 200000 # Total LLM tokens across the run
max_tool_calls: 150 # Total tool invocations
max_triage_iterations: 20 # How many times it re-checks a finding
max_wall_clock: "45m" # Hard time limit for the entire runHo's public guidance on this is worth repeating directly: for time-boxed penetration tests or CI runs, lean on the wall-clock and iteration caps so the scan always finishes. For a deep dive on a single target, loosen tokens and let the agent re-plan. For broad sweeps across many targets, keep per-target budgets tight โ one interesting target can consume everything if there is no ceiling.
Start tight. If findings are getting cut off mid-investigation โ you will see truncated stubs in the output โ loosen the caps incrementally. The failure mode of over-budgeting is not catastrophic, but it is expensive and produces noisy output that takes time to review.
Running the agent
vigolium agent \
--target https://your-target.com \
--config ./vigolium-agent.yaml \
--output ./agent-findings.jsonlvigolium agent \
--target https://your-target.com \
--config ./vigolium-agent.yaml \
--output ./agent-findings.jsonlWatch the console output. The agent logs its decisions: which module it selected, why it flagged a specific endpoint, and what evidence it collected before triaging a finding. That logging is genuinely useful for understanding why a given detection triggered, which older scanners offer almost nothing on.
Writing custom extensions
Vigolium's JavaScript engine lets teams write scan modules and request hooks without touching the Go core. Extensions use a session-aware HTTP API that provides access to request history, response bodies, and the current cookie jar.
A minimal extension that flags endpoints returning stack traces:
// stack-trace-detector.js
hooks.afterResponse(function(req, res) {
var body = res.body();
if (body.includes("at ") && body.includes(".java:") || body.includes("Traceback")) {
findings.add({
title: "Stack trace in response",
severity: "medium",
url: req.url(),
evidence: body.substring(0, 500)
});
}
});// stack-trace-detector.js
hooks.afterResponse(function(req, res) {
var body = res.body();
if (body.includes("at ") && body.includes(".java:") || body.includes("Traceback")) {
findings.add({
title: "Stack trace in response",
severity: "medium",
url: req.url(),
evidence: body.substring(0, 500)
});
}
});Load extensions at scan time:
vigolium scan \
--target https://your-target.com \
--extension ./stack-trace-detector.jsvigolium scan \
--target https://your-target.com \
--extension ./stack-trace-detector.jsOne thing to be clear about: extensions execute arbitrary code with no sandbox. This is a deliberate design choice โ sandboxing would prevent the kinds of complex probes that make custom modules useful โ but it means you should treat third-party extensions with the same caution you would any executable. Ho has acknowledged that a community module registry would essentially be distributing executables, and has indicated that any such system would need provenance signing, an untrusted-by-default posture, and active curation rather than open submission. Until that exists, only run extensions from sources you control or have audited.
For teams building internal extension libraries, Goja powers the JavaScript runtime. Understanding its API surface is useful when debugging unexpected behavior in complex extensions.
Integrating Vigolium into CI/CD pipelines
Vigolium fits cleanly into GitHub Actions, GitLab CI, and Jenkins pipelines. The JSONL output format is designed for machine parsing, and the binary's exit codes signal clean runs versus finding-detected runs.
GitHub Actions example
name: Security scan
on:
push:
branches: [main]
pull_request:
jobs:
vigolium-scan:
runs-on: ubuntu-latest
steps:
- name: Download Vigolium
run: |
curl -LO https://github.com/vigolium/vigolium/releases/latest/download/vigolium_linux_amd64.tar.gz
tar -xzf vigolium_linux_amd64.tar.gz
sudo mv vigolium /usr/local/bin/
- name: Run scan
run: |
vigolium scan \
--target ${{ secrets.TARGET_URL }} \
--severity high,critical \
--output ./findings.jsonl \
--format jsonl
- name: Upload findings
uses: actions/upload-artifact@v4
with:
name: vigolium-findings
path: ./findings.jsonlname: Security scan
on:
push:
branches: [main]
pull_request:
jobs:
vigolium-scan:
runs-on: ubuntu-latest
steps:
- name: Download Vigolium
run: |
curl -LO https://github.com/vigolium/vigolium/releases/latest/download/vigolium_linux_amd64.tar.gz
tar -xzf vigolium_linux_amd64.tar.gz
sudo mv vigolium /usr/local/bin/
- name: Run scan
run: |
vigolium scan \
--target ${{ secrets.TARGET_URL }} \
--severity high,critical \
--output ./findings.jsonl \
--format jsonl
- name: Upload findings
uses: actions/upload-artifact@v4
with:
name: vigolium-findings
path: ./findings.jsonlFor pipelines that should fail on critical findings, parse the JSONL output and check for severity values before the workflow completes. A small Python script or jq one-liner handles this without adding dependencies.
# Fail the pipeline if any critical findings exist
jq -e '[.[] | select(.severity == "critical")] | length == 0' findings.jsonl# Fail the pipeline if any critical findings exist
jq -e '[.[] | select(.severity == "critical")] | length == 0' findings.jsonlGitLab CI example
vigolium-scan:
image: ghcr.io/vigolium/vigolium:latest
stage: security
script:
- vigolium scan --target $TARGET_URL --severity high,critical --output ./findings.jsonl
artifacts:
paths:
- findings.jsonl
when: alwaysvigolium-scan:
image: ghcr.io/vigolium/vigolium:latest
stage: security
script:
- vigolium scan --target $TARGET_URL --severity high,critical --output ./findings.jsonl
artifacts:
paths:
- findings.jsonl
when: alwaysConnecting Vigolium to external tools via MCP servers
MCP (Model Context Protocol) servers let agents and tools exchange structured data with external services. Teams using the Vigolium agent can extend its capabilities by connecting it to MCP-compatible tools.
Some useful MCP servers for security workflows:
Semgrep MCP server โ Lets the Vigolium agent pull static analysis rules from Semgrep during source-code audits. When the agent requests a custom JavaScript extension that targets a specific vulnerability class, Semgrep patterns can inform the extension's detection logic.
GitHub MCP server โ Connects the agent to GitHub's API. Useful for pulling source code context when performing authenticated scans against applications where you have repository access. The agent can cross-reference live traffic patterns against source code paths.
Shodan MCP server โ Feeds passive reconnaissance data into the agent's planning phase. Before the agent selects modules, it can query Shodan for open ports, exposed services, and known vulnerabilities associated with the target IP.
Nuclei MCP server โ Nuclei maintains one of the largest open-source template libraries for vulnerability detection. Bridging Nuclei's template library into the Vigolium agent's module-selection logic gives it access to thousands of community-validated checks that go beyond Vigolium's 235 built-in modules.
VirusTotal MCP server โ Useful in triage. After the agent identifies a suspicious endpoint or file, it can query VirusTotal for reputation data before escalating a finding to high severity. This cuts false positives on findings that turn out to be known-safe assets.
JIRA MCP server โ For teams managing findings in Jira, this server lets the agent write validated findings directly to a project board. Automated ticket creation from the triage phase removes a manual handoff step that security teams consistently cite as a time sink.
Slack MCP server โ Sends real-time notifications from the agent's run to a Slack channel. Configure this for unattended overnight scans so the team gets a morning summary without polling a results file.
Configure MCP servers in the agent configuration:
agent:
mcp_servers:
- name: semgrep
url: https://mcp.semgrep.com/sse
- name: shodan
url: https://mcp.shodan.io/sse
env:
SHODAN_API_KEY: "${SHODAN_API_KEY}"agent:
mcp_servers:
- name: semgrep
url: https://mcp.semgrep.com/sse
- name: shodan
url: https://mcp.shodan.io/sse
env:
SHODAN_API_KEY: "${SHODAN_API_KEY}"Understanding the triage system
Vigolium separates finding and triage into distinct passes. The scanner identifies candidates; the triage pass re-checks each one against its evidence before producing a final output. This is worth understanding because it affects how you interpret results.
The triage system favors merging over deletion. If the agent identifies the same injection point through two different module paths, it collapses those into a single finding rather than counting them twice. What it does not do is silently drop anything it is uncertain about. Borderline findings โ things the agent could not fully reproduce โ get downgraded in severity and retained in the output with a confidence marker. They do not disappear.
That posture matters operationally. It means your review queue will contain some low-confidence findings that did not reproduce cleanly. That is not a bug. It is the system preserving signal it is not confident enough to act on. A human analyst reviewing the output should treat low-confidence findings as leads to investigate manually rather than confirmed vulnerabilities.
The alternative โ silently dropping anything the agent is uncertain about โ would make the output look cleaner while hiding real vulnerabilities that happen to be difficult to reproduce automatically. Vigolium's design explicitly rejects that trade-off.
Output formats and post-processing
Vigolium supports three output formats: JSONL, JSON, and a human-readable text format. JSONL is the most useful for automated workflows because each line is a self-contained finding object that tools like jq, Splunk, or Elastic can ingest without parsing an entire file.
Each finding object includes:
{
"title": "Reflected XSS",
"severity": "high",
"confidence": "confirmed",
"url": "https://target.com/search?q=<payload>",
"parameter": "q",
"evidence": "Response body: <script>alert(1)</script>",
"module": "xss/reflected",
"timestamp": "2026-05-29T14:23:01Z"
}{
"title": "Reflected XSS",
"severity": "high",
"confidence": "confirmed",
"url": "https://target.com/search?q=<payload>",
"parameter": "q",
"evidence": "Response body: <script>alert(1)</script>",
"module": "xss/reflected",
"timestamp": "2026-05-29T14:23:01Z"
}For teams feeding findings into a SIEM, the timestamp and module fields make it straightforward to correlate scan output with other security telemetry. The confidence field โ confirmed, probable, or unconfirmed โ is the triage system's verdict and should drive how you prioritize remediation.
Common troubleshooting
The agent stops mid-run with "budget exceeded"
Your max_tokens or max_wall_clock cap is too tight for the target. Increase max_tokens by 50% and re-run. If it stops again at the same point, the issue is the target's complexity rather than the budget being unreasonably low.
No findings on a target you know is vulnerable
Check the scope configuration first. A common mistake is scoping too narrowly โ the scanner respects scope at the request level, so if your scope file does not include the vulnerable path, the scanner will not probe it.
Extensions not loading
Extensions must be valid JavaScript that Goja can parse. Run the extension file through Node.js locally first to catch syntax errors. Goja supports ES5 and a subset of ES6; avoid ES2017+ features like async/await.
High false-positive rate on XSS findings
Vigolium's XSS module covers reflected, stored, and DOM-based XSS, including WAF-bypass encoded payloads, as of the latest commits. If false positives are high, check whether the target application is returning payloads in non-HTML contexts like JSON responses. Scope the XSS module with a response-type filter in your config.
Practical notes on scope and authorization
Nothing in this guide should be read as permission to run Vigolium against systems you do not own or have explicit written authorization to test. The tool is aggressive โ it probes for vulnerabilities actively โ and running it against unauthorized targets is illegal in most jurisdictions under laws like the Computer Fraud and Abuse Act in the US and equivalent statutes elsewhere.
For practice targets, use HackTheBox, TryHackMe, or PortSwigger Web Security Academy โ all of which provide intentionally vulnerable targets in a legal environment. Vigolium is a sharp tool. Use it on targets where you have the paperwork to back it up.
What to watch as the project matures
Vigolium is days old as an open-source project. The repository has 477 stars and 69 forks already, which is a signal that the security community took notice fast. A few things worth watching:
The extension registry question is unresolved. Ho's position is that an open submission model is a security liability, and that any registry needs curation and signing infrastructure before it launches. Teams building on the extension system should expect that their internal libraries will stay internal for the foreseeable future, which is not necessarily a bad thing given the no-sandbox execution model.
The XSS modules are actively evolving. The May 29, 2026 commit added stored XSS, DOM-XSS taint tracking, encoded payloads, and WAF-awareness in a single push. The pace of detection development is fast, which means running with the latest binary matters more than with more stable tools.
The CHANGELOG.md is worth reading before any significant engagement. Breaking changes in scan module behavior will show up there before they surface in unexpected output differences.
Vigolium sits in an interesting position: open enough to audit, commercial enough to sustain, and architecturally distinct enough that it does not just replicate what Nuclei or Burp Suite Professional already do. Whether the agentic runtime delivers consistent value in real engagements is something security teams will determine by running it. Start with the deterministic path, understand your targets' baseline findings, then let the agent loose on the same target and compare. That delta will tell you whether the AI layer is earning its API costs.