Your first scan
This page walks you through:
- Pointing
vulkro scanat a project. - Reading the output.
- Filtering it down to actionable signal.
Before your first scan, connect the CLI to your account with
vulkro login; your 14-day trial starts on that first login (see
Install -> Connect your account).
The scan itself runs entirely on your machine.
Run it
cd path/to/your/project
vulkro scan .
What happens:
- Vulkro walks the working tree honouring
.gitignore(same library ripgrep /fduse). - It detects your project's language and framework. Python, JavaScript, TypeScript, and Go are covered on every tier (Express, Fastify, Next.js, FastAPI, Django, gin, and more). Java with first-class Spring Boot support, plus Ruby, Kotlin, C#, and PHP, are included in your 14-day trial and in Pro. See Languages and coverage.
- It statically extracts every HTTP route, builds a module call graph, and runs the security pipeline (OWASP, secrets, CVEs, taint, reachability, privacy).
- It prints a colourised summary table to stdout.
Wall-clock for a mid-sized monorepo is typically 30-90s. Larger repos (Cal.com, ~2,200 modules) take ~45s on an M1.
Your first successful scan on a machine also prints a short one-time
next-steps note to stderr (triage commands, changed-file rescan,
opening the dashboard). It is suppressed when stderr is not a terminal,
when --format is any machine-readable format, or when the CI
environment variable is set, and a marker file under ~/.vulkro
guarantees it never prints twice.
Read the output
A typical run looks like this:
Detected: TypeScript | Next.js (App Router)
224 endpoints | 2,230 modules
Taint pass | Reachability | CVE match | Secrets | IaC
CRITICAL 33 HIGH 355 MED 1369 LOW 1063
API1 BrokenObjectLevelAuth 115 findings
API8 SecurityMisconfiguration 2292 findings
SECRETS 436 hardcoded | 19 in git history
DEPS 23 CVEs (4 KEV-listed, 7 reachable)
Completed in 42s | exit 1 (Critical/High present)
Each section is separately addressable:
- Severity counts are the headline. Critical and High block the build by default.
- OWASP categories show where your code spends its risk budget.
- SECRETS combines source-tree and git-history findings; the desktop
console (
vulkro serve) splits them. - DEPS tags the most dangerous CVEs. KEV-listed (CISA "actively exploited") and reachable (the vulnerable symbol is actually called from your code) are escalated.
Get the details
Default output is a summary. To see file paths and line numbers:
vulkro scan . --verbose
For machine-readable output:
vulkro scan . --format json | jq .findings[0]
vulkro scan . --format sarif > vulkro.sarif
vulkro scan . --format junit > vulkro-junit.xml
See the full output formats reference for the rest:
CycloneDX 1.6, SPDX 2.3, GDPR Art. 30 RoPA (markdown + HTML), executive HTML,
PDF (via wkhtmltopdf), GitHub-PR-comment, CSV.
Filter the noise
The default scan uses --min-confidence medium - Medium and High findings
only. Three knobs adjust the threshold:
# Default: medium + high. The typical day-to-day mode.
vulkro scan .
# Audit mode - surfaces every heuristic / pattern-only finding,
# including Low confidence ones on test/example code.
vulkro scan . --all-confidence
# CI-gate mode - High confidence only. Highest precision on the
# public vuln corpus. Production-recommended for blocking gates.
vulkro scan . --min-confidence high
# Hide non-source files (Dockerfile, lockfiles, *.tf, *.md, templates,
# docker-compose). Keeps `.env*` and k8s manifests.
vulkro scan . --scope src
Confidence model -> explains the calibration table that decides which detector categories get downgraded.
Suppress a specific finding
Add a comment in the source instead of editing a config file:
# vulkro:disable next-line API2
@router.get("/health")
def health(): ...
// vulkro:disable next-line API2
app.get("/internal/ping", noAuth);
/* vulkro:disable next-line API1 */
db.query(`SELECT * FROM ${table}`);
// vulkro:disable-file at the top of a file silences all findings for it.
Suppression counts are reported in every scan summary so you can audit them.
See the suppressions guide for the full syntax
and repo-wide vulkro.toml suppressions.
Save the run
vulkro scan . --save
Adds the run to local scan history at ~/.vulkro/scans.db so you can:
- Compare against a previous baseline (
vulkro diff <ref>). - Track risk-debt and MTTR trends over time in the desktop console.
- Mark a scan as
baselineto gate PRs against it.
What's next
- Drop vulkro into CI -> - exit-code semantics, SARIF upload, PR comments.
- Open the desktop console -> -
vulkro servefor triage. - Reading findings -> - what each detector means.