Safety
Last updated: July 20, 2026
Vulkro is built around a single design constraint: your source code, your scan results, and your environment never leave your machine.
This page is the operational complement to the Privacy Policy. Privacy explains the legal posture ("we never receive your scan data"). This page explains the engineering posture: how the binary is built so the data cannot leave, even by accident.
What Vulkro never does
Vulkro the binary, when invoked on your machine, never:
- Uploads source code anywhere. Not to us, not to a cloud
function, and not to a model (the one exception is the opt-in
vulkro triage, which sends finding context to the AI provider whose key you supply). The scanner reads bytes from disk into memory and emits findings to stdout / a file path you control. - Executes your code. Vulkro is a static analyzer built on
tree-sitter. It does not call
npm,pip,bundle,go build,cargo build, or any package-manager command. A package manager could (in principle) be subverted by a compromised package; vulkro removes that vector entirely. - Resolves DNS or makes an outbound HTTP request to analyze your
code. The analysis is fully local. The binary's network calls
sit outside the scan path and are enumerated below; with a
license file installed,
VULKRO_OFFLINE=1disables every one of them at the binary boundary. - Sends content telemetry, analytics, error reports, or any data derived from your code. The account entitlement check carries up to eight usage fields (product, install id, version, operating system, timestamp, and a scan counter, plus a device token while signed in and a short set of language slugs after a scan), never code, paths, or findings. There is no code path that sends scan content or a diagnostic home.
- Trains a model on your code. No vendor-side model ingest, no fine-tuning loop, no embedding capture. Vulkro is not an AI product in the LLM sense; the detection engine is a pattern-matching static analyzer.
- Reads files outside the scan root you pass. The default scan
root is the working directory; subprojects are detected only
within. Vulkro respects
.gitignoreand the Vulkro config's exclude patterns.
What Vulkro does do
Three things, all local:
- Read source files within the scan root. The reads are
bounded by the cap flags (
--max-file-size,--max-files) and the.gitignorefilter. - Parse the source via tree-sitter grammars compiled into the binary. Parsing is in-memory; no temp files, no fork-exec.
- Match the parse tree against the detector catalog. Each detector is a Rust function that takes the AST + source bytes and emits zero or more findings. Findings are serialized to your chosen output format and written to stdout or your file.
That is the entire scan. No phase of it requires the network, the package manager, your shell, the system clipboard, or any remote service.
The network calls, enumerated
The binary makes exactly one automatic outbound call, and it carries no code, paths, or findings:
- The account entitlement check. Vulkro requires an account
(
vulkro login); the check verifies your entitlement about once a day, on a background thread, and sends the usage fields listed above (up to eight), nothing else. Air-gapped machines use a signed license file instead and make no call at all.
That is the complete automatic list. In particular, the scanner
does not check for updates while it works. A vulkro scan makes
no release-feed request and no upgrade notice can appear.
Every other call the binary is capable of is explicit: it happens because you ran a command or set a variable that asks for it.
- The CVE bundle download on
vulkro update, from dist.vulkro.com, so the dependency-vulnerability matcher has fresh advisory data. It is gated by an explicit subcommand and served over HTTPS. The download is checksummed; cryptographic signature verification against a pinned trust root is planned but not yet enabled. - The release version check, a small JSON feed on the same CDN,
now runs only inside
vulkro update. When you run that command it reads the feed and offers to install the newer binary if there is one. Suppress it with the command's--no-version-checkflag, or withVULKRO_NO_UPDATE_CHECK=1, which still works and now applies to this one command because nothing else consults the feed. vulkro triagesends finding context to the AI provider whose key you supply. It runs only when you ask for it and refuses underVULKRO_OFFLINE=1.vulkro scanmakes no model call under any flag.VULKRO_CVE_LIVE=1opts in to a live CVE lookup that sends each dependency's package name, version, and ecosystem toapi.osv.dev, catching CVEs published since your local bundle. It is off unless you set it: by default your dependency tree is matched against the local bundle and never leaves the machine.vulkro updaterefreshes that bundle and needs no opt-in.
If your network policy blocks all of this, run the binary fully offline:
VULKRO_OFFLINE=1refuses every outbound call (the entitlement check, the CVE bundle fetch, and the version check). Pair it with a license file and the scanner runs fully disconnected.- You can also fetch the bundle on a machine with internet
access and copy it to
~/.vulkro/cve-bundle/; vulkro reads it from disk.
The bundle ingress is documented in Offline mode and Bundle format.
Versus cloud-hosted SAST
How Vulkro sits against the cloud-hosted category, where the scan runs on the vendor's infrastructure rather than on yours. Named head-to-head comparisons live on the comparison pages; this table is about the architecture, not about any one product.
| Vulkro | Cloud SAST | |
|---|---|---|
| Source code uploaded to vendor | No | Yes (the scan happens on their infrastructure) |
| Scan results visible to vendor | No | Yes (stored in vendor's database) |
| Used to train vendor's models | No | Sometimes (read the terms of service) |
| Subject to vendor data-breach exposure | No | Yes |
| Inspectable build artefacts | Yes (checksummed binaries) | No (server-side) |
| Public methodology | Yes | Vendor-published only |
Cloud SAST has real strengths (managed updates, web UI, centralized policy) and Vulkro is not trying to replace it for every team. But if "the vendor never sees the code" is a hard requirement (defense, healthcare, finance, anyone under NDA with their customers), Vulkro is built to make that requirement enforceable rather than trust-based.
How to verify
Skepticism is welcome. Three concrete checks:
- Run with the network disabled.
VULKRO_OFFLINE=1 vulkro scan .produces the same findings as a connected run (modulo CVE bundle freshness). A scanner that "needs the cloud" would fail or hang. - Snoop the network at the OS layer.
lsof -i,tcpdump, or your firewall logs while a scan runs will show no connection carrying your code, and at most one small entitlement POST toapi.vulkro.com(once per 24 hours, on a background thread). Nothing else: no lookup against the release feed, no other CDN request, nothing to a model provider. If the entitlement check already ran today, a scan shows no outbound connection at all. Re-run underVULKRO_OFFLINE=1with a license file and you will see zero outbound connections from the vulkro process. - Check the public artifacts. Vulkro is closed source (the detector implementation is the licensed product), but the binary is not obfuscated, and the benchmark harness and methodology plus the compliance mapping are public, so the accuracy and evidence claims are verifiable without the rule engine.
Reporting a safety claim that turned out to be wrong
If you find a code path that contradicts anything on this page, treat it as a security bug and email [email protected] with the reproduction. The safety guarantees on this page are load-bearing; a bypass is treated with the same seriousness as an authentication bypass would be in a customer's product.