vulkro scan
The full security pipeline: endpoint extraction + OWASP API Top 10:2023 +
secrets + dependencies (CVE) + taint + reachability + privacy + IaC + git
history. Exit 1 on any Critical/High finding (after --min-confidence).
Usage
vulkro scan [PATH] [FLAGS]
Arguments
| Argument | Description | Default |
|---|---|---|
PATH | Project root. | . |
Flags
| Flag | Description |
|---|---|
--format, -f <FMT> | table, json, sarif, gh-pr, junit, csv, cyclonedx, spdx, pdf, ropa-md, ropa-html. Default: table. |
--verbose, -v | Show file paths and line numbers per finding. |
--save | Persist the run to ~/.vulkro/scans.db and snapshot trends. |
--baseline <FILE> | Compare findings against a saved baseline JSON; only emit new findings. See also: Baselines explained. |
--rules <PATH> | Extra rule pack file or directory of *.toml files. |
--profile <NAME> | Attach a compliance evaluation: owasp-asvs, pci, soc2. |
--min-confidence <LEVEL> | medium (default), high, low. Filters before exit-code computation. |
--all-confidence (alias --all) | Equivalent to --min-confidence low. Surfaces every heuristic finding. |
--gate | Apply the [quality_gate] section of vulkro.toml. Replaces the default Critical/High exit policy. |
--validate-secrets | OFF by default. When set, each detected secret is probed against its provider API and tagged [live], [dormant], or [unknown]. |
--gate-vs <REF> | Restrict findings to lines that changed vs the given git ref. The exit code reflects only diff-scoped findings - the "block PRs that introduce new issues" lane. |
--scope <KIND> | all (default) shows every finding. src drops Dockerfile / lockfile / IaC / template / docs findings while keeping .env* and k8s manifests. |
Presets
vulkro scan exposes three named profiles that bundle a set of flag
defaults appropriate for a specific lane. Two equivalent surface
forms:
vulkro scan quick . # positional preset
vulkro scan --preset quick . # named flag
| Preset | Lane | Bundles |
|---|---|---|
quick | Pre-commit hook | --min-confidence high, --scope src, --since HEAD~1. Fast diff-scoped scan over source files. |
ci | CI gate | Current default behaviour plus --gate and a default --fail-on critical,high exit policy. |
deep | Pre-release review | --all-confidence, --include-unreachable, --min-evidence 0.0. Maximum recall. |
Bare vulkro scan [path] defaults to the ci preset and emits a
one-time stderr hint suggesting an explicit form so the chosen lane
is visible in CI logs. Suppress the hint with
VULKRO_QUIET_PRESET_HINT=1.
Precedence: a user-passed flag always wins over the preset's value.
vulkro scan quick . --min-confidence low actually scans at low,
even though quick would otherwise raise the floor to high. For
boolean flags (--gate, --all, --include-unreachable) the
preset can only turn them on; there is no --no-gate style negation.
vulkro scan quick . # pre-commit hook lane
vulkro scan ci . # what CI should do
vulkro scan deep . # release-review thoroughness
vulkro scan . # defaults to `ci`, prints one-time hint
VULKRO_QUIET_PRESET_HINT=1 vulkro scan . # quieter CI logs
An unknown preset name (vulkro scan --preset XYZ) exits 2 with an
actionable error listing the valid presets.
Strict confidence
--strict-confidence (or VULKRO_STRICT_CONFIDENCE=1) filters
High-confidence findings whose evidence bag is empty. Off by
default - behaviour-preserving for callers who don't opt in. Intended
for CI gates that want maximal precision: every surviving High
finding has cumulative-evidence proof per the
confidence rubric (a taint-flow
source-to-sink, an exact-match invariant, a schema-vs-code
contradiction, or corroborating signals whose weights sum past the
threshold).
vulkro scan ci . --strict-confidence # CLI flag
VULKRO_STRICT_CONFIDENCE=1 vulkro scan ci . # env var
The CLI flag wins if both are set. Use this when a CI pipeline should only fail on findings with explicit evidence and tolerate some loss of recall in exchange.
Post-quantum crypto audit
--pq-audit runs an opt-in audit pack that flags classical RSA,
ECDSA, ECDH, and classical Diffie-Hellman usage that NIST PQC
migration guidance targets for replacement:
- FIPS 203 (ML-KEM, the Kyber-derived key-encapsulation standard)
- FIPS 204 (ML-DSA, the Dilithium-derived digital-signature standard)
- FIPS 205 (SLH-DSA, the SPHINCS+-derived stateless hash-based signature standard)
Symmetric primitives (AES, ChaCha20, SHA-2 / SHA-3) are deliberately NOT flagged: Grover's algorithm only halves effective key length, so AES-256 stays 128-bit-strong against a cryptographically-relevant quantum computer (CRQC). Doubling key length where you already use a symmetric primitive is the correct mitigation, not replacing the algorithm.
vulkro scan ci . --pq-audit
Off by default. PQ findings are a planning surface, not an exploit-today defect; opting in keeps the default scorecard focused on actionable risk.
Confidence model
The default is --min-confidence medium - Medium and High findings emit;
Low-confidence heuristic findings (test/example/migration code matches,
pattern-only fires without corroboration) are hidden unless explicitly
requested. Vulkro is tuned for high recall at the engine level and
graduated precision at the display level.
vulkro scan . # medium + high (default - typical day-to-day)
vulkro scan . --min-confidence high # high only - production-recommended for CI gates
vulkro scan . --all-confidence # everything, including Low (audit / debug mode)
At --min-confidence high on the public 13-repo vulnerability corpus:
precision 0.76, recall 0.57, F1 0.65 - beats Semgrep CE (F1 0.32)
and Bearer (F1 0.45) outright. See Confidence model
for the calibration table and the cumulative-evidence aggregator that
governs how detector findings clear each tier.
Inline suppression
Add a comment in the source instead of a config file:
# vulkro-disable-next-line BrokenAuthentication
@router.get("/health")
def health(): ...
// vulkro-disable-next-line BrokenAuthentication
app.get("/internal/ping", noAuth);
/* vulkro-disable-next-line API1 */
db.query(`SELECT * FROM ${table}`);
vulkro-disable-file at the top silences every finding in that file.
Suppression counts are reported in the scan summary so you can audit them.
Diff-scoped scans
Block PRs only on new findings vs a base ref:
vulkro scan . --gate-vs main
Findings outside the changed-line set are still reported in JSON for
completeness but the exit code reflects only diff-scoped findings. Combine
with --baseline for richer comparisons.
Persisting runs
vulkro scan . --save
vulkro history
vulkro diff main
vulkro trends
State lives at ~/.vulkro/scans.db (SQLite). vulkro diff matches
findings by stable finding_key so re-orderings, whitespace changes, and
refactors don't trip the diff.
Examples
# Default - colourised summary, exit 1 on Critical/High.
vulkro scan .
# CI: SARIF for code-scanning + a separate gating call.
vulkro scan . --format sarif > vulkro.sarif
vulkro scan . --min-confidence high # gate
# PR-scoped review.
vulkro scan . --gate-vs origin/main --format gh-pr > comment.md
# Gather everything for an audit, scoped to source code only.
vulkro scan . --all-confidence --scope src --format json > audit.json
Related
vulkro discover- extraction without security checks.vulkro probe- runtime confirmation of static findings.vulkro diff- finding-level deltas.vulkro compliance- control mapping.- Output formats -> - every format documented.
- See also: Baselines explained - when to use
--baseline/--ratchetvs the UI's baseline-scan flag.