Network egress
This page lists every outbound network call the Vulkro scanner can make. It is the page to hand your security team. The short version:
- There is no telemetry, no analytics, and no crash reporting anywhere in the binary. Vulkro never sends your code, findings, or usage data to us.
- Exactly one call is automatic (the once-a-day update-check ping). Every other call happens only when you run a specific command or flag.
VULKRO_OFFLINE=1disables all of them. With it set, the scanner makes zero outbound connections.
Egress inventory
| Call | Trigger | Destination | Payload | Default | VULKRO_OFFLINE=1 |
|---|---|---|---|---|---|
| Update-check ping | Background thread on any command | dist.vulkro.com/releases/latest.json | GET; User-Agent: vulkro/<version>; no body | On (cached 24 h) | Disabled (no request) |
| Dependency CVE lookup | vulkro scan when a parsed manifest is found | api.osv.dev/v1/querybatch | POST JSON: {name, version, ecosystem} per dependency | On (scans with deps) | Disabled |
| CVE bundle download | vulkro update (no --bundle) | dist.vulkro.com/cve/... (override: VULKRO_CDN_BASE_URL) | GET; signature + sha256 verified before apply | Off (explicit) | Refused (exit 2) |
| Installer fetch | Interactive vulkro update after you confirm | dist.vulkro.com/install.sh | GET via curl | bash | Off (TTY + consent) | The update is refused first, so this never runs |
| Secret validation | vulkro scan --validate-secrets | Stripe, GitHub, SendGrid, Slack, OpenAI APIs | GET/POST with Authorization: Bearer <the discovered secret> | Off (opt-in) | Refused (exit 2) |
| Notifications | vulkro notify / vulkro scan --post-to <...> | Your webhook (Slack/Teams/Jira) or events.pagerduty.com | POST JSON scan summary (counts, top findings) | Off (opt-in) | notify refused (exit 2); --post-to skipped with a warning |
| Rule-pack registry | vulkro rules add / rules update | dist.vulkro.com/rules/... (override: VULKRO_RULES_REGISTRY_URL) | GET; sha256 verified | Off (explicit) | Refused (exit 2) |
| Active probe | vulkro probe --base-url <URL> | The target URL you supply | Crafted attack requests (see probe) | Off (explicit) | Refused (exit 2) |
| Test webhook | "Test webhook" button in vulkro serve | Your configured webhook URL | POST a fixed test payload | Off (manual click) | Refused (error in the UI) |
Notes:
- Destinations are fixed or yours. The
dist.vulkro.comcalls are the only ones that reach Vulkro infrastructure, and all of them are off by default except the update-check ping. The probe and webhook destinations are URLs you supply. - Signed and verified. Every artifact Vulkro downloads (CVE bundle, rule
packs) is signature- and/or sha256-verified against trust roots
pinned in the binary before it is used. Mirroring via
VULKRO_CDN_BASE_URLdoes not change the trust model.
Listeners (not egress)
These accept inbound connections on loopback; they do not send data out. They
are not gated by VULKRO_OFFLINE because their purpose is to serve a local UI.
vulkro servebinds127.0.0.1:8723(the desktop console).vulkro mcp serve --port <P>binds127.0.0.1:<port>(SSE transport; the default MCP transport is stdio, no socket).vulkro lspspeaks over stdio (no socket).
Verifying zero egress
VULKRO_OFFLINE=1 is the single switch. To prove it under OS-level network
blocking:
# Linux: run in a network namespace with no interfaces.
unshare -rn /bin/bash -c 'VULKRO_OFFLINE=1 vulkro scan .'
# macOS / any platform: observe syscalls and confirm no connect() to a
# non-loopback address.
sudo dtruss -t connect -f env VULKRO_OFFLINE=1 vulkro scan . # macOS
strace -f -e trace=connect env VULKRO_OFFLINE=1 vulkro scan . # Linux
The scan should complete normally and you should see no connect() to any
non-loopback address. If you observe one, it is a bug: please report it.
The egress inventory above is also enforced in our own CI: a source-level guard
test fails the build if any new code path makes an outbound call (reqwest, raw
TCP, or raw TLS) without being covered by a VULKRO_OFFLINE gate. The inventory
cannot silently grow.
Related
- Offline mode - the command-by-command behaviour table.
- Bundle format and Signing & trust roots.