Skip to main content

vulkro discover

Map your API surface - extract every HTTP endpoint without running any security scan. Faster than scan and useful when you only need the route inventory (e.g. for OpenAPI generation, contract diffs, or onboarding docs).

Usage

vulkro discover [PATH]
vulkro discover [PATH] --format json

Arguments

ArgumentDescriptionDefault
PATHPath to the project root..

Flags

FlagDescriptionDefault
--format, -ftable, json, sarif, gh-pr, junit, csv, cyclonedx, spdx, pdf, ropa-md, ropa-html.table

What it does

Walks the working tree honouring .gitignore, detects the language and framework, and statically extracts:

  • HTTP method
  • Route path (with [param] -> {param} normalisation for Next.js)
  • Source file + line number
  • Handler function (when extractable)
  • Auth status (Protected, Unprotected, Unknown)

Output is the same Endpoint records the security engine consumes - so vulkro discover --format json is the canonical way to feed Vulkro's endpoint detection into another tool.

Example

$ vulkro discover ./mealie

Detected: Python | FastAPI
124 endpoints

GET /api/auth/refresh [Protected] mealie/routes/auth.py:42
POST /api/auth/login [Unprotected] mealie/routes/auth.py:67
GET /api/recipes/{slug} [Protected] mealie/routes/recipes.py:113
DELETE /api/groups/{group_id}/members [Protected] mealie/routes/groups.py:88
...

Export to OpenAPI

vulkro export . --target openapi -o openapi.yaml

Produces an OpenAPI 3.1 document with one operation per endpoint. Schemas are minimal placeholders - Vulkro doesn't infer request/response shapes - but route paths, parameters, and method are accurate.

Command reference

Generated from vulkro help discover 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.

List every API endpoint in a project without running the security checks.

Map your API surface: extract all endpoints without running a security scan.

Exit codes: `0` success, `2` arg error or internal failure. Discover never emits findings so exit `1` is not used.

Usage: vulkro discover [OPTIONS] [PATH]

Arguments:
[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

--no-cache
Bypass the per-file extraction cache (`~/.vulkro/scans.db`). Forces every source file to be re-read and re-extracted, and suppresses cache writes. Useful for regression hunts or when you want a clean-slate measurement of scan latency

--force-app
Bypass the framework self-scan heuristic. By default, a repo whose manifest names it as a known framework (`name: "express"`, `name = "Flask"`, etc.) is treated as framework source - endpoint extraction is skipped because every "finding" would be the framework's own internals, not the user's code. Pass `--force-app` to run the full pipeline regardless

--include-unreachable
Include findings in files unreachable from any entry point. By default these are hidden - most are noise in dead code or vendored deps. Use this to include them for triage. This is a DISPLAY flag: on `discover` it changes the table and the RoPA document only. The machine-readable lanes (json, the SBOM emitters, csv, evidence-graph) always carry the full set, with each hidden row tagged `suppressed_by_unreachability`, so a downstream consumer can filter them itself

--force-all-rules
Bypass the posture-based rule-applicability gate. Every rule runs regardless of the project's detected `ProjectPosture`. Default `false`: CSRF on JWT APIs, session-fixation on static sites, and similar inapplicable rules are silenced

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