Scanner CLI Reference

Kolega Scan OSS

Kolega's open-source security scanner. Point kolega-scan at a directory and get Semgrep-compatible JSON findings. It ships in two versions — V1 (the default) and V2 — matching the entries you see on the RealVuln benchmark. Set one API key and scan; drop the JSON into any pipeline.

Overview

Kolega Scan OSS takes a repository path and returns a stable, repo-keyed list of findings in Semgrep-compatible JSON. It is storage- and orchestration-agnostic: it reads a directory and writes JSON, so you can drop it into any pipeline.

Under the hood it runs a semantic detection pipeline — threat-model → discover → verify → triage — across one or more LLMs. V1 uses two models and is the default; V2 adds a third for higher recall at higher cost. You pick with --scanner, or just run it and get V1.

stdout is reserved for findings JSON; all progress, warnings, and errors go to stderr — so piping into jq always works.

Install

Kolega Scan requires Python 3.10 or newer. It installs a kolega-scan command. A PyPI package is coming; for now install from source.

# Requires Python 3.10+
pip install "git+https://github.com/kolega-ai/kolega-scan"

# Or, for local development
git clone https://github.com/kolega-ai/kolega-scan
pip install -e ./kolega-scan

# Verify
kolega-scan --version

Quick Start

Set one API key and point Kolega Scan OSS at a repository. That's the whole flow — findings land on stdout or in the file you name with --out.

# 1. Set the key (V1, the default, needs only DeepSeek)
export DEEPSEEK_API_KEY=sk-...

# 2. Scan — findings to a file
kolega-scan scan ./my-project --out findings.json

# 3. Watch progress while it runs
kolega-scan scan ./my-project -v

Commands

scan is the command you'll use day to day: point it at a repository and collect the findings. (The CLI also ships benchmark ground-truth tooling for scanner development — see the repo's developer docs.)

scan

Scan a repository and emit Semgrep-compatible Finding JSON. Findings print to stdout by default, or to a file with --out; progress and diagnostics go to stderr.

kolega-scan scan <repo-path> [options]
Arguments
ArgumentDescription
repo-pathPath to the repository to scan. Must be an existing directory.
Options
FlagDescription
--out <path>Write Finding JSON here instead of stdout.
--config <path>YAML config file with defaults; explicit CLI flags take precedence.
--scanner <name>Pick a version: kolega-scan-oss-v1 (default) or kolega-scan-oss-v2. See Versions below.
-v, --verboseVerbose (DEBUG) progress on stderr.
-q, --quietOnly warnings and errors on stderr.
  • V1 runs by default and reads `DEEPSEEK_API_KEY` from the environment; a missing key exits 2 with a clear message.
  • The scan command keeps stdout to findings JSON only, so `kolega-scan scan ... | jq` always works.

Versions

Kolega Scan OSS ships in two versions — the same V1 and V2 you see on the RealVuln benchmark. If you don't pass --scanner, you get V1.

Version--scanner valueCredentialsDescription
V1 (default)kolega-scan-oss-v1DEEPSEEK_API_KEYTwo models (DeepSeek flash + pro). The best price-to-performance version — runs when no --scanner is given.
V2kolega-scan-oss-v2DEEPSEEK_API_KEY, MOONSHOT_API_KEYThree models (adds Moonshot Kimi). Higher recall at higher cost; a finding survives if any model confirms it.

Extending Kolega Scan

External scanners register at runtime through the kolega_security_scanner.scanners entry-point group — install a distribution that declares one and it appears as a --scanner value. No fork required. The repo's developer docs include worked examples for writing your own scanners and detectors.

V1 (default)

# V1 is the default — no flag needed.
export DEEPSEEK_API_KEY=sk-...
kolega-scan scan ./my-project --out findings.json

# Equivalent, spelled out:
kolega-scan scan ./my-project --scanner kolega-scan-oss-v1 --out findings.json

V2

# V2: three models; a finding survives if ANY model confirms it.
export DEEPSEEK_API_KEY=sk-...
export MOONSHOT_API_KEY=sk-...
kolega-scan scan ./my-project \
  --scanner kolega-scan-oss-v2 \
  --out findings.json -v

Configuration

The LLM scanners need a client. By default (direct backend) each model spec — written provider/model — is routed to that provider's own endpoint using the matching key. Set KOLEGA_LLM_BACKEND=litellm to route everything through a single OpenAI-compatible proxy instead.

Environment variablePurpose
KOLEGA_LLM_BACKENDdirect (default) routes each provider to its own endpoint; litellm routes everything through one proxy.
DEEPSEEK_API_KEYKey for deepseek/* models (the default model).
MOONSHOT_API_KEYKey for moonshot/* (Kimi) models.
OPENAI_API_KEYKey for openai/* models.
ANTHROPIC_API_KEYKey for anthropic/* models (native Messages API).
LITELLM_API_KEYKey for the LiteLLM proxy (litellm backend only).
LITELLM_URLLiteLLM proxy endpoint (litellm backend only).
  • Keys can also come from a .env file in the working directory. Because a scanned repo may be untrusted, only a fixed allowlist of credential keys is ever read from it — a repo's .env cannot inject arbitrary environment variables.
  • V1 uses DeepSeek models only, so a single DEEPSEEK_API_KEY is enough to get started.

LiteLLM proxy backend

# Route every model through one OpenAI-compatible proxy instead of
# each provider's own endpoint.
export KOLEGA_LLM_BACKEND=litellm
export LITELLM_API_KEY=...
export LITELLM_URL=http://proxy.internal:4000/v1
kolega-scan scan ./my-project

YAML config file

Pass --config to set defaults for any scan flag. Explicit CLI flags always win over the file.

config.yaml
# config.yaml — explicit CLI flags always take precedence over these.
out: findings.json
kolega-scan scan ./my-project --config config.yaml

Output & Exit Codes

Findings are emitted as a JSON object keyed by repository directory name, each value a list of Semgrep-compatible findings. The extra.metadata.kolega block carries the finding's vulnerability class and the scanner's confidence, alongside the standard CWE references.

findings.json
{
  "my-project": [
    {
      "path": "src/db.py",
      "check_id": "kolega.claude-adaptation.sql-injection",
      "start": { "line": 42, "col": null },
      "end": null,
      "extra": {
        "message": "SQL injection in the login query — attacker-controlled input is concatenated into the SQL string. [verified: input reaches the query unsanitized]",
        "severity": "high",
        "metadata": {
          "cwe": ["CWE-89"],
          "kolega": {
            "cluster_id": "sql_injection",
            "detector_slug": null,
            "confidence": "high",
            "root_key": null
          }
        }
      }
    }
  ]
}

Exit codes

CodeMeaning
0Success — the command completed.
1Domain failure (reserved; not used by the scan command).
2Usage error — bad arguments, unknown scanner, or a missing key.
10Internal error — an unhandled exception.

Automation & CI

Because findings are clean JSON on stdout and diagnostics stay on stderr, Kolega Scan drops straight into a pipeline. Use -q to keep logs to warnings only, --out to write a report artifact, and the exit code to gate the build.

# GitHub Actions — fail the job on any finding.
- name: Kolega security scan
  env:
    DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
  run: |
    pip install "git+https://github.com/kolega-ai/kolega-scan"
    kolega-scan scan . --out findings.json -q
    test "$(jq '[.[][]] | length' findings.json)" -eq 0
  • Store the provider key as a CI secret and expose it only to the scan step.
  • Run V2 on scheduled or main-branch runs; keep PR runs on V1.
  • Parse the repo-keyed JSON with jq to count or filter findings by severity before failing the job.