Offline mode
Vulkro scans offline by design. Exactly one outbound call is automatic; every other call happens only when you ask for it. The full list:
- Account sign-in and entitlement refresh - the only automatic call.
vulkro loginconnects the CLI to your account, and your first login starts a 14-day trial. While signed in, the CLI refreshes its signed lease about once a day. The refresh carries up to eight usage fields (product, install_id, version, OS, timestamp, scan counter, plus a device token while signed in and a language slug-set after a scan), never code, paths, or findings. Air-gapped machines use an installed license file instead and make neither call. See Telemetry for the exact fields. - Live dependency CVE lookup - opt-in only. With
VULKRO_CVE_LIVE=1,vulkro scanqueriesapi.osv.devwhen it finds a parsed dependency manifest, sending package name, version, and ecosystem, to catch CVEs published since your local bundle. Off by default: a plain scan resolves dependencies against the local bundle only, so nothing about your dependency tree leaves the machine.VULKRO_OFFLINE=1overrides the opt-in. - Installer - fetches the binary tarball from the Vulkro release feed.
- First-run CVE bundle -
vulkro updateruns once during install to populate~/.vulkro/data/cves/. vulkro updatewhen invoked explicitly. It downloads the signed CVE bundle, and it is also the only place the release-feed version check runs: it asks for the latest version and offers to install a newer binary. The scanner does not check for updates while it works, so a plainvulkro scannever touches the release feed. Suppress just the version check with--no-version-checkorVULKRO_NO_UPDATE_CHECK=1.vulkro probe --base-url <URL>when invoked explicitly.vulkro rules add/vulkro rules updatewhen invoked explicitly.vulkro notify --url <URL>/vulkro scan --post-to <...>when invoked explicitly.vulkro scan --validate-secretswhen invoked explicitly.
The analysis itself is always local. Discovery, scan, container scan,
history, diff, trends, contributors, compliance, and the desktop console all
read from disk and write to disk. Your source code, file paths, and findings
are never sent anywhere by any command in the list above. VULKRO_OFFLINE=1
(below) disables every call in the list. For the full per-call inventory
(destination, payload, gate), see Network egress.
VULKRO_OFFLINE=1
Setting this environment variable refuses every outbound network call. Affected commands:
| Command | Behaviour with VULKRO_OFFLINE=1 |
|---|---|
| Entitlement refresh (the one automatic call, while signed in) | Disabled - install a license file (vulkro activate <file>.lic) to satisfy the account requirement with zero network. |
Release-feed version check (only inside vulkro update) | Disabled - no request is sent. |
vulkro login | Refused - use a license file on offline machines. |
vulkro update (no flags) | Refused with a hint to use --bundle. |
vulkro update --bundle <path> | Allowed. Fully offline. |
vulkro update --verify <path> | Allowed. Fully offline. |
vulkro rules add | Refused (503-style error). |
vulkro rules update | Refused (503-style error). |
vulkro probe | Refused (exit 2) - the probe contract is "I will make HTTP calls". |
vulkro notify | Refused (exit 2). |
vulkro scan --post-to <...> | Skipped with a warning; the scan still runs. |
vulkro scan --validate-secrets | Refused (exit 2) for the validation lane; main scan still works. |
vulkro scan (no validate-secrets) | Fully offline. |
vulkro container <ref> | Allowed. Shells out to local docker only. |
vulkro publish / vulkro org publish | Refused (exit 2) with an actionable error. Publishing to an organisation dashboard is an outbound call by definition, so offline mode and the dashboard do not mix. |
vulkro publish --preview / --terms | Allowed. Both print locally and send nothing. |
Scanning is unchanged: it needs no account and no network, and it uploads
nothing. The organisation dashboard is the single exception, and it is
opt-in per repository: running vulkro publish uploads a map of the
application (file and module names, API routes, and the file and line
behind each finding) plus your dependency inventory and contributor names.
It never uploads your source, your snippets or your secrets. Preview the
exact payload with vulkro publish --preview and read the terms with
vulkro publish --terms.
A fully air-gapped organisation is not supported: if your machines have no
route out, keep the offline seat and the dashboard simply is not available.
See vulkro publish.
Verifying the contract
You can confirm Vulkro holds to the offline contract:
# Run vulkro with all network egress blocked at the kernel level.
unshare -rn /bin/bash -c 'VULKRO_OFFLINE=1 vulkro scan .'
Should complete without error.
CDN base URL override
For organisations that mirror the Vulkro CVE bundle internally:
export VULKRO_CDN_BASE_URL="https://artifacts.internal/vulkro-cve"
vulkro update
The mirror must serve the same /manifest.json + /manifest.json.sig +
bundle layout as the public CDN. Signed bundles are still verified
against the built-in trust list - mirroring doesn't change the signing
trust model.
Air-gapped install
Full walkthrough at Install -> Air-gapped install.