> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vigolium.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Customizing & Extending Vigolium

> Covers every customization mechanism in Vigolium, from JS and YAML extensions to scanning profiles and the olium agent runtime.

Vigolium is designed for extensibility. Whether you need to add a new vulnerability check, reshape scan behavior, or integrate AI-driven analysis, there are multiple extension points, each with different trade-offs.

This guide covers every customization mechanism, explains when to use each one, and helps you pick the right approach for your use case.

***

## Table of Contents

* [Extension Points at a Glance](#extension-points-at-a-glance)
* [1. JavaScript Extensions](#1-javascript-extensions)
* [2. YAML Extensions](#2-yaml-extensions)
* [3. Custom Prompt Templates](#3-custom-prompt-templates)
* [4. Scanning Profiles](#4-scanning-profiles)
* [5. Scope Rules](#5-scope-rules)
* [6. Pre-Hooks and Post-Hooks](#6-pre-hooks-and-post-hooks)
* [7. Agent Providers (Olium)](#7-agent-providers-olium)
* [8. Configuration Overrides](#8-configuration-overrides)
* [Decision Matrix](#decision-matrix)

***

## Extension Points at a Glance

| Extension Point                                   | Language                | Recompile? | Best For                                                     |
| ------------------------------------------------- | ----------------------- | ---------- | ------------------------------------------------------------ |
| [JavaScript Extensions](#1-javascript-extensions) | JavaScript              | No         | Custom active/passive checks with full API access            |
| [YAML Extensions](#2-yaml-extensions)             | YAML                    | No         | Declarative pattern matching, simple payload/matcher rules   |
| [Prompt Templates](#3-custom-prompt-templates)    | Markdown + Go templates | No         | AI-driven code review, endpoint discovery, custom analysis   |
| [Scanning Profiles](#4-scanning-profiles)         | YAML                    | No         | Reusable scan presets (speed, modules, phases)               |
| [Scope Rules](#5-scope-rules)                     | YAML                    | No         | Target filtering (hosts, paths, status codes, content types) |
| [Pre/Post Hooks](#6-pre-hooks-and-post-hooks)     | JS or YAML              | No         | Request mutation, finding suppression, severity escalation   |
| [Agent Providers](#7-agent-providers-olium)       | Olium provider config   | No         | Picking the LLM provider/model for AI subcommands            |
| [Config Overrides](#8-configuration-overrides)    | YAML                    | No         | Tuning concurrency, rate limits, database, notifications     |

***

## 1. JavaScript Extensions

JavaScript extensions are the most flexible way to add custom scanning logic without recompiling Vigolium. They run inside an embedded JS engine (Grafana Sobek) and have access to the full `vigolium.*` API, HTTP requests, database queries, parsing utilities, AI integration, and more.

### What you can build

* **Active modules**: send payloads to insertion points (parameters, headers, cookies, paths) and analyze responses for vulnerabilities.
* **Passive modules**: analyze captured HTTP traffic without generating new requests.
* **Pre-hooks**: mutate requests before they reach scanner modules (inject auth headers, skip paths).
* **Post-hooks**: filter, tag, or escalate findings after detection.

### Minimal example (active module)

```javascript theme={null}
module.exports = {
  id: "reflected-param-scanner",
  name: "Reflected Parameter Scanner",
  type: "active",
  severity: "medium",
  confidence: "firm",
  scanTypes: ["per_insertion_point"],

  scanPerInsertionPoint: function(ctx, insertion) {
    var canary = "VGNM" + vigolium.utils.randomString(8);
    var resp = vigolium.http.send(insertion.buildRequest(canary));

    if (resp && resp.body.indexOf(canary) !== -1) {
      return [{
        matched: canary,
        url: ctx.request.url,
        name: "Reflected parameter: " + insertion.name,
        severity: "medium",
        request: insertion.buildRequest(canary),
        response: resp.raw
      }];
    }
    return null;
  }
};
```

### Available APIs

| Namespace         | Purpose                | Key Methods                                                    |
| ----------------- | ---------------------- | -------------------------------------------------------------- |
| `vigolium.http`   | Send HTTP requests     | `get`, `post`, `request`, `send`                               |
| `vigolium.scan`   | Scan control           | `listModules`, `isInScope`, `createFinding`, `startNewScan`    |
| `vigolium.db`     | Database access        | `records.query`, `findings.query`, `compareResponses`          |
| `vigolium.parse`  | HTTP parsing           | `url`, `request`, `response`, `headers`, `json`                |
| `vigolium.utils`  | Encoding, hashing, I/O | `base64Encode`, `sha256`, `readFile`, `exec`, `detectAnomaly`  |
| `vigolium.ingest` | Import traffic         | `url`, `curl`, `raw`, `openapi`, `postman`                     |
| `vigolium.source` | Source code access     | `list`, `readFile`, `listFiles`, `searchFiles`                 |
| `vigolium.agent`  | AI integration         | `ask`, `generatePayloads`, `analyzeResponse`, `confirmFinding` |
| `vigolium.config` | Extension variables    | Read-only access to `extensions.variables`                     |

Full TypeScript definitions: [`pkg/jsext/vigolium.d.ts`](../../pkg/jsext/vigolium.d.ts)

### Setup

```yaml theme={null}
# vigolium-configs.yaml
dynamic-assessment:
  extensions:
    enabled: true
    extension_dir: ~/.vigolium/extensions/
    variables:
      auth_token: "Bearer eyJ..."
```

Drop `.js` files into `~/.vigolium/extensions/` and verify with `vigolium extensions ls`.

### Pros

* **No recompilation**: drop a file and scan.
* **Full API access**: HTTP, database, AI, source code, parsing, and system utilities.
* **AI-augmented scanning**: use `vigolium.agent.generatePayloads()` and `vigolium.agent.analyzeResponse()` for LLM-powered detection.
* **Rapid iteration**: edit, save, rescan.
* **Sandboxed execution**: file I/O constrained to `sandbox_dir`, `exec()` gated behind config.

### Cons

* **Slower than Go**: interpreted JS engine adds overhead per invocation.
* **No Go standard library**: limited to `vigolium.*` APIs, no arbitrary imports.
* **Single-threaded per VM**: each extension instance runs in its own VM (thread-safe via pooling, but no parallelism within a single extension).
* **Limited debugging**: no step-through debugger, `vigolium.log.*` is your main tool.

### When to use

* You need a custom vulnerability check and don't want to recompile.
* You want AI-augmented payload generation or response analysis.
* You need database or source code access in your check logic.
* You're building organization-specific checks (e.g., custom header validation, business-logic flaws).

See the full guide: [Writing Extensions](/customization/writing-extensions)

***

## 2. YAML Extensions

YAML extensions (`.vgm.yaml`) are a declarative alternative to JavaScript. They're ideal for simple payload-and-matcher rules where you don't need programmatic control flow.

### Minimal example (active module)

```yaml theme={null}
id: error-pattern-detector
name: Error Pattern Detector
type: active
severity: low
confidence: firm
scan_types: [per_request]

payloads:
  - "'"
  - "\" OR 1=1--"

matchers:
  - type: body
    regex: "(?i)(SQL syntax|mysql_fetch|ORA-\\d{5}|SQLSTATE\\[)"
  - type: body
    regex: "(?i)(Traceback \\(most recent call last\\)|at \\w+\\.java:\\d+)"

matchers_condition: or

finding:
  name: "Error-Based Information Leak"
  description: "Application returns verbose error messages that reveal implementation details"
  severity: low
```

### YAML hook example (pre-hook)

```yaml theme={null}
id: auth-header-injector
name: Auth Header Injector
type: pre_hook

add_headers:
  Authorization: "Bearer ${AUTH_TOKEN}"
  X-Request-ID: "vgm-{{random}}"

skip_when:
  url_contains: ["/health", "/metrics"]
```

### YAML hook example (post-hook)

```yaml theme={null}
id: suppress-low-on-static
name: Suppress Low Findings on Static Assets
type: post_hook

drop_when:
  severity: [low, info]
  url_contains: ["/static/", "/assets/", ".css", ".js"]

escalate:
  when_url_contains: ["/admin", "/api/v1/auth"]
  bump_severity: true
  tag: sensitive_endpoint
```

### Supported features

| Feature              | Description                                                    |
| -------------------- | -------------------------------------------------------------- |
| `payloads`           | List of strings injected per insertion point or request        |
| `matchers`           | Body regex/contains, header checks, status codes, or inline JS |
| `matchers_condition` | `or` (any matcher) or `and` (all matchers)                     |
| `add_headers`        | Pre-hook: headers to inject                                    |
| `skip_when`          | Pre-hook: conditions to skip processing                        |
| `drop_when`          | Post-hook: conditions to discard findings                      |
| `escalate`           | Post-hook: bump severity, add tags                             |
| `script`             | Inline JS escape hatch for complex logic                       |

### Pros

* **Zero coding**: pure declarative YAML.
* **Fast to write**: a payload list + matcher regex is often all you need.
* **Easy to audit**: non-technical team members can review rules.
* **Same pipeline integration**: loaded alongside JS extensions, same lifecycle.

### Cons

* **Limited logic**: no conditionals, loops, or state beyond what matchers offer.
* **No API access**: no database queries, HTTP follow-ups, or AI calls (unless you use the `script` escape hatch, which is effectively JS).
* **No multi-step checks**: can't chain requests or compare responses across steps.
* **Coarser insertion control**: payload injection is straightforward but you can't dynamically generate payloads based on context.

### When to use

* Simple signature-based detection (error strings, header patterns, status codes).
* Quick pre-hook rules (add auth headers, skip static assets).
* Post-hook filtering (suppress low-severity findings on static paths).
* When non-developers need to contribute scanning rules.

See the full guide: [Writing Extensions](/customization/writing-extensions)

***

## 3. Custom Prompt Templates

Prompt templates drive Vigolium's agent mode. They're Markdown files with YAML frontmatter that define what an AI agent should analyze and how it should report results. Templates support Go template syntax and are automatically enriched with context from the database, module registry, and source code.

### Template format

````markdown theme={null}
---
id: my-custom-review
name: My Custom Review
description: What this template does
output_schema: findings    # or: http_records
variables:
  - SourceCode
  - Language
  - PreviousFindings
---

You are a security engineer. Analyze the following code for {{.Language}} vulnerabilities.

{{if .PreviousFindings}}
Previous findings to verify:
{{.PreviousFindings}}
{{end}}

Source code:
```
{{.SourceCode}}
```

Respond with JSON: {"findings": [...]}
````

### Available template variables

| Variable              | Source                             | Description                             |
| --------------------- | ---------------------------------- | --------------------------------------- |
| `SourceCode`          | Gathered from `--source`/`--files` | Concatenated source code                |
| `Language`            | Auto-detected                      | Primary language (Go, Python, JS, etc.) |
| `Framework`           | `--framework` flag                 | Framework hint                          |
| `FilePath`            | Gathered                           | Primary file path                       |
| `SourcePath`          | `--source` flag                    | Source code root path                   |
| `TargetURL`           | `--target` flag                    | Target URL                              |
| `Hostname`            | Derived from target                | Hostname for DB lookups                 |
| `Endpoints`           | `--endpoints` flag                 | Pre-discovered endpoints                |
| `PreviousFindings`    | Database (JSON)                    | Prior findings for context              |
| `DiscoveredEndpoints` | Database (JSON)                    | HTTP records from DB                    |
| `ModuleList`          | Module registry (JSON)             | Available scanner modules               |
| `ScanStats`           | Database (JSON)                    | Aggregate scan statistics               |
| `AvailableCommands`   | Hardcoded reference                | CLI commands the agent can invoke       |
| `Extra`               | `--extra` flag                     | Custom key-value pairs                  |

Only variables listed in the frontmatter `variables` array trigger database queries, keeping prompts fast.

### Output schemas

**`findings`**: for code review, vulnerability detection:

```json theme={null}
{
  "findings": [{
    "title": "SQL Injection in login handler",
    "severity": "critical",
    "confidence": "certain",
    "file": "auth/login.go",
    "line": 42,
    "snippet": "db.Query(\"SELECT * FROM users WHERE id=\" + userID)",
    "cwe": "CWE-89",
    "tags": ["sqli"]
  }]
}
```

**`http_records`**: for endpoint discovery, API input generation:

```json theme={null}
{
  "http_records": [{
    "method": "POST",
    "url": "https://api.example.com/users",
    "headers": {"Content-Type": "application/json"},
    "body": "{\"name\": \"test\"}",
    "notes": "Create user endpoint"
  }]
}
```

### Preset templates

Vigolium ships with 15 built-in templates:

| Template                | Schema        | Purpose                                      |
| ----------------------- | ------------- | -------------------------------------------- |
| `security-code-review`  | findings      | General OWASP-focused code review            |
| `injection-sinks`       | findings      | Identify injection sinks (SQLi, cmd, SSRF)   |
| `auth-bypass`           | findings      | Authentication/authorization bypass patterns |
| `secret-detection`      | findings      | Hardcoded secrets and credentials            |
| `endpoint-discovery`    | http\_records | Extract API routes from source code          |
| `api-input-gen`         | http\_records | Generate HTTP requests from endpoints        |
| `curl-command-gen`      | http\_records | Generate curl commands for all routes        |
| `interactive-scan`      | findings      | Autopilot: analyze + run scans               |
| `targeted-retest`       | findings      | Autopilot: verify previous findings          |
| `attack-surface-mapper` | http\_records | Discover and cross-reference APIs            |
| `nextjs-security-audit` | findings      | Next.js-specific security review             |
| `react-xss-audit`       | findings      | React XSS pattern analysis                   |
| `auth-session-review`   | findings      | Auth and session management                  |
| `cors-csrf-review`      | findings      | CORS/CSRF configuration review               |
| `build-config-audit`    | findings      | Build/deployment config security             |

### Setup

Place custom templates in `~/.vigolium/prompts/` or set `agent.templates_dir` in config. User templates override built-in ones by ID.

```bash theme={null}
# Use a custom template
vigolium agent query --prompt-template my-custom-review --source /path/to/source

# Dry-run to see the rendered prompt
vigolium agent query --prompt-template my-custom-review --source /path/to/source --dry-run
```

### Pros

* **No code**: Markdown files with template syntax.
* **Context-aware**: automatic enrichment with database findings, endpoints, scan stats.
* **Multiple AI backends**: works with any of the eight olium providers (Anthropic API/OAuth/CLI/Vertex, OpenAI API/Codex-OAuth, Google Vertex, OpenAI-compatible local models).
* **Iterative refinement**: autopilot and pipeline modes pass prior findings back for verification.
* **Two output modes**: emit findings for code review or HTTP records for endpoint discovery.

### Cons

* **AI dependency**: requires a configured agent backend and API access.
* **Non-deterministic**: LLM output varies between runs; false positives require tuning.
* **Latency**: agent invocations are slower than pattern matching (seconds to minutes per run).
* **Token costs**: large codebases consume significant tokens per analysis.

### When to use

* Code-level security review that needs semantic understanding (not just pattern matching).
* Generating HTTP test inputs from source code (route extraction, API fuzzing seeds).
* Framework-specific audits (Next.js, React, Django, Spring) where templates can embed domain knowledge.
* Iterative analysis where the agent refines findings across multiple passes.

***

## 4. Scanning Profiles

Profiles are YAML files that overlay on top of the main configuration. They bundle scanning strategy, pace, phase settings, and module selection into a reusable preset.

### Format

A profile is a subset of `vigolium-configs.yaml`. Only non-nil values override the base config.

```yaml theme={null}
# ~/.vigolium/profiles/aggressive.yaml
# description: Fast aggressive scan for CI/CD pipelines

scanning_strategy:
  default_strategy: deep

scanning_pace:
  concurrency: 100
  rate_limit: 200
  max_per_host: 20
  audit:
    concurrency: 100
    max_duration: 60m

discovery:
  mode: files_and_dirs
  recursion:
    enabled: true
    max_depth: 8

spidering:
  max_depth: 0
  headless: true
  strategy: aggressive

audit:
  enabled_modules:
    active_modules:
      - all
    passive_modules:
      - all
```

### Usage

```bash theme={null}
# Use a named profile
vigolium scan --target https://example.com --scanning-profile aggressive

# Use a profile file path
vigolium scan --target https://example.com --scanning-profile /path/to/profile.yaml
```

Profiles are resolved from `~/.vigolium/profiles/` or `public/presets/profiles/` by name.

### Pros

* **Reusable presets**: define once, use across targets and teams.
* **Composable**: overlay on top of base config; only override what you need.
* **No code**: pure YAML.
* **Team-friendly**: share profiles in version control for consistent scan policies.

### Cons

* **Config-only**: can't add new scanning logic, only tune existing settings.
* **No per-target logic**: same profile applies to all targets in a scan.
* **Limited validation**: typos in field names silently ignored.

### When to use

* You run different scan intensities for different contexts (CI/CD vs. full audit vs. quick check).
* You want to enforce consistent scan settings across a team.
* You need to toggle phases (e.g., skip discovery, only run passive modules).

***

## 5. Scope Rules

Scope rules control what gets scanned. They filter at the host, path, status code, content type, and body level. You can define them in the config, via CLI flags, or programmatically from JS extensions.

### Configuration

```yaml theme={null}
# vigolium-configs.yaml
scope:
  applied_on_ingest: false     # enforce at ingest time or scan time

  host:
    include: ["*.example.com", "api.example.com"]
    exclude: ["staging.example.com"]

  path:
    include: ["/api/*"]
    exclude: ["/api/health", "/api/metrics", "/static/*"]

  status_code:
    include: ["2xx", "3xx"]    # exact, wildcard (2xx), range (400-499)
    exclude: ["404"]

  request_content_type:
    include: ["application/json*", "application/x-www-form-urlencoded*"]

  response_content_type:
    include: ["text/html*", "application/json*"]
    exclude: ["image/*", "font/*"]

  ignore_static_file: true     # auto-skip .jpg, .png, .css, etc.
```

### Scope from extensions

```javascript theme={null}
// Check scope programmatically
if (vigolium.scan.isInScope("api.example.com", "/users")) {
  // proceed
}

// Read current scope
var scope = vigolium.scan.getScope();

// Modify scope at runtime
vigolium.scan.setScope({
  host: { include: ["*.example.com"], exclude: [] },
  path: { include: ["/api/*"], exclude: [] }
});
```

### Pros

* **Precision targeting**: scan only what matters, skip noise.
* **Multiple filter types**: host globs, path patterns, status codes, content types, body strings.
* **Runtime adjustable**: extensions can modify scope during a scan.
* **Safety net**: prevents accidental scanning of out-of-scope systems.

### Cons

* **Config-only complexity**: complex scope rules can be hard to debug.
* **No request-level conditions**: you can't scope by request header values or authentication state (use pre-hooks for that).

### When to use

* Restricting scans to specific subdomains or API paths.
* Excluding health checks, static assets, or third-party endpoints.
* Bug bounty programs with defined scope boundaries.
* Filtering by response characteristics (status codes, content types).

***

## 6. Pre-Hooks and Post-Hooks

Hooks wrap the scanning pipeline. Pre-hooks transform requests before modules process them. Post-hooks filter or modify findings after detection.

### Pre-hook use cases

| Use case            | Implementation                                        |
| ------------------- | ----------------------------------------------------- |
| Inject auth headers | YAML `add_headers` or JS returning `{headers: {...}}` |
| Skip static assets  | YAML `skip_when.url_contains` or JS returning `null`  |
| Add correlation IDs | JS generating unique IDs per request                  |
| Rewrite URLs        | JS modifying `ctx.request` before forwarding          |

### Post-hook use cases

| Use case                              | Implementation                               |
| ------------------------------------- | -------------------------------------------- |
| Suppress low-severity on static paths | YAML `drop_when`                             |
| Escalate findings on admin endpoints  | YAML `escalate.when_url_contains`            |
| Tag findings by business unit         | JS adding metadata based on URL patterns     |
| AI-powered false positive filtering   | JS calling `vigolium.agent.confirmFinding()` |

### JS pre-hook example

```javascript theme={null}
module.exports = {
  id: "inject-session",
  name: "Session Injector",
  type: "pre_hook",

  execute: function(request) {
    return {
      headers: {
        "Cookie": "session=" + vigolium.config.session_token,
        "X-Correlation-ID": vigolium.utils.randomString(16)
      }
    };
  }
};
```

### JS post-hook example (AI false positive filter)

```javascript theme={null}
module.exports = {
  id: "ai-fp-filter",
  name: "AI False Positive Filter",
  type: "post_hook",

  execute: function(result) {
    if (typeof vigolium.agent === "undefined") return result;

    var check = vigolium.agent.confirmFinding({
      name: result.info.name,
      request: result.request,
      response: result.response,
      matched: result.matched
    });

    if (!check.confirmed && check.confidence !== "low") {
      vigolium.log.info("Suppressed FP: " + result.info.name);
      return null; // drop the finding
    }
    return result;
  }
};
```

### Pros

* **Pipeline integration**: runs automatically on every request/finding.
* **Composable**: multiple hooks chain sequentially.
* **Both JS and YAML**: simple rules in YAML, complex logic in JS.
* **Non-invasive**: doesn't modify module code.

### Cons

* **Sequential overhead**: hooks run on the hot path; slow hooks slow everything.
* **Order-dependent**: hook execution order matters but isn't always obvious.
* **Pre-hooks can't see responses**: they only have access to the outbound request.

### When to use

* You need to inject authentication into every request (pre-hook).
* You want to suppress known false positives across all modules (post-hook).
* You need to tag or route findings based on URL patterns (post-hook).
* AI-powered confirmation of findings before reporting (post-hook).

See the full guide: [Writing Extensions](/customization/writing-extensions)

***

## 7. Agent Providers (Olium)

Every agent invocation in Vigolium is dispatched through the in-process **olium** runtime (`pkg/olium/`). There are no external SDK or ACP subprocess backends, instead you choose a *provider* (the LLM API olium dispatches to) and configure its credential.

### Built-in providers

Default provider is `openai-compatible` with model `gemma4:latest` (a local Ollama endpoint), so a freshly initialized config works against `http://localhost:11434/v1` out of the box. Pick a hosted provider when you want a frontier model:

| Provider                                         | Typical model                  | Credential source                                                                                                              |
| ------------------------------------------------ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `openai-codex-oauth`                             | `gpt-5.5`                      | `oauth_cred_path` (`~/.codex/auth.json`, produced by `codex login`)                                                            |
| `anthropic-api-key`                              | `claude-opus-4-7`              | `llm_api_key` or `$ANTHROPIC_API_KEY`                                                                                          |
| `anthropic-oauth`                                | `claude-opus-4-7`              | `oauth_token` from `claude setup-token` (or `$ANTHROPIC_API_KEY`)                                                              |
| `openai-api-key`                                 | `gpt-5.5`                      | `llm_api_key` or `$OPENAI_API_KEY`                                                                                             |
| `openai-responses`                               | `gpt-5.5`                      | `llm_api_key` or `$OPENAI_API_KEY` (public OpenAI Responses API, `/v1/responses`)                                              |
| `anthropic-cli` *(alias `anthropic-claude-cli`)* | `claude-opus-4-7`              | shells out to the local `claude` binary on `$PATH`                                                                             |
| `anthropic-claude-sdk-bridge`                    | Claude Code default            | logged-in Claude Code subscription via the `vigolium-audit bridge` sidecar (no key); `bridge_binary` / `--bridge-bin` override |
| `anthropic-compatible`                           | via `custom_provider.model_id` | `custom_provider.base_url` (Anthropic Messages `/v1/messages` gateway / proxy)                                                 |
| `anthropic-vertex`                               | `claude-opus-4-6`              | GCP service-account JSON (or `$GOOGLE_APPLICATION_CREDENTIALS`) + project/location                                             |
| `google-vertex`                                  | `gemini-2.5-pro`               | same GCP creds; routes `gemini-*` models                                                                                       |
| `openai-compatible` *(default)*                  | `gemma4:latest`                | `custom_provider.base_url` (Ollama / OpenRouter / LM Studio / vLLM / Groq / …); `api_key` optional                             |

### Configuring a provider

```yaml theme={null}
# vigolium-configs.yaml
agent:
  olium:
    provider: anthropic-api-key
    model: claude-opus-4-7
    llm_api_key: ${ANTHROPIC_API_KEY}
    reasoning_effort: medium       # codex providers only
    max_tokens: 1000000
    max_turns: 32
    max_concurrent: 4              # global cap on simultaneous provider calls
    call_timeout_sec: 600
```

Override per-run from any agent subcommand:

```bash theme={null}
vigolium agent query --prompt-template security-code-review --source ./app \
  --provider anthropic-api-key --model claude-opus-4-7

vigolium agent autopilot -t https://example.com \
  --provider anthropic-oauth --oauth-token "$ANTHROPIC_API_KEY"

vigolium ol --provider openai-api-key --llm-api-key "$OPENAI_API_KEY"
```

> **Server-side workloads:** the REST API does **not** mirror these per-invocation flags. The server resolves the provider once from `agent.olium.*` and reuses it across requests so prompt caches stay stable.

### Tool registry

The olium engine exposes eight built-in tools to the model: `bash`, `read_file`, `write_file`, `edit_file`, `ls`, `grep`, `glob`, `web_fetch`. Autopilot adds two security-specific tools: `halt_scan` (model-driven exit) and `report_finding` (DB-backed finding ingestion). See [Olium Agent](/agentic-scan/olium) for the full tool reference.

### LLM config (for JS extensions)

The `vigolium.agent.*` APIs available to JavaScript extensions dispatch through the same in-process **olium** engine that powers the `vigolium agent` subcommands. Configure the provider once under `agent.olium` — see [Olium Agent](/agentic-scan/olium) for the full provider/model options.

> **Note:** The legacy `agent.llm` config block is **deprecated and ignored**. The JS extension agent API now resolves its provider from `agent.olium`; remove any `agent.llm` section from your config.

### Pros

* **Eleven providers**: pick the credential model that fits (OAuth for ChatGPT Plus / Claude Max, API keys for raw API access — Chat Completions or the OpenAI Responses API — CLI shellout or the Claude Code Agent-SDK bridge for a logged-in Claude subscription, Vertex for GCP, OpenAI- or Anthropic-compatible for local/self-hosted models).
* **Single in-process runtime**: no subprocess startup overhead, prompt caching is reused across phases that share an engine (Anthropic + Codex providers only).
* **Per-invocation overrides**: every CLI subcommand exposes `--provider`, `--model`, `--oauth-cred`, `--oauth-token`, `--llm-api-key`.
* **Global concurrency cap**: `max_concurrent` keeps tier-1 plans from hitting 429s under fan-out.

### Cons

* **Provider lock-in to supported drivers**: only the eleven drivers above are recognised; arbitrary custom CLIs are not pluggable as backends anymore.
* **Cost**: LLM API calls still have token costs; the `--intensity` preset (autopilot) caps the iteration budget — `quick` is the lightest, `deep` the heaviest.

### When to use

* Always, every agent subcommand goes through olium. The choice you actually make is **which provider and model**, not whether to use olium.

***

## 8. Configuration Overrides

The main `vigolium-configs.yaml` is the central control plane for all scan behavior. Every aspect of the scanner, phases, pace, modules, database, notifications, and more, is configurable.

### Key configuration sections

| Section              | What it controls                                                                   |
| -------------------- | ---------------------------------------------------------------------------------- |
| `scanning_strategy`  | Phase presets: `lite`, `balanced`, `deep`                                          |
| `scanning_pace`      | Concurrency, rate limits, per-phase duration caps                                  |
| `dynamic-assessment` | Active/passive module selection, extension config                                  |
| `discovery`          | Content discovery mode, recursion, wordlists                                       |
| `spidering`          | Browser crawling depth, strategy, headless mode                                    |
| `scope`              | Host/path/status/content-type filtering                                            |
| `database`           | SQLite or PostgreSQL, connection settings                                          |
| `notify`             | Alert routing: Telegram, Discord, severity filters                                 |
| `mutation_strategy`  | Payload mutation modes, field-type defaults                                        |
| `oast`               | Out-of-band testing server, blind XSS config                                       |
| `agent`              | Olium provider, LLM config (JS extensions), audit harness, browser, context limits |
| `storage`            | S3-compatible cloud storage for source uploads and result archival                 |

### Environment variable expansion

```yaml theme={null}
database:
  postgres:
    password: ${VIGOLIUM_DB_PASSWORD}

agent:
  llm:
    api_key_env: ANTHROPIC_API_KEY
```

### Pros

* **Comprehensive**: controls every scanner behavior.
* **Environment-aware**: variable expansion for secrets.
* **Layered**: base config + profiles + CLI flags, in order of precedence.

### Cons

* **No logic**: pure configuration, can't express conditional behavior.
* **Silent failures**: unrecognized keys are ignored, not flagged.
* **Single file**: large configs can become unwieldy.

### When to use

* Tuning scan speed and resource usage for your infrastructure.
* Selecting which modules run by default.
* Configuring database, notifications, and OAST.
* Setting organization-wide defaults.

***

## Decision Matrix

Use this table to quickly pick the right extension mechanism:

| I want to...                                       | Use                                                                                                                                                |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Add a custom vulnerability check (simple patterns) | [YAML Extension](#2-yaml-extensions)                                                                                                               |
| Add a custom vulnerability check (complex logic)   | [JS Extension](#1-javascript-extensions)                                                                                                           |
| Run AI code review with custom focus areas         | [Prompt Template](#3-custom-prompt-templates)                                                                                                      |
| Create a reusable scan preset for my team          | [Scanning Profile](#4-scanning-profiles)                                                                                                           |
| Restrict scanning to specific hosts/paths          | [Scope Rules](#5-scope-rules)                                                                                                                      |
| Inject auth headers into every request             | [Pre-Hook](#6-pre-hooks-and-post-hooks)                                                                                                            |
| Suppress false positives across all modules        | [Post-Hook](#6-pre-hooks-and-post-hooks)                                                                                                           |
| Use AI to confirm findings before reporting        | [Post-Hook + agent API](#6-pre-hooks-and-post-hooks)                                                                                               |
| Pick a different LLM provider/model                | [Agent Providers (Olium)](#7-agent-providers-olium)                                                                                                |
| Tune concurrency and rate limits                   | [Config Override](#8-configuration-overrides) or [Profile](#4-scanning-profiles)                                                                   |
| Generate HTTP test inputs from source code         | [Prompt Template](#3-custom-prompt-templates) (with `http_records` schema)                                                                         |
| Build an organization-specific scanner pipeline    | Combine: [Profile](#4-scanning-profiles) + [Scope](#5-scope-rules) + [Hooks](#6-pre-hooks-and-post-hooks) + [Extensions](#1-javascript-extensions) |
