Skip to main content

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 content telemetry, no analytics, and no crash reporting anywhere in the binary. Vulkro never sends your code, file paths, or findings to us. The only usage data that ever leaves the machine is the account entitlement refresh, which carries exactly six fields: product, install id, version, operating system, timestamp, and a scan counter.
  • Two calls are automatic (the once-a-day update-check ping, and the once-a-day entitlement refresh while you are signed in). Every other call happens only when you run a specific command or flag.
  • VULKRO_OFFLINE=1 disables all of them. With it set, the scanner makes zero outbound connections; pair it with an installed license file, which satisfies the account requirement without any network access.

Egress inventory

CallTriggerDestinationPayloadDefaultVULKRO_OFFLINE=1
Account sign-invulkro login (explicit)The Vulkro license serviceSign-in exchange that returns a signed lease; never code, paths, or findingsOff (explicit command)Refused; use a license file instead
Entitlement refreshBackground, about once a day while signed inThe Vulkro license serviceSix usage fields: product, install id, version, OS, timestamp, scan counterOn when signed inDisabled; an installed license file satisfies the account requirement
Update-check pingBackground thread on any commanddist.vulkro.com/releases/latest.jsonGET; User-Agent: vulkro/<version>; no bodyOn (cached 24 h)Disabled (no request)
Dependency CVE lookupvulkro scan when a parsed manifest is foundapi.osv.dev/v1/querybatchPOST JSON: {name, version, ecosystem} per dependencyOn (scans with deps)Disabled
CVE bundle downloadvulkro update (no --bundle)dist.vulkro.com/cve/... (override: VULKRO_CDN_BASE_URL)GET; signature + sha256 verified before applyOff (explicit)Refused (exit 2)
Installer fetchInteractive vulkro update after you confirmdist.vulkro.com/install.shGET via curl | bashOff (TTY + consent)The update is refused first, so this never runs
Secret validationvulkro scan --validate-secretsStripe, GitHub, SendGrid, Slack, OpenAI APIsGET/POST with Authorization: Bearer <the discovered secret>Off (opt-in)Refused (exit 2)
Notificationsvulkro notify / vulkro scan --post-to <...>Your webhook (Slack/Teams/Jira) or events.pagerduty.comPOST JSON scan summary (counts, top findings)Off (opt-in)notify refused (exit 2); --post-to skipped with a warning
Rule-pack registryvulkro rules add / rules updatedist.vulkro.com/rules/... (override: VULKRO_RULES_REGISTRY_URL)GET; sha256 verifiedOff (explicit)Refused (exit 2)
Active probevulkro probe --base-url <URL>The target URL you supplyCrafted attack requests (see probe)Off (explicit)Refused (exit 2)
Test webhook"Test webhook" button in vulkro serveYour configured webhook URLPOST a fixed test payloadOff (manual click)Refused (error in the UI)

Notes:

  • Destinations are fixed or yours. The dist.vulkro.com calls and the license-service calls are the only ones that reach Vulkro infrastructure, and all of them are off by default except the update-check ping and the entitlement refresh. 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_URL does 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 serve binds 127.0.0.1:8723 (the desktop console).
  • vulkro mcp serve --port <P> binds 127.0.0.1:<port> (SSE transport; the default MCP transport is stdio, no socket).
  • vulkro lsp speaks 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.