Environment variables
Generated from vulkro env --format markdown and vulkro-sf env --format markdown. Run vulkro env [TOPIC] for the same reference for the version you have installed.
vulkro
Network: the offline switch and outbound endpoints
A scan never needs the network. These variables control the few commands and background tasks that do make an outbound call.
VULKRO_OFFLINE: Set to refuse every outbound network call. The global--offlineflag sets it for one run. Under it:vulkro updatewill not fetch the CVE bundle (apply a local one withvulkro update --bundle <path>), the live CVE lookup, the usage heartbeat, the lease refresh and the release version check do not run,login,publish,probe,notify,install-extensionandscan --validate-secretsare refused, andscan --post-tois skipped with a warning. A cloud AI endpoint is refused; a loopback model (http://127.0.0.1, http://localhost) is still allowed. Any value turns offline mode on, including an empty one, except0,false,noandoff(any case), which turn it off and print a one-time warning. The editor extension, the npm wrapper and the install scripts read it the same way.VULKRO_CVE_LIVE: Set to 1 to opt in to the live CVE lookup: each declared dependency's name, version and ecosystem is sent to api.osv.dev to catch advisories published since your local bundle. OFF by default, so nothing about your dependency tree leaves the machine. Transitive (lockfile-only) packages are never sent. Ignored under VULKRO_OFFLINE.VULKRO_NO_UPDATE_CHECK: Any non-empty value skips the release version check thatvulkro updateruns. A scan never contacts the release feed.VULKRO_NO_HEARTBEAT: Any non-empty value disables only the usage heartbeat (and with it the online lease refresh), leaving every other network call untouched. VULKRO_OFFLINE also disables it.VULKRO_HEARTBEAT_URL: Override the heartbeat endpoint. Defaulthttps://api.vulkro.com/v1/heartbeat. For a self-hosted or test server.VULKRO_CDN_BASE_URL: Override the base URLvulkro updatefetches the signed CVE bundle from. Defaulthttps://dist.vulkro.com/cve. The bundle signature is still verified against the keys built into the binary.VULKRO_DNS_REBIND_DOMAIN:vulkro probeonly: a hostname on a DNS server you control that answers a public IP first and 127.0.0.1 second. The probe does not run a rebinding check yet: with it set the report carries a Low informational row saying the probe is set up, and without it a Low row saying the probe was skipped.
Account: vulkro login
VULKRO_ACCOUNT_URL: Override the account / API base thatvulkro loginandvulkro logouttalk to. Defaulthttps://app.vulkro.com/api.VULKRO_ACCOUNT_TOKEN: A CI key created in your account (app.vulkro.com, Settings), for CI and headless machines. Every scanning command signs in with it automatically when no licence is cached on the machine (so CI needs novulkro loginstep), andvulkro loginuses it with no browser and no pasted code. An explicit--codewins over it.VULKRO_LICENSE_B64: The base64 of a.licfile, for air-gapped CI runners: every scanning command verifies it in memory (nothing is written to ~/.vulkro) when no licence is installed. Create it withbase64 < your-key.lic(base64 -w0on Linux).
Vulkro Cloud: vulkro cloud
vulkro cloud uses the connection vulkro cloud connect saved (~/.vulkro/cloud.json). For CI against a company workspace:
VULKRO_CLOUD_URL: The workspace address (https://<slug>.vulkro.com) to use instead of the saved connection. Needs VULKRO_CLOUD_TOKEN, unless it matches the saved workspace.VULKRO_CLOUD_TOKEN: A workspace token (vkws_...) to use instead of the saved one. Needs VULKRO_CLOUD_URL when this machine has no saved connection. Workspace access only: it is not a vulkro licence.
Pro Cloud (vulkro cloud connect --pro) stores no token: each request carries this machine's Vulkro sign-in, or VULKRO_ACCOUNT_TOKEN (see the account topic) when it is set. VULKRO_OFFLINE refuses every cloud command.
Organisation dashboard: vulkro publish
VULKRO_ORG: Default organisation slug forvulkro publishwhen--orgis not given. Unset is fine for a token that belongs to one org.VULKRO_ORG_TOKEN: An account API-key token to publish with. When unset, a machine signed in withvulkro loginpublishes with its device token.VULKRO_ORG_URL: The org server to publish to. Defaulthttps://app.vulkro.com/api. Point it at a self-hosted server.VULKRO_ORG_SCHEMA2: Any non-empty value sends the lighter schema-2 snapshot (counts, category labels and hashed finding ids) instead of the default full-detail schema 3, for a server that only understands schema 2.VULKRO_ORG_SCHEMA1: Any non-empty value sends the original schema-1 snapshot. Wins over VULKRO_ORG_SCHEMA2.VULKRO_ORG_NO_DEPS: Any non-empty value drops the per-package dependency inventory from a schema-2 snapshot, keeping the redacted advisory counts.
vulkro publish --preview prints the exact snapshot and sends nothing. Publishing is refused under VULKRO_OFFLINE.
Scan: output, precision and project context
Boolean switches below accept 1 / true / yes / on to turn on and 0 / false / no / off to turn off, unless the entry says otherwise.
VULKRO_DISABLE_CACHE: Same asscan --no-cache: any value other than empty or 0 bypasses the per-file extraction cache, the git-history cache and the code-graph cache (code-graph, assess-change, from-trace).VULKRO_TIMINGS: Same asscan --timings: any value other than empty or 0 records per-pass wall-clock times instats.pass_timings. Changes no finding and no exit code.VULKRO_SCAN_BUDGET_SECS: Wall-clock ceiling for the detector passes, in seconds (whole or fractional). Unset or 0 means unlimited (the default). Checked at pass boundaries only: once reached, the remaining passes are skipped, named indegraded_passes, and a partial-results line is added towarnings. Exit codes are unchanged.VULKRO_DETERMINISTIC: Set to 1 to pinscanned_at(the output's only clock field) so the full JSON is byte-reproducible run to run;scan --no-timestampsets it for one run. SOURCE_DATE_EPOCH (integer seconds) also pins it, to that instant. Ids and ordering are always deterministic.VULKRO_GIT_COMMIT: The full commit SHA (40 or 64 hex characters) to report as the scanned revision in thegitobject of--format json, the NDJSON summary line and SARIFversionControlProvenance, in place of HEAD. For a CI runner or container whose checkout has no.git. Any other value is ignored with a warning and HEAD is read.VULKRO_GIT_BRANCH: The branch name to report in the same places, in place of the checked-out branch (a shallow clone is often on a detached HEAD, which reportsbranch: null). A leadingrefs/heads/is removed.VULKRO_QUIET_PRESET_HINT: Set to 1 to silence the one-time hint a barevulkro scan [path]prints when no preset is named.VULKRO_STRICT_CONFIDENCE: Set to 1 for the same effect asscan --strict-confidence: High findings with an empty evidence bag are filtered out.VULKRO_STRICT_PROOF: The strict-proof tier, ON by default. A Medium finding that rests only on heuristic signals (no dataflow, secret-format or reachability proof) is shown at Low, outside the default view and--fail-on, and still visible under--all-confidence. Set to 0 to restore the fuller default view.VULKRO_STRICT_ADMISSION: The high-tier admission gate, ON by default. A Critical or High finding keeps its severity only when its disposition isadmitted(a proven source-to-sink trace, a value-verified secret, an advisory-proven dependency hit, or a dispositive injection shape); every other one is capped at Medium, which takes it out of--fail-on critical,highwhile leaving it fully reported. Set to 0 to restore the pre-gate view and exit codes.VULKRO_ABSENCE_AUTHZ: ON by default. Authorization findings that fire only because no guard was visible in the lines the rule read are reported at Low confidence (out of the default view and--fail-on). A finding of that family with a real source-to-sink trace keeps its tier. Set to 0 to restore the previous default view.VULKRO_NO_SUPPRESS: Set to 1 to ignore// vulkro:disablesource annotations, so a CI lane can see what would normally be suppressed.VULKRO_NO_FOLD: Set to 1 to turn off the one-issue-per-root-cause fold: every engine's report of one bug is listed as its own row again. By default rows of the same vulnerability family within two lines of one sink in one file fold into the strongest row, which lists the others underalso_reported_by.VULKRO_GIT_BLAME: Set to 1 to fill each finding'sownerfromgit blameof the offending line. Off by default because it can add tens of seconds on a large repository (bounded at 30 seconds).VULKRO_AUTH_MIDDLEWARE_NAMES: Comma-separated names of project-specific auth middleware to recognise as a route guard, added to the built-in list and toauth_middleware_namesinvulkro.toml. Applies to Node.js / TypeScript and Go routes (Go: a per-route middleware argument, a.Use(...)call or a router-group guard). Only identifier characters are accepted; other names are skipped.vulkro config show-patternslists the result.VULKRO_SCAN_VENDORED: Set to exactly 1 to scan vendored, minified and generated files that the security passes skip by default.VULKRO_NO_FRONTEND_SCAN: Set to 1 to skip the frontend check subset over JavaScript / TypeScript files that were not registered as modules.VULKRO_MAX_AST_FILE_BYTES: Files larger than this many bytes are skipped by the syntax-tree security passes. Default 1500000; 0 disables the cap.VULKRO_MAX_AST_FILE_LINES: Files longer than this many lines are skipped by the syntax-tree security passes. Default 8000; 0 disables the cap.VULKRO_PARSE_CACHE_MAX_BYTES: Cap, in source bytes, on the per-scan parse cache (default 67108864, 64 MiB). A file past the cap is parsed again when a pass needs it, so findings are the same whatever the value; lowering it trades speed for memory.VULKRO_DISABLE_PARALLEL_DISPATCH: Set to 1 or true to run the independent detector passes one after another instead of in parallel. The output is identical either way; unset (parallel) is faster.VULKRO_NEXTJS_FULL_MODULES: Set to 1 to register every file of a Next.js project with all detectors. By default only route-shaped files and the server files they import are registered. Off by default: on three real apps the extra High and Critical rows were about 6% true positives, and it roughly doubles scan time.VULKRO_DIFF_ONLY_REF: Same asscan --diff-only <ref>(the flag sets it): only files that differ from this git ref are scanned. When nothing differs or git fails, the whole project is scanned.VULKRO_VERIFIED_REQUIRES_PROOF: OFF by default. Set to 1 to reserve the topVerifiedconfidence tier for findings with a machine-checkable proof (a taint trace hop or theadmitteddisposition). By default an auth finding on an unprotected route whose handler reads user input is also promoted toVerified.VULKRO_AUTOFIX_WIDE: Set to 1 to widen the one-clicksuggestionblocks of--format gh-pr-inlinefrom the four read-only fix classes to the full deterministic fix catalogue. A widened suggestion is emitted only for anadmittedfinding whose rewrite a re-scan confirms clears it. Off by default.VULKRO_DEBUG: Any value, even an empty one, prints the project cache fingerprint in the scan progress log, notes Helm templates too complex to render, and keeps full webhook URLs in--post-toerror messages instead of redacting them. Leave it unset in shared CI logs.VULKRO_LEGACY_UNCONFIRMED_TAINT: DEPRECATED, removed in the next release. Any non-empty value lets an injection finding whose taint check failed be promoted back into the default view (and so into--fail-on), as before 0.22. Only for keeping a pipeline's exit code stable while you re-baseline; a scan with it set prints a deprecation warning.VULKRO_LEGACY_TIER: DEPRECATED, removed in the next release. Any non-empty value lets a finding in a test, example, fixture, migration, generated, doc, dev-tool or framework-internal file stay Critical or High (it is otherwise capped at Medium). A scan with it set prints a deprecation warning.
Dependency CVEs (SCA):
VULKRO_SCA_DEV_DEP_DEMOTE: ON by default. A CVE in a package declared only as a development dependency (and never as a production one in any manifest) is held at Low confidence, so it leaves the default view and--fail-on critical,high; it stays in JSON and SARIF, tagged(dev dependency). Set to 0 to keep such CVEs at full confidence.VULKRO_SCA_NO_TRANSITIVE: Set to 1 to report only the dependencies your manifests declare. By default every package in the lockfiles is matched against the local CVE bundle and hits no manifest declares are reported at Medium confidence, marked(transitive dependency).VULKRO_SCA_REACHABLE: ON by default. Labels each dependency CVEreachableorunreachablewith the entry-point call chain as evidence; the label never changes severity (use--fail-on-reachable-onlyto act on it). Set to 0 to skip the labelling; set to 1 to also downgrade first-party taint findings whose sink no entry point reaches.VULKRO_INSPECT_DEPS: Set to 1 to inspect the installed source of the npm dependencies your reachable code imports (node_modules/<pkg>, top level only) for compromised-package payloads (time-bomb gates and download-and-run loaders). Off by default; npm only.
vulkro gate and vulkro review:
VULKRO_GATE_BASE: Default base ref forvulkro gatewhen--baseis not given, so a CI lane sets it once (VULKRO_GATE_BASE=origin/main).VULKRO_GATE_SEVERITY_ONLY: Compatibility switch, off by default. Anot-examinedfinding is normally reported but never failsscan --fail-on,vulkro gate,vulkro review --fail-onor the MCP gate. Set to 1 to let severity alone decide again; it also turns VULKRO_ABSENCE_AUTHZ off and restores the previousvulkro guard checkverdict.VULKRO_REVIEW_CONTEXT: Default number of diff context linesvulkro reviewshows around each change (default 3).--contextwins over it.
Engine: opt-in analysis depth
Call-graph and taint switches. Each one that is OFF by default can add findings when turned on. Set to 1 / true / yes / on to turn on.
VULKRO_GO_SAMEPKG_EDGES: ON by default (since Wave 5; set to 0 to opt out). Go same-package call-graph edges: an unqualified callfoo()can bind to a top-levelfunc fooin a sibling file of the same directory andpackageclause (free functions only, never across packages). Measured: no finding changed on the Go corpora, the reachable closure grew on every Go repository.VULKRO_CODEGRAPH_LADDER: Call-graph half ON by default (since Wave 5; set to 0 to opt out): a parameter's declared type (p: T,p T,T p) bindsp.method()to T's method. Set to 1 to also turn on co-located test linking invulkro assess(still opt-in).VULKRO_XPKG_GO: OFF by default. Strips thego.modmodule prefix off qualified Go imports so a cross-package import resolves to the in-repo package and taint can follow it across the package boundary. Kept off: in the Wave 5 A/B it added a Critical lookalike on the Go ground-truth app and no true positive.VULKRO_XPKG_JVM: OFF by default. Java cross-file call-graph edges: import and same-package resolution of method calls, bound only to a unique declaring class. Wave 5: no finding changed on the Java corpora and reachability grew; kept off until the Java advisory replay is measured with it on.VULKRO_JS_RECEIVER_RESOLVE: OFF by default. Receiver-typed callee resolution for JavaScript and TypeScript taint: a method call on a never-reassignednew Foo()local, where Foo is a project class nothing extends, binds to that class's method instead of every same-named one. Kept off: in the Wave 5 A/B it added 26 Critical/High rows on the precision repos, all sampled ones false positives.VULKRO_REACHABILITY_CLOSURE: ON by default. The reachability-closure repair, which makes framework route handlers call-graph nodes so the forward closure from entry points is complete. Set to 0 / false / no / off to opt out.VULKRO_XPKG_JS_EXPORTS: ON by default (set to 0 to opt out). Resolves a JS / TypeScript workspace-package import (@scope/pkgin a pnpm, turbo or nx monorepo) through the package'spackage.jsonexports,moduleormain, so taint and reachability cross the package boundary. Binds only to an in-project source file, nevernode_modules.VULKRO_DISABLE_INTERPROC_TAINT: Set to 1 to skip the cross-file taint pass, the call-graph build and its propagation; they are named indegraded_passes. Off by default.VULKRO_INTERPROC_TAINT_MAX_MODULES: Above this many modules the cross-file taint pass is skipped automatically, with a progress note naming this variable. Default 6000; 0 turns the automatic skip off.
Taint precision in the proof-carrying engines:
VULKRO_TAINT_FLOW_ORDER: ON by default (set to 0 to opt out). JS/TS, Python, Go and Java: a trace is kept only when the assignment that taints the value sits above the sink, except in the same loop body or across a closure, where text order says nothing about run order.VULKRO_TAINT_VALUE_DEFUSE: OFF by default. JS/TS: a local carries taint only when its assigned value preserves it (concatenation, interpolation, property read, spread, ternary). A value-destroying call (sha1(...),parseInt,.length) clears it; a reshape (.toString(),JSON.parse,atob) passes it through.VULKRO_TAINT_CALLBACK_PARAM: OFF by default. JS/TS: the first parameter of a.map,.forEach,.filter,.flatMap,.find,.someor.everycallback inherits the receiver's taint. Kept off because the name stays bound for the whole enclosing function, so a reused short name can report a flow that does not exist.VULKRO_TAINT_RESOLVED_BIND: OFF by default. JS/TS: pins an ambiguous cross-file callee with the type-aware call-graph resolver before the by-name fallback, and treats a local assigned from a helper proven to return a constant as clean. Measured neutral, so kept opt-in.VULKRO_TAINT_SANITIZER_SUMMARY: OFF by default. Go: a project helper that validates or encodes its parameter before every return, or is marked// vulkro: sanitizer, counts as a sanitizer.VULKRO_TAINT_VALUE_SCOPED_SANITIZER: OFF by default. Go: a cross-method sanitizer clears only the variable it was applied to, not an unrelated field on the same call edge.VULKRO_TAINT_GO_BODY_BIND: ON by default (set to 0 to opt out). Go: a request body bound into a struct (c.ShouldBindJSON(&req),c.Bind, fiberBodyParser,json.NewDecoder(r.Body).Decode) is a taint source.VULKRO_GO_FIELD_TAINT: ON by default (set to 0 to opt out). Go: a keyed struct literal taints only the field built from tainted data, aurl.URLis a redirect or SSRF target only when a destination field is tainted, and a statement spanning several lines is read whole.VULKRO_TAINT_GO_ERR_WASH: ON by default (set to 0 to opt out). Go:err = f(tainted)does not tainterr; an error built from the value (fmt.Errorf,errors.New,errors.Wrap) still does.VULKRO_TAINT_GO_REDIRECT_CONFIG: ON by default (set to 0 to opt out). Go: a redirect to a configuration URL getter, optionally with a new path or query, is not reported as an open redirect.VULKRO_TAINT_GO_SCALAR_PARAM: ON by default (set to 0 to opt out). Go: taint does not flow into a parameter declared as a number,boolortime.Duration;byte,rune,int8,uint8andint32stay tainted.
Data-layer SQL sinks:
VULKRO_TAINT_P7_QB_IDENT: ON by default (set to 0 to opt out). A tainted value in an SQL identifier slot (ORDER BY / GROUP BY column, table name) of a JS/TS, Python or Go query builder is reported, always at Low severity and confidence, so it stays out of the default view.VULKRO_TAINT_P7_HEURISTIC_SQL_GATE: ON by default (set to 0 to opt out). Clears a heuristic INJ-001 store-then-execute finding only when the call is provably parameterised (bound parameters and placeholder-only query text).VULKRO_TAINT_P7_ORM_RAW_ESCAPE: OFF by default. JS/TS: also treatssql.unsafe,sql.litandSequelize.literalas raw-SQL sinks.VULKRO_TAINT_P7_RECEIVER_NAMES: OFF by default. JS/TS: also treats a handle namedinstanceas an SQL handle.VULKRO_TAINT_P7_PY_RAW: OFF by default. Python: Djangoobjects.raw,.extraandRawSQL,cursor.executescriptandconn.execute/.fetch/.fetchval/.fetchroware SQL sinks, behind the parameterisation gate.VULKRO_TAINT_P7_JVGO_RAW: OFF by default. JavaJdbcTemplate.update/queryForStreamand jOOQresultQuery/fetch, and Go sqlxQueryx/QueryRowx/NamedExec/NamedQuery/MustExec, are SQL sinks, behind each engine's parameterisation gate.
Bruteforce sinks (scan --bruteforce-sinks; Python and JS/TS):
VULKRO_BRUTEFORCE_SINKS: Set to exactly 1 to run the bruteforce-sinks pass: every critical call site is driven against an adversarial payload corpus and a payload that reaches the sink with no recognised guard is reported. The flag sets it;vulkro lsphonours it too. Off by default and slower.VULKRO_BRUTEFORCE_CATEGORIES: Comma-separated sink categories to check: sql, shell, http, payment, llm, file-write, deserialization, email. Unset means all.--bruteforce-categoriessets it.VULKRO_BRUTEFORCE_PAYLOAD_CLASSES: Comma-separated payload classes: type-confusion, numeric, size, unicode, injection, path-traversal, prompt-injection, payment. Unset means all.--bruteforce-payload-classessets it.VULKRO_BRUTEFORCE_CONFIDENCE: Lowest confidence reported: high (the default), medium or low.vulkro scanalways sets it from--bruteforce-confidence, so the variable matters only for scans started another way, such as by the language server.VULKRO_BRUTEFORCE_DEPTH: Maximum expansion depth per function. Default 6, clamped to [2, 12].VULKRO_BRUTEFORCE_PATHS_PER_FN: Maximum paths walked per function. Default 64, clamped to [8, 512].
Console and local store: vulkro serve
VULKRO_SERVE_TOKEN: The console access token to require instead of the random one each start generates. It is not printed; scripts send it asAuthorization: Bearer <token>. Shared withvulkro-sf serve. A blank value is ignored.VULKRO_SERVE_ALLOWED_HOSTS: Comma-separated extra host names the console answers to, and whoseOriginit accepts, for a console behind a reverse proxy that rewritesHost(for examplevulkro.internal:8723).VULKRO_DB: Full path of the local SQLite store, instead of~/.vulkro/scans.db. One file holds the per-file cache, the scan history and trend snapshots, and local licence state, so this moves all of them together. The parent directory is created if missing.
Notifications: scan --post-to
--post-to integrations (Slack / Teams / Jira / PagerDuty) read their secrets from environment variables so credentials never land in shell history. A value missing from both the flag and the environment falls back to ~/.vulkro/notify.json (--post-to saved posts to every destination saved there). Notification failures are non-fatal: the scan exit code is unchanged and a warning is printed to stderr. Skipped under VULKRO_OFFLINE. --post-to is a Pro capability (notify).
VULKRO_SLACK_WEBHOOK: Slack incoming-webhook URL, used by--post-to slack. A URL passed inline as--post-to slack=<url>wins over it.VULKRO_TEAMS_WEBHOOK: MS Teams Adaptive Card webhook URL, used by--post-to teams. A URL passed inline as--post-to teams=<url>wins over it.VULKRO_JIRA_BASE_URL: Jira Cloud base for--post-to jira=<PROJECT_KEY>, for examplehttps://acme.atlassian.net. One issue per Critical finding.VULKRO_JIRA_EMAIL: Atlassian account email for basic auth.VULKRO_JIRA_TOKEN: Atlassian API token for basic auth.VULKRO_PD_ROUTING_KEY: PagerDuty Events API v2 routing key for--post-to pagerduty. One incident when at least one Critical is present.VULKRO_NOTIFY_RETRIES: Attempts per integration (default 3, clamped to [1, 5]), with backoff of 250ms, 1s, 4s, 10s, 20s between attempts. 1 disables retry.
AI: optional model for triage and fixes
Resolution order: the per-run flags (--ai-model, --ai-url, --no-ai), then these variables, then the selection saved by vulkro ai use, then the local default (Ollama at http://127.0.0.1:11434/v1). A blank value counts as unset.
VULKRO_AI_MODEL: Model tag to use, for exampleqwen2.5-coder:7b.VULKRO_AI_URL: OpenAI-compatible base URL. A loopback URL is a local model; any other URL is a cloud endpoint and is refused under VULKRO_OFFLINE.VULKRO_AI_KEY: API key sent to a cloud endpoint. Ignored for a local URL and never saved to disk.VULKRO_AI_ENDPOINT_CLASS: Set tocloudto treat the AI endpoint as cloud even when its URL is loopback, so VULKRO_OFFLINE refuses it. For a local relay that forwards to a cloud model (the editor extension's editor-AI option sets it; so should a LiteLLM-style proxy). Onlycloudis honoured: nothing can make a remote URL count as local.VULKRO_TRIAGE_API_KEY: Older name for the keyvulkro triagesends to an Anthropic cloud URL. Used only when no AI key (VULKRO_AI_KEY) is set; ANTHROPIC_API_KEY is the last fallback.
Editor, language server and MCP
VULKRO_LSP_LOG: Any value other than empty or 0 writes per-message trace lines fromvulkro lspto stderr. Off by default so the stdio JSON-RPC channel stays clean.VULKRO_LSP_DEBOUNCE_MS: ThetextDocument/didChangedebounce window forvulkro lsp, in milliseconds. Default 300, clamped to [50, 5000]; a value that does not parse falls back to 300.VULKRO_LSP_INCREMENTAL: Incremental save is the default: a save re-analyses only the saved file and reuses the cached findings for the rest, falling back to a full rescan when the file is part of a cross-file finding. Set to 0 / false / no / off to rescan the whole project on every save instead. The old opt-in value 1 still works and prints a note that it is no longer needed.VULKRO_MCP_LOG: Any value other than empty or 0 writes per-request trace lines fromvulkro mcp serveto stderr. Off by default.VULKRO_VSIX_URL: Full URL of the .vsix thatvulkro install-extensiondownloads, instead of the Vulkro CDN (a self-hosted mirror). Still refused under VULKRO_OFFLINE; use--vsix <file>for an air-gapped machine.VULKRO_PQ_AUDIT: Set to exactly 1 to add the post-quantum crypto audit pass to the scansvulkro lspruns (slower). The editor's deep-scan setting sets it.
Scans started by the language server and the MCP server honour the scan and engine variables (vulkro env scan, vulkro env engine) in the same way, including VULKRO_BRUTEFORCE_SINKS.
Git hooks: vulkro install-hook
VULKRO_SKIP_HOOKS: Set to exactly 1 to bypass the pre-commit and pre-push hooks thatvulkro install-hookwrites, for one commit or push.VULKRO_SKIP_PRECOMMIT: Set to exactly 1 to bypass the pre-commit hook that the deprecatedvulkro initwrites, for one commit.VULKRO_GIT_HOOK: Exported by those hooks (set to the hook name) so the command a hook runs knows it is inside a git hook. Not something you set yourself.
Custom rules and rule packs
VULKRO_RULES: Path to a YAML custom-rule file to load in place ofvulkro-rules.yaml(or.yml) at the project root. Used only when the file exists.VULKRO_RULES_REGISTRY_URL: Override the rule-pack registry index thatvulkro rulesfetches (list, update, adding a pack). Defaulthttps://dist.vulkro.com/rules/index.json. For a mirror or proxy.
vulkro-sf
Scan: detector switches and project context
VULKRO_SCA_DEV_DEP_DEMOTE: Development-only npm dependencies (build, test and lint tooling that is never deployed to the org) are held back: their CVEs are left out of the table, JSON and SARIF, and the table says how many. ON by default;0/false/no/offlists them at full confidence, and--min-confidence lowlists them as the Low-confidence rows they are. A package any lockfile installs for production is never held back.VULKRO_APEX_ASYNC_TAINT: Which Apex constructors become call-graph nodes, so a tainted value handed tonew SomeJob(x)and enqueued reaches the sink in that class'sexecute(). ON by default (since 2026-09-22) in the narrow mode: unset or any value other than the two below = only classes implementing Queueable / Database.Batchable / Schedulable.0/false/no/off= OFF (the previous behaviour);all= every constructor (the wide arm). Turned on after an A/B on the labelled corpus moved zero findings (recall 42/42, no false-positive file added); the mechanism is verified end-to-end onbench/fixtures/apex_async_ctor_taint.VULKRO_APEX_RECEIVER_RESOLVE: Binds each Apex call to the methods the project's declared types can reach (enclosing class chain, typed receivers,new T(), return types, interface / virtual subtypes) instead of every same-named method. Ambiguous calls still carry taint but are reported as unproven. ON by default;0/false/no/offrestores name-only resolution.VULKRO_APEX_EFFECTIVE_MODE: Judges Apex record-access findings (CRUD/FLS, IDOR, sharing bypass, agent FLS) by the sharing context and access mode each data operation actually runs in: the class keyword inherited down the call stack and theextendschain, the API 67.0 user-mode default, andas system/WITH SYSTEM_MODEper operation. A batch or@futurebody is its own entry point unless a request value is passed into it. ON by default;0/false/no/offrestores the previous per-class verdicts.VULKRO_SF_OAUTH_TAKEOVER_ANY_BROAD: Set to 1 to let ANY broad OAuth scope (including a bareapi) qualify a ConnectedApp for the High org-takeover composite (SF-OAUTH-SCOPE-007). By default only afullscope does:apiis still bounded by the authorising user's own permissions, so it is reported as over-broad (Medium) instead.VULKRO_SF_GATE_BASE: Default base ref. Overridden by--gate-vs. Lets a CI lane set the comparison once (VULKRO_SF_GATE_BASE=origin/main). Setting it turns on the diff-scoped gate, which is Pro.VULKRO_GIT_HOOK: Exported by the pre-commit hookvulkro-sf initwrites, to mark a run started by a git hook (see above). Not something you set yourself.VULKRO_SF_ORG_CONTEXT: Path to a Salesforce org-context file (vulkro.sf-org-context/v1: active holders per profile / permission set, object access, feature licences, component origin). Overrides<project>/.vulkro/org-context.json. With it, grants nobody holds are reported as latent (Low), paid add-on advice (Shield, Field Audit Trail) only fires when licensed, and Salesforce-shipped components are Info. Without it, findings that need an org fact are tagged org-unverified. A malformed file is reported once and ignored.VULKRO_SF_HYGIENE: Set to 1 to opt in to the metadata-hygiene detectors: duplicate custom labels, duplicate / case-colliding custom fields, and candidate-unused permission sets. These are informational code-quality findings (Severity Low), off by default so a standard scan stays focused on security. The unused-permset check is a CANDIDATE only: static source cannot see direct user / profile assignments, so verify live-org assignments before deleting a flagged permission set.VULKRO_SF_GOVERNANCE_FILE: Path to the metadata-governance config (owner / deprecated / review-by conventions). Absolute, or relative to the project root. Defaults to.vulkro-sf/metadata-governance.yaml. When the config is present the deterministic governance pass runs (SF-META-GOV-001 missing owner, SF-META-GOV-002 overdue review, SF-META-GOV-003 deprecated-but-referenced); when it is absent the pass is a no-op.
Notifications: scan --post-to
--post-to integrations (Slack / Teams / Jira / PagerDuty) each read secrets from environment variables so credentials never land on the shell history. Set the variables before running the command (or before the CI job starts). Notification failures are non-fatal: the scan still exits 1 on findings and a warning is printed to stderr.
VULKRO_SF_SLACK_WEBHOOK: Slack incoming-webhook URL. A URL passed inline as--post-to slack=<url>wins over it.VULKRO_SF_TEAMS_WEBHOOK: MS Teams Adaptive Card webhook URL. A URL passed inline as--post-to teams=<url>wins over it.VULKRO_SF_JIRA_BASE_URL: Jira Cloud base, e.g.https://acme.atlassian.net.VULKRO_SF_JIRA_EMAIL: Atlassian account email for basic auth.VULKRO_SF_JIRA_TOKEN: Atlassian API token for basic auth.VULKRO_SF_PD_ROUTING_KEY: PagerDuty Events API v2 routing key.
Every value falls back to the console's saved notification settings (~/.vulkro/sf-notify.json, Settings > Notifications in vulkro-sf serve) when neither the flag nor the variable gives it; --post-to saved posts to every saved target.
VULKRO_SF_NOTIFY_RETRIES: Notification dispatch retry budget (default 3, clamped to [1, 5]). Backoff[250ms, 1s, 4s, 10s, 20s]between attempts; 1 disables retry.VULKRO_SF_DEBUG: Any value, even an empty one, keeps full webhook URLs in--post-toerror messages instead of redacting them, to debug a mistyped Slack / Teams URL. Leave it unset in shared CI logs.
Apex taint engine and detector thresholds
VULKRO_APEX_BRACE_WALK: ON by default (set to 0 to opt out). The Apex local-taint walk descends into for / if / while / try bodies and binds for-each loop variables (including over Trigger.new / Trigger.old), so a dynamic SOQL or DML sink fed inside a loop or guard block is traced.VULKRO_TAINT_LOCAL_ALIAS: ON by default (set to 0 to opt out). A plain local copy of a tainted parameter (String q = p; helper(q);) carries the taint across the call, on resolved calls only.VULKRO_APEX_TAINT_DEPTH: Interprocedural Apex taint call depth. Default 5, clamped to [1, 12]. Raise it (for example 8) for deep Controller / Service / Selector stacks; the scan's coverage note says when a flow hit the limit.VULKRO_APEX_STORED_TAINT: Set to 1 to opt in to coarse second-order (stored) Apex taint: a High stored SOQL injection when a guest-reachable write stores input on a field and a later dynamic query selects that field. Off by default (high false-positive risk).VULKRO_SF_GUEST_EXPLOIT: Set to 1 to add the fused SF-GUEST-EXPLOITABLE finding toscan: a guest-reachable Apex entry point joined with a proven dataflow or CRUD/FLS finding on the same class. With--org, the org's live guest grants and record counts are used. Off by default.VULKRO_SF_API_VERSION_FLOOR: Integer API version below which a*-meta.xmlcomponent is flagged end-of-life (SF-THREAT-API-EOL-001: High when retired, below 21; Medium when deprecated). Default 31; a non-numeric value falls back to the default.VULKRO_SF_FLS_USER_BROAD_BAR: Per-user field-level-security audit (needs User and PermissionSetAssignment exports under the scan path): a sensitive field readable (SF-FLS-USER-001) or editable (SF-FLS-USER-002) by more than this many users is flagged. Default 5; a malformed or non-positive value falls back to the default.VULKRO_SF_RECERT_STALE_DAYS:vulkro-sf recert: days without a login after which an active user is flagged as a dormant live credential. Default 90; a malformed or non-positive value falls back to the default.
External tools: the platform's own Apex analyzer, ESLint and RetireJS
VULKRO_PMD_BIN: Absolute path to thepmdbinary forscan --include-pmd. Wins over the firstpmdon PATH; a set path that is not a file is an error. An empty value searches PATH.VULKRO_ESLINT_BIN: Path to theeslintbinary forscan --include-eslint, used as given. Unset or empty:eslinton PATH, thennpx eslint.VULKRO_RETIREJS_BIN: Full path to aretirebinary forscan --include-retirejs. A set path that does not exist is an error. Unset or empty:retireon PATH, thennpx retire.
Custom rules and the rule marketplace
VULKRO_SF_CUSTOM_RULES_DIR: When set, the custom-rule loader reads ONLY this directory and skips both.vulkro-sf/rules/(project) and~/.vulkro/rules/(user). Useful in CI to test a rule pack in isolation.VULKRO_SF_MARKETPLACE_BUNDLE_OVERRIDE: When set,rules marketplacereads ONLY this gzipped JSON bundle instead of the built-in one. For testing a bundle in CI or sideloading on an air-gapped host.VULKRO_SF_MARKETPLACE_INSTALL_DIR: When set,rules marketplace install/uninstalluse this directory instead of~/.vulkro/rules/.VULKRO_RULES_DIR: The per-user rule directory the console's Rules tab lists and installs marketplace rules into, instead of~/.vulkro/rules/.
Threat-intel bundles: sca, org audits, trust status
VULKRO_SF_INTEL_BUNDLE_OVERRIDE: Path to your own gzipped JSON managed-package advisory bundle forvulkro-sf sca. None ships, so without it SF-SCA-001 (vulnerable package) and SF-SCA-002 (end-of-life package) are reported as not checked.VULKRO_SF_INTEL_TRUST_BUNDLE_OVERRIDE: Path to your own trust.salesforce.com incident snapshot, fororg trust-status(gzipped JSON) and the console's Trust Status tab (plain JSON). None ships: without it the command exits 2 and the tab says no intel is loaded; neither reports the org as clear.VULKRO_SF_APT_PLAYBOOKS: Any value other than empty or 0 is the same asorg audit-trail --check-apt-playbooks: the SetupAuditTrail and AuthSession timeline is also matched against the APT playbooks.VULKRO_SF_INTEL_APT_BUNDLE_OVERRIDE: Path to a local gzipped JSON APT playbook bundle to use instead of the cached or built-in one (an air-gapped sideload).VULKRO_SF_INTEL_COMPROMISED: Any value other than empty or 0 is the same asorg connected-apps --check-compromised. No compromised client-ID list ships and that command does not read consumer keys, so it only prints that the check did not run.VULKRO_SF_INTEL_COMPROMISED_BUNDLE_OVERRIDE: Path to your own gzipped JSON list of compromised OAuth client IDs, which the console (vulkro-sf serve) matches Connected Apps against. None ships.
Event Monitoring: org event-monitoring and logs analyze
The lookback window of the live-org audit, then the thresholds of the behavioural rules vulkro-sf logs analyze runs. Each falls back to its default when unset or unparseable.
VULKRO_SF_EVENT_MON_SINCE_DAYS: Lookback window in days fororg event-monitoring(default 7).--since-dayswins over it.VULKRO_SF_EVENT_MON_ANOMALY_ZSCORE: Z-score outlier bar for SF-EVENT-MON-ANOMALY-001 (default 3.0). A non-positive value is ignored.VULKRO_SF_EVENT_MON_ANOMALY_PEER_RATIO: Peer-median ratio bar for the same rule (default 10.0): the outlier's volume must be at least this many times the peer median. A value below 1.0 is ignored.VULKRO_SF_EVENT_MON_REPORT_RUN_COUNT: SF-EVENT-MON-010: a user running more than this many Report / Dashboard / ReportExport events in the window is flagged (default 50). A non-positive value is ignored.VULKRO_SF_EVENT_MON_REPORT_EXPORT_ROWS: SF-EVENT-MON-010: a user exporting more than this many report rows in total is flagged (default 100000). A non-positive value is ignored.VULKRO_SF_EVENT_MON_IMPOSSIBLE_TRAVEL_MINUTES: SF-EVENT-MON-011: two successful logins from different IPs inside this many minutes are flagged (default 15). A non-positive value is ignored.VULKRO_SF_EVENT_MON_DEVICE_FP_WINDOW_MINUTES: SF-SESSION-FP-001: window in minutes that groups one user's successful logins (default 60). A non-positive value is ignored.VULKRO_SF_EVENT_MON_DEVICE_FP_COUNT: SF-SESSION-FP-001: more than this many distinct browser and platform fingerprints for one user inside the window is flagged (default 3). A non-positive value is ignored.VULKRO_SF_EVENT_MON_ADV_EXFIL_RATIO: SF-EVENT-MON-013: a query whose SOQL complexity score is at least this many times the user's own baseline median is flagged (default 8.0). A value below 1.0 is ignored.VULKRO_SF_EVENT_MON_GRANT_VELOCITY_COUNT: SF-EVENT-MON-015: more than this many dangerous grants by one actor inside the velocity window is a burst (default 3). A non-positive value is ignored.VULKRO_SF_EVENT_MON_GRANT_VELOCITY_MINUTES: SF-EVENT-MON-015: the velocity window in minutes (default 30). A non-positive value is ignored.VULKRO_SF_EVENT_MON_API_ABUSE_SCORE: SF-EVENT-MON-017: a user whose blended request-rate, session and token-reuse score crosses this bar is flagged (default 1000). A non-positive value is ignored.
Quality gate: vulkro-sf quality --gate
Each overrides the matching key in .vulkro-sf/quality-gates.yaml; an unparseable value is ignored.
VULKRO_SF_QUALITY_GATE_MAX_COMPLEXITY: Fail if any Apex method's cyclomatic complexity exceeds this integer.VULKRO_SF_QUALITY_GATE_MIN_COVERAGE: Fail if overall test coverage is below this percent (0 to 100, decimals allowed).VULKRO_SF_QUALITY_GATE_MAX_FINDINGS: Fail if the total finding count exceeds this integer.VULKRO_SF_QUALITY_GATE_MIN_GOVERNANCE: Fail if the governance score (0 to 100) is below this integer.VULKRO_SF_QUALITY_GATE_MAX_CLASS_LINES: Fail if any Apex class has more source lines than this integer.VULKRO_SF_QUALITY_GATE_MAX_METHODS: Fail if any Apex class declares more methods than this integer.
Console: vulkro-sf serve
The console requires an access token, like vulkro serve: each start mints a random one and prints the console URL with it. A request without the token gets HTTP 401; one from another web page gets HTTP 403.
VULKRO_SERVE_TOKEN: The access token to require instead of a generated one (shared withvulkro serve). It is not printed; scripts send it asAuthorization: Bearer <token>. Required for any non-loopback bind.VULKRO_SERVE_ALLOWED_HOSTS: Comma-separated hosts whoseOriginthe console also accepts, for a console behind a reverse proxy that rewritesHost(shared withvulkro serve).VULKRO_SF_BIND: Bind address. Default 127.0.0.1. A non-loopback address such as 0.0.0.0 is refused unless VULKRO_SERVE_TOKEN is set.VULKRO_SF_PORT: Listen port.--portwins over it; unset or unparseable lets the OS pick a free port, which the console prints.VULKRO_SF_DATA_DIR: Data directory (the console's SQLite store and on-disk state, and thequality-history.jsonlthatqualityappends to andtrendsreads). Default~/.vulkro-sf/data/, else./.vulkro-sf/data/.VULKRO_SF_ENGAGEMENTS_DIR: Root of the consultancy engagement folders the console's engagement dashboard reads, instead of~/.vulkro/engagements/.
Language server and MCP
VULKRO_SF_LSP_LOG: Any value other than empty or 0 writes per-message trace lines fromvulkro-sf lspto stderr.VULKRO_SF_LSP_TARGET_ORG: Default target org (alias) for thevulkro-sf.scan-orgcommand when the editor does not passinitializationOptions.targetOrg.VULKRO_SF_LSP_DEBOUNCE_MS:textDocument/didChangedebounce window in milliseconds. Default 300, clamped to [50, 5000]; an unparseable value falls back to 300.VULKRO_SF_MCP_LOG: Any value other than empty or 0 writes per-request trace lines fromvulkro-sf mcp serveto stderr. Off by default so the stdio JSON-RPC stream stays clean.
Hooks, review, attest and the antipatterns cache
VULKRO_SF_SKIP_PRECOMMIT: Set to exactly 1 to bypass the pre-commit hookvulkro-sf init --pre-commitwrites, for one commit.VULKRO_REVIEW_CONTEXT: Default number of diff context linesvulkro-sf reviewshows around each change (default 3).--contextwins over it.VULKRO_SF_ATTESTER: Identitycompliance attestrecords when--submitteris not given. Falls back tounknown.VULKRO_SF_NO_CACHE: Any value, even an empty one, bypasses the per-file detector cache ofvulkro-sf antipatterns(same as--no-cache).VULKRO_SF_CACHE_DIR: Directory for that cache (sf-antipattern-cache.json) instead of~/.vulkro/(same as--cache-dir).
Detector legacy gates
Detector legacy gates (one-release fallbacks after cross-method taint-engine migrations; default OFF):
VULKRO_SF_AP018_LEGACY: re-enable the legacy intra-file AP-018.VULKRO_SF_AP024_LEGACY: re-enable the legacy intra-file AP-024 (partial-success DML without SaveResult inspection).VULKRO_SF_AP042_LEGACY: re-enable the legacy intra-file AP-042 (HTTP callout without retry path).VULKRO_SF_AP044_LEGACY: re-enable the legacy intra-file AP-044 (REST endpoint without auth check).VULKRO_SF_AP060_LEGACY: suppress AP-060 entirely (Type.forName dynamic dispatch with no FLS / sharing marker anywhere in the workspace). AP-060 ships fresh so this env var only silences emission.
The Agentforce knowledge bundle
Agentforce knowledge-bundle distribution (AP-066..AP-070). A scan never downloads the bundle: it uses the verified copy that vulkro-sf update last fetched, else the built-in seed.
VULKRO_SF_OFFLINE: set to 1 to ignore the cached bundle (scans use only the built-in seed) and to makevulkro-sf updateskip the bundle refresh.VULKRO_SF_RULES_BUNDLE_URL: override the base URL thatvulkro-sf updatefetches from. Defaulthttps://dist.vulkro.com/sf/rules.VULKRO_SF_RULES_BUNDLE_OVERRIDE: sideload a local JSON bundle (testing / pre-publish).VULKRO_SF_RULES_BUNDLE_CACHE_DIR: override the on-disk cache (default~/.vulkro/rules-bundle/).VULKRO_SF_RULES_BUNDLE_MIN_REFRESH_SECS: age in seconds after which a scan prints a one-line note suggestingvulkro-sf update(default 86400, clamped [60, 604800]).
Licence: vulkro-sf login, CI
Every scanning command needs a licence (start the 14-day trial at app.vulkro.com/billing, then vulkro-sf login). For CI and air-gapped runners:
VULKRO_ACCOUNT_TOKEN: a CI key from app.vulkro.com (Settings). Every scanning command signs in with it automatically when no licence is cached on the machine, so CI needs novulkro-sf loginstep.VULKRO_LICENSE_B64: the base64 of a.licfile (base64 < key.lic,base64 -w0on Linux), for air-gapped CI: verified in memory on every scanning command when no licence is installed; nothing is written to ~/.vulkro.VULKRO_ACCOUNT_URL: the account / API baselogintalks to (default https://app.vulkro.com/api).
Vulkro Cloud: vulkro-sf cloud
vulkro-sf cloud and the sf_cloud_* MCP tools use the connection vulkro-sf cloud connect saved (~/.vulkro/sf-cloud.json). Pro Cloud (vulkro-sf cloud connect --pro) stores no token: each request carries this machine's Vulkro sign-in, or VULKRO_ACCOUNT_TOKEN when it is set. For CI against a company workspace:
VULKRO_SF_CLOUD_URL: workspace address to use instead of the saved connection. Needs VULKRO_SF_CLOUD_TOKEN, unless it matches the saved workspace.VULKRO_SF_CLOUD_TOKEN: a workspace token (vkws_...) to use instead of the saved one. Needs VULKRO_SF_CLOUD_URL when this machine has no saved connection.VULKRO_OFFLINE: set to refuse every network call; everycloudcommand is then refused (local scans keep working). Any value turns it on, including an empty one, except 0, false, no and off (any case).VULKRO_SF_OFFLINE: the same rule; skips only the Agentforce rules bundle refresh.