vigolium agent autopilot is the single-loop agentic scan, one long-running LLM session decides what to investigate, drives tools (bash, file I/O, web fetch, vigolium CLI commands), reports findings to the database as it confirms them, and halts on its own when it has nothing productive left to do.
It is the simplest of the agentic-scan modes, there is no master/worker pipeline, no plan/triage phase split, just one engine running until it calls halt_scan.
Mental model
Think of it as a security analyst sitting at a terminal:- The analyst is given a target URL, optionally a source tree, and a focus hint.
- They have shell access, file-read access, web access, and the vigolium CLI.
- They poke around, follow leads, write findings to a notebook as they confirm each bug, and stop when there is nothing more worth digging into.
findings table.
Lifecycle (high-level)
CLI
Key flags
| Flag | Default | Description |
|---|---|---|
-t, --target | , | Target URL (derived from --input if omitted) |
--input | , | Raw input (curl, raw HTTP, Burp XML, base64, URL). Reads stdin if piped |
--record-uuid | , | Use an HTTP record from the database as the seed input |
--source | , | Path to application source code (or git URL, auto-cloned). Auto-runs vigolium-audit. |
--files | , | Specific files to include (relative to --source) |
--focus | , | Focus area hint (e.g. "auth bypass", "API injection") |
--instruction / --instruction-file | , | Custom instruction appended to prompt |
--intensity | balanced | Preset bundle: quick / balanced / deep. Sets the command budget (quick=150, balanced=500, deep=1500 turns), audit mode, browser, and pre-scan strategy |
--audit | lite (with --source) | Vigolium-audit mode: lite / balanced / deep / mock / off |
--browser | false | Enable agent-browser for browser-based interactions |
--credentials | , | Credentials for auth preflight (e.g. "admin/admin123") |
--auth-required | false | Require auth/session preparation before the operator starts |
--requires-browser | false | Require browser-assisted auth instead of HTTP-only preflight |
--browser-start-url | , | Explicit browser/login start URL |
--focus-routes | , | Protected/browser-focused routes to prioritize |
--diff | , | Focus on changed code (PR URL, main...branch, HEAD~N) |
--last-commits | , | Shorthand for --diff HEAD~N |
--max-duration | 6h | Wall-clock cap (intensity preset sets this — quick=1h, balanced=6h, deep=12h) |
--triage | false | Run an AI triage pass over findings after the scan (confirm real issues vs false positives) |
--skill | , | Force-load these skills by name, bypassing the pre-flight selection (repeatable or comma-separated) |
--skill-tag | , | Force-load every skill carrying one of these tags (e.g. xss,idor) |
--no-skill-filter | false | Load the full skill set; skip the pre-flight skill selection |
--db-isolate | false | Scan into a private temporary database, then merge results into --db at the end (lets parallel runs share one DB; SQLite only) |
--plan-file | , | Plan file mixing free-text guidance + raw HTTP request(s); owns the instruction + seed input (mutually exclusive with --input/--instruction/--instruction-file) |
--piolium | , | Run piolium audit instead of vigolium-audit when --source is set (lite/balanced/deep/longshot/…); empty auto-picks piolium when pi is installed |
--no-prescan | false | Skip the native pre-scan that seeds http_records before the operator (target-only runs; no-op with --source) |
--upload-results | false | Upload session bundle to cloud storage on completion |
--provider | (config) | Olium provider override |
--model | (config) | Model id override |
--oauth-cred / --oauth-token / --llm-api-key | (config) | Provider credential overrides |
--system | , | Extra text appended to the built-in system prompt |
--dry-run | false | Render prompt without launching agent |
--show-prompt | false | Print rendered prompt to stderr before executing |
API
EffectiveSourcePath() accepts either source or the legacy repo_path JSON field. The server resolves provider/model from agent.olium.* by default; pass api_key, oauth_token, oauth_cred_file, or oauth_cred_json on the same request to override per call. Returns 202 Accepted with {agentic_scan_uuid, status}. Set stream: true for an SSE response.
What the agent actually has access to
The autopilot is not restricted to the vigolium CLI. The engine ships a generic agentic toolset; security-specific behavior comes from the system prompt and skills, not from the tool surface itself.| Tool | Notes |
|---|---|
bash | Unsandboxed shell. Catastrophic patterns (e.g. rm -rf /) hard-rejected. |
read_file | Read-only. Parallelizable. |
write_file | Side-effect; serial only. |
edit_file | Side-effect; serial only. |
ls | Parallelizable. |
grep | Parallelizable. |
glob | Parallelizable. |
web_fetch | Parallelizable. |
load_skill | Pulls a skill body by name (skills are indexed in the system prompt). |
halt_scan | Autopilot-only. Sets HaltSignal, engine exits naturally next turn. |
report_finding | Autopilot-only. Writes a Finding row scoped to the AgenticScan UUID. |
vigolium scan-url, vigolium finding, etc., those are shell commands, not first-class tools. The agent runs them via bash if it judges them useful.
Provider selection
olium.ResolveProvider picks the backend in this order:
- CLI override (
--provider) - Config file (
agent.olium.providerinvigolium-configs.yaml) - Default →
openai-compatiblewithgemma4:latest(a local Ollama endpoint)
| Provider | Typical model | Credential |
|---|---|---|
openai-codex-oauth | gpt-5.5 | OAuth cred file (--oauth-cred / agent.olium.oauth_cred_path) |
anthropic-api-key | claude-opus-4-7 | --llm-api-key / $ANTHROPIC_API_KEY |
anthropic-oauth | claude-opus-4-7 | Bearer token from claude setup-token (--oauth-token / $ANTHROPIC_API_KEY) |
openai-api-key | gpt-5.5 | --llm-api-key / $OPENAI_API_KEY |
anthropic-cli | claude-opus-4-7 | The local claude binary on $PATH |
anthropic-vertex | claude-opus-4-6 | GCP service-account JSON + project/location |
google-vertex | gemini-2.5-pro | Same GCP creds; routes gemini-* models |
openai-compatible | gemma4:latest | custom_provider.base_url (Ollama, OpenRouter, LM Studio, vLLM, …); api_key optional |
EnablePromptCache: true) is set on the engine; only the Anthropic providers and the Codex OAuth provider actually emit cache markers — openai-compatible (including Ollama) and openai-api-key ignore them.
Intensity presets
--intensity bundles several settings; explicit flags always override.
| Preset | MaxCommands | Timeout | Vigolium-audit mode | Browser |
|---|---|---|---|---|
quick | 150 | 1h | lite | on |
balanced (default) | 500 | 6h | balanced | on |
deep | 1500 | 12h | deep | on |
MaxCommands is the autopilot’s own turn cap (the agent’s DefaultAutopilotMaxTurns is 200; intensity overrides it). When the cap is hit the run ends with an error event — the model didn’t get to halt cleanly. agent.olium.max_turns applies to the shorter, non-autopilot engine uses (swarm phases, source analysis, query), not to autopilot.
Halt conditions
The autopilot exits in one of four ways:- Natural halt: model calls
halt_scan. The current turn is allowed to finish; the engine then sees no further tool calls on the next turn and emitsEventRunDone.Result.Halted=true,HaltReasonpopulated. - Quiet halt: model finishes a turn with no tool calls and no
halt_scan. Treated as a natural stop. - Max turns: turn count hits
MaxCommands. Engine emits anEventError; autopilot returns a non-nil error. - Context cancelled: timeout or SIGINT/SIGTERM. Engine teardown cancels in-flight tools.
report_finding:
- soft warning at 50 findings (still saved)
- hard cap at 200 (rejected with an
IsErrorresult that nudges the model towardhalt_scan)
Findings persistence
Every successfulreport_finding call writes a row via repo.SaveFindingDirect. Key fields:
ProjectUUID,ScanUUID,AgenticScanUUID, propagate the project/scan scope sovigolium findingandvigolium agent sessionscan join back.ModuleID = "olium-autopilot",ModuleType = "ai-agent",FindingSource = "autopilot", distinguishes agent-originated findings from scanner-module findings.FindingHash: SHA-256 over (title, severity, source_file, url, description-fingerprint), or over an explicitdedup_keyif the model supplies one. The DB’sON CONFLICThandler squashes duplicates.
AgenticScan row is just updated to status=failed with the error message, but everything saved before that point stays in the DB.
Session artifacts
For each run, autopilot creates a UUID-named directory underagent.sessions_dir (default ~/.vigolium/agent-sessions/):
AgenticScan.uuid row, so vigolium agent sessions and vigolium log <uuid> both work without extra plumbing. Stale dirs older than 48h are swept on startup; orphan PID files (from SIGKILL’d runs) are cleared via agent.CleanupOrphanedProcesses.
Source-aware mode
When--source is set, three things change:
- Source resolution: accepts local paths, git URLs (cloned to a temp dir),
--diff PR-url|ref...ref|HEAD~N, and--last-commits N. The agent gets a local path and (optionally) a list of changed files. - Initial prompt mode hint: the prompt switches between blackbox (“probe the live target”), whitebox (“navigate the source tree”), or a greybox blend (“read the code to find what’s risky, then probe”).
- Skill scope: embedded skills +
~/.vigolium/skills/are indexed in the system prompt; scan-specific skills likeaudit-authandtriage-findingare loadable viaload_skill.
--source is set, freezing its findings into vigolium-audit/ for the operator to consult.
Multi-app fan-out
When the positional prompt parses to multiple apps (vigolium agent autopilot "scan source at ~/src/A, ~/src/B"), the package-level autopilot flags are snapshotted and reapplied per app, then runAutopilotOlium is invoked sequentially for each. Each app gets its own session dir, AgenticScan row, and provider session.
A single-app prompt re-enters runAgentAutopilot directly with the parsed flags, same code path as a flag-driven invocation.
REST API workflow
autopilot.Run on a goroutine; the run UUID is returned immediately.
TL;DR
Autopilot is a single LLM agent on a leash made ofMaxCommands turns and Timeout wall-clock. It gets shell, files, and the web; vigolium-specific behavior is encoded entirely in the system prompt, two custom tools (halt_scan, report_finding), and the optional skills under ~/.vigolium/skills/. Findings are written as it goes; the run ends when the model halts itself, hits the turn cap, or gets cancelled.