VS Code, Cursor, and Windsurf extension
The Vulkro IDE extension drives both scanners from a single .vsix
(which also loads in Cursor and Windsurf, both VS Code forks):
vulkro(the general-purpose scanner) for non-Salesforce code.vulkro-sf(the Salesforce scanner) for SFDX projects.
The extension is a thin shell over the two language servers: it does not
re-implement detection. Findings come from vulkro or vulkro-sf exactly
as the engines produce them. The detectors stay closed-source; the
extension is the UI surface, not a second implementation.
This page covers the Salesforce side. For the general behaviour (the findings panel, status bar, severity filter, and the managed binary install) see the core extension page.
Requirements
- The
vulkro-sfbinary onPATH, or an absolute path in thevulkro-sf.pathsetting. If it is missing when the extension starts, the error offers an Install action that downloads and checksum-verifies it into~/.vulkro/bin. - The Salesforce Extension Pack (or any extension that contributes the
apexlanguage id). Apex highlighting routes on that language id; without it,.cls/.triggerfiles are still matched by file glob but you lose Apex syntax support.
Workspace auto-detection
When you open a folder the extension checks the workspace for Salesforce DX
markers: sfdx-project.json, .forceignore, or a force-app/main/default
directory. If any is present it starts a second language server,
vulkro-sf lsp, alongside the core vulkro server. The two tag their
diagnostics with distinct sources (vulkro vs vulkro-sf).
Apex is routed to vulkro-sf exclusively (it is removed from the core
server's selector) so a finding is never published twice. The core vulkro
binary runs with Salesforce detection disabled, which is exactly why the
dedicated vulkro-sf server is needed for Salesforce code.
Settings
// .vscode/settings.json (or User Settings)
{
// Path to the vulkro-sf binary. Default: vulkro-sf (resolved against PATH).
"vulkro-sf.path": "/usr/local/bin/vulkro-sf",
// Minimum severity to surface from the Salesforce server. Default: medium.
"vulkro-sf.severityThreshold": "high",
// Re-run vulkro-sf on every save. Default: true. Disable for very large orgs.
"vulkro-sf.scanOnSave": true,
// Default org alias or username for the org-audit command. Also honoured
// via the VULKRO_SF_LSP_TARGET_ORG environment variable.
"vulkro-sf.targetOrg": "my-scratch-org",
// Trace LSP traffic in the "Vulkro for Salesforce" output channel.
"vulkro-sf.trace.server": "off"
}
vulkro-sf.path is independent of the core vulkro.path, so you can point
it at a local feature branch build while keeping the released vulkro for
non-Salesforce folders.
Inline findings
The vulkro-sf server scans the SFDX project on open and on save, then
publishes diagnostics for the file types it routes:
- Apex (
.cls,.trigger): CRUD/FLS, sharing, SOQL injection, IDOR, mass-assignment, crypto, hardcoded secrets,System.debugof sensitive values, and Well-Architected anti-patterns (SOQL/DML in loops, hardcoded IDs, and so on). - Visualforce (
.page,.component):escape="false"on user content, external script over HTTP, stack-trace disclosure, untrustedPageReferenceconcatenation. - Aura (
.cmp):aura:unescapedHtmlwith user input, Aura action CSRF. - Flow (
.flow-meta.xml): system-context DML, hardcoded record IDs, guest-context flows. - Permission metadata (
.permissionset-meta.xml,.profile-meta.xml): over-privilege and guest-user exposure.
LWC controllers (.js) are scanned by the core vulkro server as
general JavaScript, not by vulkro-sf. Broader org-metadata posture
(connected apps, named credentials, remote sites, SecuritySettings, and the
Agentforce / GenAI surface) is reported by the vulkro-sf CLI on a
whole-project scan; see the CLI docs.
Findings render as VS Code diagnostics with the rule message in the hover
and the Problems panel. The severity-to-colour map matches VS Code defaults:
Critical and High render as Error, Medium as Warning, Low as
Information. Because Critical and High share the Error colour, the
critical and high thresholds behave identically in the editor.
Salesforce commands
Three commands are contributed under the Vulkro for Salesforce prefix (always present in the command palette; outside an SFDX workspace they show an actionable message instead of running):
- Vulkro for Salesforce: Explain finding by rule ID renders the rule's
long-form explainer (the same text as
vulkro-sf explain <RULE-ID>) into the "Vulkro for Salesforce" output channel. - Vulkro for Salesforce: Suppress finding on this line asks the server
for a
// vulkro:disable next-line <RULE>edit and applies it. The server never edits the file itself; it returns the edit and the client flushes it, preserving the read-only-by-design contract. No logic is ever rewritten. - Vulkro for Salesforce: Audit configured target org runs a
permission-posture audit against
vulkro-sf.targetOrg.
The live-org audit
The org-audit command runs entirely through your own authenticated sf
CLI: the extension never implements an OAuth flow, never stores a token,
and never calls a Vulkro server for org data. It reads vulkro-sf.targetOrg
(or VULKRO_SF_LSP_TARGET_ORG) and queries that org via sf.
If sf is not installed or you are not logged in, the command surfaces an
actionable error (run sf org login web, then retry). See
the sf CLI handoff for the full call shape.
What this isn't (yet)
- Not on the marketplaces yet. Install the
.vsixmanually (build it fromeditor-extensions/vscodewithnpm install && npm run package). - No org picker / live status dashboards. The single org command audits
the configured
vulkro-sf.targetOrg; there is nosf org listpicker or packages/status command in the extension today. - No as-you-type diagnostics. Findings refresh on save, not on every keystroke.
Where to go next
- Core extension page: the findings panel, status bar, severity filter, and managed install shared with the general scanner.
- The sf CLI handoff: what happens when the org-audit command fires.
- Methodology: the rule taxonomy the inline findings map to.
- CI/CD integration: the matching pre-merge gate.