Skip to main content

vulkro diff

Compare the current API surface and findings against a saved scan or a git ref. Produces a per-finding delta - added, fixed, unchanged.

Pro

vulkro diff is part of Pro: API-surface diff (api-diff), what the API contract gained and lost between two refs. On Free it stops before doing any work, prints what it needs and where to get it, and exits 1. See Pricing.

Usage

vulkro diff [OPTIONS] [BASE] [PATH]

Arguments

ArgumentDescriptionDefault
BASEBase git ref to compare against (e.g. main, HEAD~1, v1.0.0).main
PATHPath to the project root..

Flags

FlagDescription
-f, --format <FORMAT>Output format (see Output formats). Default table.
--offlineHard-disable every outbound network call for this run (sets VULKRO_OFFLINE=1). A loopback model (http://127.0.0.1, http://localhost) is still allowed.
--ai[advisory] Attach a plain-language AI security-delta narrative to the surface diff: new unauthenticated routes, removed auth checks, and new or regressed findings, explained for a reviewer. The resolved local model narrates only the deterministic signals; it never changes the diff, the findings, or the exit code.
--ai-model <MODEL>AI model tag override for --ai (highest precedence). Overrides VULKRO_AI_MODEL, the saved vulkro ai use selection, and the smart default. Example: --ai-model qwen2.5-coder:7b.
--ai-url <URL>AI runtime base url override for --ai (OpenAI-compatible). Example: --ai-url http://127.0.0.1:11434/v1. A loopback url is allowed under VULKRO_OFFLINE; a cloud url is refused offline.

The --ai narrative

--ai is additive. The narrative appears as an ai_narrative field in JSON and a labelled block in text, marked advisory, non-deterministic and excluded from the benchmark. It is omitted entirely without the flag. A loopback model is allowed under VULKRO_OFFLINE; a cloud url is refused offline. If AI is off or unreachable, vulkro diff prints a note and leaves the diff unchanged.

How matching works

Findings are matched by a stable finding_key rather than file/line, so reordering a function or adding a new line above a finding doesn't generate spurious "added" / "removed" pairs.

Use case: review API-surface changes vs main

# Print endpoints and findings that changed vs origin/main
vulkro diff origin/main

vulkro diff reports the surface delta; it does not fail the build on its own. To gate a PR on findings that are new vs a base ref, use vulkro gate --base, the canonical fail-on-new-only gate. Together they are the typical "block PRs on regressions, ignore long-tail tech debt" CI pattern.

Output formats

Pass one with -f / --format. The full enum:

  • table (default) - human-readable terminal output.
  • json - structured diff document.
  • sarif - SARIF for code-scanning tools.
  • gh-pr - Markdown for gh pr comment, grouped by added / fixed and suppressing unchanged.
  • gh-pr-inline-comments - NDJSON, one per-finding GitHub PR inline review comment per line, to pipe into a gh api loop.
  • github-annotations - one GitHub Actions / GitLab CI workflow-command line per finding, turned into an inline annotation pinned to file:line.
  • gitlab-mr - GitLab merge-request comment (GitLab-flavored Markdown with collapsible blocks).
  • bitbucket-pr - Bitbucket pull-request comment (flat Markdown).
  • azure-pr - Azure DevOps pull-request comment (flat Markdown).
  • junit - JUnit XML.
  • csv - comma-separated rows.
  • cyclonedx - CycloneDX 1.6 JSON SBOM.
  • cyclonedx-1.7 - CycloneDX 1.7 JSON SBOM.
  • spdx - SPDX 2.3 JSON SBOM.
  • spdx3 - SPDX 3.0.1 JSON-LD SBOM.
  • cbom - CycloneDX 1.6 CBOM (Cryptographic Bill of Materials).
  • cbom-1.7 - CycloneDX 1.7 CBOM with a richer post-quantum descriptor.
  • openvex - OpenVEX 0.2.0 exploitability statements for each dependency CVE.
  • cyclonedx-vex - CycloneDX 1.6 VEX, the same verdicts as openvex.
  • pdf - PDF render of the executive HTML report (requires wkhtmltopdf on PATH).
  • ropa-md / ropa-html - GDPR Article 30 Records-of-Processing template.
  • ndjson - newline-delimited JSON, one finding per line plus a trailing summary line.
  • evidence-graph - evidence-graph JSON (evidence-graph/1.0), an AI-consumable graph of endpoints, taint flows, reachability verdicts, findings and the SBOM.

Exit codes

vulkro diff prints the surface delta and never fails on it, so it never returns 1.

  • 0 - diff rendered.
  • 2 - a bad ref, or a scan / IO error.

To gate CI on findings that are new versus a base ref, use vulkro gate --base (or vulkro ci --base <ref>), which owns the findings-gated exit 1.

vulkro history

Lists saved scans:

vulkro history

Add --save to a scan run to populate it.

Shows risk-score, finding-count, MTTR, and risk-debt deltas across the saved history:

vulkro trends . --limit 30

Command reference

Generated from vulkro help diff on vulkro 0.26.0. This block is the authoritative flag, usage, and exit-code reference for this command; the prose above is the friendly explanation. Do not edit this block by hand; run npm run docs:cli after a release.

[Pro] Show which endpoints changed since a git branch, tag or commit.

[Pro] Compare current API surface against a git ref (branch, tag, or SHA).

Exit code: 0 diff rendered, 2 on a bad ref or a scan / IO error. It prints the surface delta and does not fail on it, so it never returns 1 (use `vulkro ci --base <ref>` for a findings-gated CI exit).

Usage: vulkro diff [OPTIONS] [BASE] [PATH]

Arguments:
[BASE]
Base git ref to compare against (e.g. main, HEAD~1, v1.0.0)

[default: main]

[PATH]
Path to the project root (default: current directory)

[default: .]

Options:
-f, --format <FORMAT>
Output format

Possible values:
- table
- json
- sarif
- gh-pr
- gh-pr-inline-comments: GitHub PR per-finding **inline review comments**. NDJSON, one `{path, line, side, severity, rule_id, fingerprint, body}` object per line. Designed to be piped straight to a `gh api` loop so `vulkro gate` can drop comments next to the offending line on the Files Changed tab without going through a GitHub App. See the GitHub CLI integration guide at vulkro.com/docs
- github-annotations: GitHub Actions / GitLab CI **PR annotations**. One workflow-command line per finding (`::error file=...,line=...,endLine=...,title=<rule id>::<message> (<helpUri>)`). Printed straight to a CI job's stdout, GitHub turns each line into an inline annotation pinned to `file:line` on the Files Changed tab; GitLab CI's annotation parser reads the same grammar. When run against a baseline (`--gate-vs` / a `gate` flow) only NEW findings are annotated so a first run does not paper the PR
- gitlab-mr: GitLab Merge-Request comment: GitLab-flavored Markdown with collapsible blocks
- bitbucket-pr: Bitbucket Pull-Request comment: flat Markdown (Bitbucket does not render `<details>`)
- azure-pr: Azure DevOps Pull-Request comment: flat Markdown (shared with Bitbucket)
- junit
- csv
- cyclonedx: CycloneDX 1.6 JSON SBOM (uses `ScanResult.packages`)
- cyclonedx-1.7: CycloneDX 1.7 JSON SBOM. Same component shape as `cyclonedx`; emits the newer `specVersion`. Offered alongside 1.6 (which stays default)
- spdx: SPDX 2.3 JSON SBOM
- spdx3: SPDX 3.0.1 JSON-LD SBOM (`@context` + `@graph` of typed elements). Offered alongside SPDX 2.3, which stays the default for `--format spdx`
- cbom: CycloneDX 1.6 CBOM (Cryptographic Bill of Materials): one `cryptographic-asset` component per detected weak algorithm (MD5, SHA-1, ECB, RC4, DES, static IV, insecure RNG), with file:line occurrences inlined under `evidence.occurrences`. Compliance buyers (FedRAMP, post-quantum readiness reviews) ask for this as a distinct artefact from the library SBOM
- openvex: OpenVEX 0.2.0 exploitability statements for each dependency CVE (`affected` / `not_affected` / `under_investigation`), with `not_affected` backed by reachability analysis. Pairs with an SBOM
- cyclonedx-vex: CycloneDX 1.6 VEX: the same exploitability verdicts as `openvex`, in a CycloneDX `vulnerabilities[].analysis` document
- cbom-1.7: CycloneDX 1.7 CBOM. Same crypto-asset grouping as `cbom` plus a richer post-quantum descriptor. Offered alongside 1.6 (default)
- pdf: PDF render of the executive HTML report (requires `wkhtmltopdf` on PATH)
- ropa-md: GDPR Article 30 Records-of-Processing template - Markdown
- ropa-html: GDPR Article 30 Records-of-Processing template - HTML
- ndjson: Newline-delimited JSON: one finding per line plus a trailing summary line. Designed for SIEM ingestion and `jq` filter pipelines
- evidence-graph: Evidence-graph JSON (`evidence-graph/1.0`): a stable, versioned, AI-consumable document that composes endpoints, taint source -> sink flows, reachability verdicts, findings, and the dependency SBOM into one graph. Meant to be handed to an external AI agent as deterministic ground truth (Vulkro embeds no model; the agent brings its own). Pairs with `vulkro aggregate` for cross-repo linking. See `docs/ai-tool/`

[default: table]

--offline
Hard-disable every outbound network call for this run (sets VULKRO_OFFLINE=1). Blocks the CVE feed, the license heartbeat, the update check, webhooks, and any cloud AI endpoint; a loopback model (http://127.0.0.1, http://localhost) is still allowed. Equivalent to exporting VULKRO_OFFLINE=1, and the flag wins when both are set

--ai
[advisory] Attach a plain-language AI SECURITY-DELTA narrative to the surface diff: new unauthenticated routes, removed auth checks, and new / regressed findings, explained for a reviewer. The resolved LOCAL model (see `vulkro ai`) narrates ONLY the deterministic signals; it never changes the diff, the findings, or the exit code. The narrative is additive (a `ai_narrative` field in JSON, a labelled block in text), labelled advisory / non-deterministic / excluded-from-benchmark, and omitted entirely without `--ai`. A loopback model is allowed under VULKRO_OFFLINE; a cloud url is refused offline. AI off or unreachable prints a note and leaves the diff unchanged

--ai-model <MODEL>
AI model tag override for `--ai` (highest precedence). Overrides VULKRO_AI_MODEL, the saved `vulkro ai use` selection, and the smart default. Example: `--ai-model qwen2.5-coder:7b`

--ai-url <URL>
AI runtime base url override for `--ai` (OpenAI-compatible). Example: `--ai-url http://127.0.0.1:11434/v1`. A loopback url is allowed under VULKRO_OFFLINE; a cloud url is refused offline

-h, --help
Print help (see a summary with '-h')