VS Code security extension (also Cursor and Windsurf)
Vulkro ships a Language Server Protocol
server, exposed as the vulkro lsp subcommand of the main binary, and a
VS Code extension that consumes it. The same extension loads in Cursor and
Windsurf (both VS Code forks).
There are two extensions, and they install side by side: Vulkro (this
page, driven by vulkro) and Vulkro for Salesforce (driven by
vulkro-sf). Each takes its own files. Anything under a folder containing
sfdx-project.json goes to the Salesforce extension, including the
JavaScript and HTML inside lwc/ and aura/; everything else goes to
this one. Installing only Vulkro in a Salesforce project does not scan
Apex: it shows a one-time notice pointing at the other extension. Each has
its own Marketplace listing, README and icon. See
the Salesforce extension page.
The extension surfaces Vulkro findings inside your editor as diagnostics, with hover-to-explain, quick-fix code actions, report export, a CI-parity check, and optional AI assistance. AI assistance is advisory and local: it never changes a deterministic scan result, and the published benchmark is AI-free.
Install
The extension spawns the vulkro binary you already have, so install the
scanner first (see the install guide).
Install Vulkro from the Visual Studio Marketplace (search for Vulkro in
the Extensions view), or from the CLI you already have, which finds your
editor even when its code command is not on your PATH:
vulkro install-extension # detects your editor, asks, then installs
vulkro-sf install-extension # the Vulkro for Salesforce extension
It detects VS Code, Cursor, Windsurf, and VSCodium (on your PATH and in each
editor's standard install location), downloads the .vsix from the Vulkro CDN,
and installs it through the editor's own CLI. Flags: --yes (skip the prompt),
--editor <name>, --vsix <file> (install a local package). VULKRO_VSIX_URL
overrides the download URL for a self-hosted mirror or an air-gapped copy. If no
editor is found, it prints how to add the code command or install from a VSIX
by hand.
Build from source / install a .vsix manually. You can also build and
install the package directly, from integrations/editors/vscode:
cd integrations/editors/vscode
npm install
npm run package:editions
That emits vulkro-<version>.vsix (Vulkro) and vulkro-sf-<version>.vsix
(Vulkro for Salesforce). Install one through your editor: Extensions view,
... menu, Install from VSIX.
If the binary cannot be found when the extension starts, it offers an
Install action (also the Vulkro: Install or update the scanner binary
command) that downloads the right release for your platform, verifies its
.sha256, and installs it into ~/.vulkro/bin. That download runs only when
you trigger it, never on activation; it respects VULKRO_OFFLINE=1 and
honours the VULKRO_CDN host override.
Free, Pro and signing in
No account is needed. Every language scans without signing in, and every finding comes with its proof and its fix. That is Free, on one repository at a time, and it never expires.
Signing in holds Pro. In the editor that means the views that turn one scan into a picture of the whole application: attack paths, impact, working-tree review, the data-flow and code-structure maps, history, trends, compare, the evidence formats, the executive report and the AI impact narrative. Each Pro view opens three times on Free before it locks, so you can see what it adds on your own code; the lock line names the capability and its See pricing action opens the pricing page. The first verified device login on an account starts a 14-day term of the full product.
The extension is a thin layer over the CLI: the vulkro binary owns your
licence, so signing in from the editor runs the same device login as
vulkro login.
- Command Palette (
Cmd/Ctrl+Shift+P) -> Vulkro: Sign in (or the Sign in button in the Vulkro sidebar's Account view). - Your browser opens to your account; approve the device code the editor shows.
- The editor is bound to your account. If you had already run
vulkro loginon this machine, you are signed in immediately - the extension and the CLI share the same on-disk license.
Sign out with Vulkro: Sign out. Air-gapped machines use Vulkro: Activate
license file to activate a .lic offline instead. Licenses are issued
directly by our team (license@vulkro.com).
What you get
- Diagnostics on open and save. Open any Python, JavaScript, TypeScript,
JSX/TSX, Go, or Java file inside a project with a root marker (
.git,package.json,pyproject.toml,Cargo.toml,go.mod,pom.xml,build.gradle,build.gradle.kts,composer.json,sfdx-project.json, orvulkro.toml). The server paints the open file first with a fast single-file scan, then reconciles with a full project scan moments later. Saving re-runs the engine; typing only republishes cached results (debounced), so keystrokes never trigger a re-scan. - Scanning without an account. Every language, including Java, scans without signing in, with the proof and the fix on every finding. Signing in holds Pro; the first verified device login on a device starts a 14-day term of the full product. Licences are issued directly by our team (license@vulkro.com).
- Salesforce projects belong to the other extension. Anything under a
folder containing
sfdx-project.json, the JavaScript and HTML insidelwc/andaura/included, is scanned by Vulkro for Salesforce, which installs side by side with this one. Without it, this extension shows a one-time notice pointing at it and leaves those files alone. See the Salesforce extension page. - Hover to explain. Hovering a diagnostic surfaces the rule id, severity, message, and remediation in a Markdown popup.
- Quick fixes on the lightbulb. Every Vulkro diagnostic offers
Suppress (insert a
// vulkro:disable next-line <rule>comment) and Explain (the rule's long-form explainer). A small set of clear-cut patterns (weak hash,yaml.load, cookie flags, debug flags, and similar) also gets a deterministic one-line fix; each template refuses to edit any line whose shape it does not fully recognise. Fix with AI (review) appears when local AI is set up (see below). - Sidebar views. The Vulkro activity-bar container shows Overview,
This File, Issues, and Account by default. Turning on
vulkro.showAdvancedViewsreveals Changes, History, Impact, Codemap, Trends, Dependencies, AI Hunt, Suppressions, and Ask Vulkro. Changes, History, Impact, Codemap and Trends are Pro views, with three free looks each. A status bar item shows the live finding count. - Watch mode.
vulkro.watch(or Vulkro: Toggle watch mode) rescans the whole workspace as files change on disk, including files you have not opened and changes made bygit checkoutor codegen. Off by default. - Baseline. Set, clear, or toggle a baseline to hide known findings and surface only new ones.
- Severity display floor.
vulkro.severityThresholdhides findings below the chosen level from the gutter, the Problems panel, and the Vulkro views. It is a display floor, not a scan setting: the scanner still detects everything.
You stay in control of edits
The language server never writes to your files. Every edit it can produce (the suppression comment, a deterministic one-line fix, an AI fix candidate) is proposed through the editor and applied only when you accept it. AI fix candidates go one step further: a candidate is only offered after a fresh deterministic re-scan of the patched working copy confirms the finding no longer appears and the file still parses. That is what "verified" means here; it does not claim the build compiles or the tests pass.
Export a report
Vulkro: Export report (SARIF and other formats) (vulkro.exportReport)
runs the same whole-project vulkro scan that CI would, captures the output,
and saves it where you choose:
- SARIF 2.1.0 (the portable default): open it in a SARIF viewer or upload it to your code-scanning platform.
- JSON: the native Vulkro findings document, for scripts and
jq. - HTML is offered only when the installed engine's
scanaccepts--format html; the command probesscan -hso the picker never offers a format your binary would reject.
A scan that exits 0 (clean) or 1 (findings reported) both produce a
report; only exit 2 (error) is treated as a failure.
Editor / CI parity
Vulkro: Verify editor / CI parity (vulkro.verifyCiParity) runs the
CI-equivalent scan (vulkro scan <root> --format json), counts findings by
severity, and reports how your vulkro.severityThreshold display floor maps
onto a CI invocation. It then offers to copy the matching command, for
example:
vulkro scan . --min-severity low
--min-severity is the CLI twin of the editor's display floor: it drops
findings below the level from the output (composing with --fail-on, which
then evaluates the filtered set), so CI and the editor agree on what appears.
See CLI: scan.
AI assistance (local first)
All AI features are optional and advisory: they never change a deterministic
scan result, and the benchmark stays AI-free. The default transport is a
local model through Ollama, default model
qwen2.5-coder:7b, so nothing leaves your machine.
- Vulkro: Set up AI model lists recommended models (with their licenses), pulls your pick, and self-tests the connection. Test AI connection and Disable AI manage it afterwards.
- Fix issue with AI (review + apply) and Fix all issues with AI draft fixes for findings, validate each one with a deterministic re-scan (a fix is verified when the re-scan no longer reports the finding and the file still parses; the build compiling or tests passing is not claimed), show you the diff, and apply only what you accept.
- Explain impact with AI, Review my changes with AI, AI Hunt, and the Ask Vulkro chat view build on the same local model.
Using your editor's AI model instead
If you do not run Ollama, vulkro.ai.transport: "editor" (or Vulkro: Use
editor AI model) reuses the model your editor already provides (for
example GitHub Copilot) through a loopback shim on 127.0.0.1. This is
opt-in behind an explicit confirmation, because prompt content (which can
include your source code and findings) is sent to whatever provider backs
that model, usually a cloud service. It is refused outright when
VULKRO_OFFLINE=1 is set. Vulkro: Use local AI model switches back.
Your editor's AI agent can call Vulkro
On hosts new enough to expose the APIs (the extension targets VS Code 1.101+; older hosts degrade gracefully), the extension also plugs the scanner into the editor's own AI agent:
- Language-model tools.
vulkro_scan_filescans a single file and returns its findings;vulkro_explain_findingexplains a rule id. Agent mode can call both, and you can reference them in prompts (#vulkroScanFile,#vulkroExplainFinding). The Vulkro for Salesforce extension registersvulkro_sf_*twins, so both co-exist in one host. - MCP server. An MCP server-definition provider teaches the editor to
launch the engine's own stdio MCP server (
vulkro mcp serve) withVULKRO_OFFLINE=1set, so the agent's MCP scans never reach the network.
Settings
| Setting | Default | Purpose |
|---|---|---|
vulkro.path | vulkro | Path to the vulkro binary, or the bare name if it is on PATH. The extension spawns <path> lsp. |
vulkro.severityThreshold | low | Lowest severity shown (critical, high, medium, low, info). A display floor: match it to your CI --min-severity. |
vulkro.showAdvancedViews | false | Reveal the full set of sidebar views beyond Overview, This File, Issues, and Account. |
vulkro.watch | false | Rescan the whole workspace as files change on disk, including unopened files. |
vulkro.lsp.debounceMs | 300 | Debounce window (ms) for didChange republishes, clamped to [50, 5000]. Passed as VULKRO_LSP_DEBOUNCE_MS. |
vulkro.ai.model | (empty) | Override the local AI model; empty uses the engine default (qwen2.5-coder:7b). Passed as VULKRO_AI_MODEL. |
vulkro.ai.url | (empty) | Base URL of the local Ollama (OpenAI-compatible) endpoint; empty uses http://127.0.0.1:11434/v1. Passed as VULKRO_AI_URL. |
vulkro.ai.transport | local | local keeps AI fully on-machine; editor reuses the editor's model through the loopback shim (opt-in, see above). |
vulkro.trace.server | off | Trace LSP traffic in the Vulkro output channel. |
The Vulkro for Salesforce extension has its own settings namespace
(vulkro-sf.path, vulkro-sf.severityThreshold, vulkro-sf.scanOnSave,
vulkro-sf.watch, vulkro-sf.targetOrg, vulkro-sf.trace.server); see
the Salesforce extension page.
Because the server maps Critical and High to the same editor severity
(Error), the critical and high thresholds behave identically in the
editor.
How the LSP talks to the scanner
vulkro lsp runs the scan in-process: no subprocess, no JSON-over-pipe. It
uses the same detection pipeline as vulkro scan (the full extractor set,
the auth model, taint analysis, and the same suppression pass), so a
// vulkro:disable directive silences the same finding in the editor and in
CI. Diagnostics are pushed by the server per file. vulkro lsp exits 0 on
a clean shutdown and 2 on an operational error; set VULKRO_LSP_LOG=1 for
a stderr message trace.
Performance
Opening the first file in a project (and every save) publishes the current file's findings from a fast single-file scan first, so squiggles land in a fraction of a second, then a full project scan reconciles the complete picture. Typing republishes cached results only; the engine re-runs on save (or on any disk change when watch mode is on).
For a scoped terminal loop alongside the editor, run something like
vulkro scan . --min-confidence high --scope src (see
CLI: scan).
Suppressing network egress from inside the editor
To suppress all network egress from the binary the editor spawns, set:
// settings.json
"terminal.integrated.env.osx": {
"VULKRO_OFFLINE": "1"
}
(Adapt osx to linux / windows as needed.)
VULKRO_OFFLINE=1 is the single switch and covers everything: scans, the
managed binary install, and the editor-AI transport (which is refused under
it). The MCP server the extension registers is always launched with
VULKRO_OFFLINE=1 regardless.
What this isn't (yet)
- No standalone JetBrains plugin. The server works with any LSP-aware
editor in principle;
vulkro lsp --helpprints ready-made snippets for Neovim (nvim-lspconfig), Helix, and Emacs eglot. VS Code (and its forks) is the only editor with a packaged extension today. - No unreviewed rewrites. Every edit, deterministic or AI-drafted, is applied only when you accept it, and AI candidates must first pass the deterministic re-scan described above.
- No as-you-type engine runs. Diagnostics refresh from cache while you type; the engine re-runs on save (or on disk changes in watch mode).
Related
vulkro scan: the CLI front door that produces the same findings the LSP surfaces, plus the--min-severityparity flag.- Salesforce extension page: the
other extension, driven by the
vulkro-sfserver. - Pricing: which views are Free and which are Pro, in the scanner's own words.