CyberXYZ Supply Chain Scanner
Catch malicious packages and vulnerable dependencies before they reach your machine or your build. The extension reads the full dependency tree from your lockfile, checks every package at the exact version you install, puts known-malicious releases and actively exploited vulnerabilities first, and fixes them in one reviewed step.
npm, PyPI, Go and NuGet. Backed by the same CyberXYZ decision engine that gates installs through the CyberXYZ proxy.
Documentation | Dashboard | Privacy | Support
Features
- Malicious packages first. Every package in the tree is checked against the CyberXYZ known-malicious corpus. Direct and flagged packages also get the proxy decision (block, quarantine, alert) with the reason in words: "Published very recently", "New dependency injected in this release". A malicious release outranks any CVE.
- Actively exploited next. Advisories in CISA's Known Exploited Vulnerabilities catalog are marked KEV (actively exploited), reported as errors and never hidden by the severity filter.
- The full tree, at exact versions. Dependency trees come from your lockfile (npm, yarn, pnpm, Poetry, uv, Pipfile, pip-compile, Go, NuGet), read locally. Each package is checked at the version it installs, with every path from your direct dependency down to it.
- Fix all, reviewed. One confirmation lists every change and the advisories it clears. Major-version bumps stay unticked until you tick them. The lock command runs once per manifest; a missing package manager is installed with one click. When no release fixes an advisory yet, you get the real options: a partial upgrade (clears N of M), removal, an ignore with a reason and expiry, and the advisory.
- Fix history. Every applied fix is recorded with the advisories it cleared and the lock command's result, exportable as JSON.
- Hovers where you work. Hover a dependency in a manifest, or an
import in JavaScript, TypeScript, Python or Go, for the package card.
- Your organization, one click away. Which machines installed a package, the proxy's decisions for it, its blast radius, and deep links into the CyberXYZ dashboard.
- Ignore with a reason.
.cyberxyz/ignore.json, committed and shared with your team, with expiry dates.
Quick start
- Install. Search for CyberXYZ Supply Chain Scanner in the Extensions view (
Ctrl+Shift+X / Cmd+Shift+X), or run code --install-extension cyberxyz.cyberxyz-vulnerability-scanner.
- Sign in. Run CyberXYZ: Sign In. VS Code shows a one-time code and opens the CyberXYZ dashboard; check the code matches and approve with your usual sign-in (password and MFA, SSO or a passkey). There is no key to copy. No account yet? Create one at app.cyberxyz.io.
- Open a project. Open a folder with a
package.json, requirements*.txt, pyproject.toml, Pipfile, go.mod or *.csproj. The workspace is scanned when it opens; results appear in the CyberXYZ view in the Activity Bar, in the Problems panel and on the dependency lines.
CyberXYZ: Get Started opens a short walkthrough of the same steps.
Until you sign in, dependency trees are read locally and nothing is sent to CyberXYZ.
Where to find it
- The CyberXYZ shield in the Activity Bar has three views:
- Dependencies: every manifest with its package, issue and KEV counts, then its direct dependencies, then the full tree.
- Issues: every package version with something to act on, worst first, with the fix version and the path that pulls it in.
- Fix History: every fix applied from this machine.
- The status bar item (
CyberXYZ: 3 issues (1 KEV)) opens the Issues view.
- Diagnostics, hovers, CodeLens and quick fixes appear in the manifest itself.
How fixing works
The fix version. For each flagged package, CyberXYZ's per-version data gives the nearest version free of the advisories that affect the one you have, preferring one within your current major version. When that data doesn't hold a clean release, the fix is the highest fixed version across the package's advisories: every advisory must name one, and a version CyberXYZ flags is never used. A fix that leaves one of the advisories open is never offered as the fix.
Fix one finding. Use the light bulb on the underlined line (Ctrl+. / Cmd+.), the CodeLens above it, or Fix in either view. The quick fix says what it fixes: Upgrade lodash 4.17.20 → 4.17.21 (fixes 3 advisories, 1 KEV). The version in the manifest is rewritten the way it was written (^1.2.3 → ^1.2.9, ==2.0.1 → ==2.3.3, v0.17.0 → v0.23.0). When there is more than one way to fix it, you choose, recommended first.
Fix All. The wrench in the Issues and Dependencies view toolbars, CyberXYZ: Fix All in the Command Palette, or right-click a manifest for just that file:
Plans a fix for every finding:
| Finding |
Fix |
| Direct dependency |
The version is rewritten. If a fixed version exists in the current major, it is recommended; the new major is an opt-in alternative |
| The manifest already allows the fix |
A targeted lock update: npm update x, pnpm update x, yarn up -R x, uv lock --upgrade-package x, poetry update x, pipenv update x, pip-compile --upgrade-package x, go get x@vY, dotnet add package x --version Y |
| Transitive, npm / yarn / pnpm |
An overrides / resolutions / pnpm.overrides entry within the installed major; if only a new major fixes it, upgrade the parent to the lowest version that pulls in a fixed child |
| Transitive, pip / pip-compile |
The pin in requirements.txt rewritten, and a minimum added to requirements.in (or the constraints file) so the next compile keeps it |
| Transitive, Poetry / uv / PEP 621 / Pipfile |
An explicit dependency, [tool.uv] constraint-dependencies, or a [packages] entry |
| Transitive, Go |
go get module@vX, then go mod tidy |
| Transitive, NuGet |
A direct <PackageReference> at the fix version; with Central Package Management, a <PackageVersion> with transitive pinning |
A version that can't be rewritten (latest, a URL) |
A manual step with the exact line and command (Copy manual steps) |
| Known malicious, no clean version |
Remove dependency (unticked, confirmed a second time) |
| No version fixes every advisory, one fixes some |
A PARTIAL upgrade to the version that leaves the fewest advisories: Upgrade pkg to 1.3.0 (clears 1 of 2), with the ones still open named. Unticked |
| No version fixes any advisory |
Nothing is changed; the finding is listed under no upstream fix with its options (below) |
Shows one confirmation: every change grouped by file, with the advisories it clears and the command that follows. The title line groups the findings: 12 fixable now / 3 partially fixable / 2 no upstream fix. Major-version bumps, removals, alternatives and partial fixes are unticked: nothing crosses a major version unless you tick it.
Applies the ticked changes, then runs each manifest's lock command once (once per shared lockfile), with progress you can cancel.
Ends with a summary: what was applied, which commands succeeded or failed, manual steps, and the same grouping. Options for N unfixed opens the findings with no upstream fix.
No fixed version upstream. When no release fixes an advisory yet, Fix on the finding (in either view, or the no complete fix, see the options quick fix) and Options for N unfixed after Fix All offer what you can do instead:
- Upgrade to X (clears N of M), marked PARTIAL, when a newer version fixes some of the advisories. Recorded in Fix History as an upgrade, with the advisories still open in its reasons.
- Remove the dependency (direct dependencies). The extension looks for imports of it in the JavaScript / TypeScript, Python or Go files next to the manifest and says looks unused or where it is imported; removal always asks to confirm. For a transitive package, Show what pulls it in.
- Ignore with a reason and expiry, pre-filled with the advisory and no fix available upstream, expiring in 30 days so it comes back for a re-check.
- Open the advisory (GitHub, NVD or OSV) and the package's page on packages.cyberxyz.io.
A finding flagged only by a proxy signal (a new maintainer, a version jump, no advisory) has nothing to upgrade to; it is counted separately and left to review or ignore. There is no "replace with" option: CyberXYZ does not have data on maintained alternatives, so it does not suggest one.
Lockfile regeneration. The extension edits manifests, never lockfiles: your package manager updates the lockfile. After a fix it runs the lock command (npm install, yarn install, pnpm install, uv lock, poetry lock, pipenv lock, pip-compile, go mod tidy, dotnet restore) as a CyberXYZ task in the manifest's folder, so its exit code is recorded. When the lockfile changes, the tree is read again and re-checked. A manifest without a lockfile gets Generate lockfiles, then plan first, so the plan uses the exact tree.
One-click tool install. Before a command runs, the extension checks that its tool is installed: the project's .venv / venv, then PATH, then the usual per-user folders. It uses a fallback when there is one (uv pip compile for pip-compile, corepack yarn, python3 -m pip). Otherwise you get one Install button with the best installer on this machine:
| Tool |
Installer, in order of preference |
| poetry |
pipx install, uv tool install, brew install, python3 -m pip install --user |
| pipenv, uv, pip-tools |
uv tool install, pipx install, brew install (macOS), winget / scoop (Windows), python3 -m pip install --user |
| yarn, pnpm |
corepack enable, npm install -g |
| go, dotnet, node |
Homebrew (macOS), winget / scoop (Windows), apt (Linux); otherwise the download page |
The install runs as a visible task and the fix continues when it finishes. Nothing is installed without your click.
Fix History. Every fix (single, quick fix, Fix All, tool install) is recorded: time, workspace, file, package, from and to version, advisories cleared, and the lock command's result. It is kept on this machine (the last 1,000, not synced). Export Fix History (JSON) and Clear Fix History are in the view's toolbar.
Fix requests from your organization
An organization admin can ask you to fix a finding from the CyberXYZ dashboard (Request fix on an open finding in a machine's IDE section). While you are signed in, the extension checks for requests when it starts and every 15 minutes, and shows a notification:
admin@example.com asked you to upgrade lodash 4.17.20 → 4.17.21 in web/package.json (clears GHSA-35jh-r3h4-6jhm) Review & apply Decline
You always confirm. A request names only a package and two versions. Review & apply plans the fix here, from your own manifest and lockfile, with the same planner as Fix All, and opens the Fix All confirmation with that change ticked. Nothing changes until you confirm there, and no command, script or edit from the server is ever run. If the local plan disagrees (the upgrade crosses a major version, the package is no longer in this workspace, no fixed version is known), you see why and the request is declined with that reason. Your answer goes back to the requester's dashboard.
Turn requests off with xyz-scanner.acceptFixRequests. CyberXYZ: Check Fix Requests checks now.
Supported ecosystems
| Ecosystem |
Manifests |
Lockfiles (exact tree) |
| npm |
package.json (dependencies, devDependencies, peerDependencies, optionalDependencies) |
package-lock.json / npm-shrinkwrap.json v1-v3 (including workspaces), yarn.lock (classic and berry), pnpm-lock.yaml (v5, v6, v9) |
| PyPI |
requirements*.txt, pyproject.toml ([project], optional dependencies, dependency groups, Poetry tables), Pipfile |
poetry.lock, uv.lock, Pipfile.lock, pip-compile output (# via comments) |
| Go |
go.mod |
go.sum |
| NuGet |
*.csproj (PackageReference) |
packages.lock.json |
Limits to know about
- Maven and Gradle are not parsed (
pom.xml, build.gradle); nor are Cargo, RubyGems or Composer manifests. Use the CyberXYZ CLI or the proxy for those ecosystems.
- No lockfile: the tree comes from the CyberXYZ registry graph, which follows each package's latest release, so it is marked Approximate. Click the note (or run CyberXYZ: Generate Lockfile) for exact versions. Go manifests without
go.sum list direct modules only.
Pipfile.lock and go.sum record versions but not who requires whom: direct dependencies are listed, and everything else sits under Other locked packages / Indirect modules.
- Dependencies with no version (
requests alone, *, git URLs, $(MSBuild) properties) are not checked, because every advisory would match.
- The extension reads files from the local file system: virtual workspaces (for example a GitHub repository opened in the browser) are not scanned.
Ignoring findings
Ignore… (right-click in either view, or the light bulb on a diagnostic) asks what to ignore (one advisory, this version, or every version), why, and an optional expiry date (default 90 days). It writes .cyberxyz/ignore.json at the workspace root with your git name and email; commit it so your team shares the decision.
{
"version": 1,
"ignores": [
{ "package": "lodash", "ecosystem": "npm", "version": "4.17.20", "advisory": "CVE-2021-23337",
"reason": "not reachable: we never call template()", "expires": "2026-12-31",
"author": "Jane Doe <jane@example.com>", "created": "2026-09-26" }
]
}
Ignored findings are hidden from the views, counts and the Problems panel; Show Ignored Findings brings them back with the reason. Expired entries stop applying. Ignoring a blocked or known-malicious package needs a second confirmation: a malicious package should be removed, not ignored.
Your organization's fleet
Right-click a package in either view (or use the CodeLens above a flagged dependency):
- Machines in My Org That Installed This: from the CyberXYZ proxy and agent install log (last 90 days), each machine with the version, the decision and when it was last seen.
- Proxy Decisions for This Package: your organization's install log for it.
- Blast Radius: public packages that depend on it, and whether their ranges admit the affected version.
- Open in CyberXYZ Dashboard: the package page, its dependency graph, the proxy monitor or environments.
If your plan or role doesn't include a feature, the extension says so.
Commands
| Command |
What it does |
| CyberXYZ: Get Started |
Open the getting-started walkthrough |
| CyberXYZ: Sign In |
Sign in with your browser (device flow: approve a one-time code in the dashboard) |
| CyberXYZ: Sign Out |
Revoke the browser session and forget it on this machine; offers to remove a stored API key |
| CyberXYZ: Set API Key |
Store an API key in VS Code's secret storage instead of signing in |
| CyberXYZ: Scan This File |
Check the manifest in the active editor (also in the Explorer and editor title menus) |
| CyberXYZ: Scan All Files in Workspace |
Find every manifest in the workspace and check every package in every tree |
| CyberXYZ: Show Dependency Tree |
Reveal the current manifest in the Dependencies view |
| CyberXYZ: Clear Cache |
Forget cached results (otherwise reused for an hour) |
| CyberXYZ: Only Packages with Issues |
Dependencies view: show only the paths that lead to an issue |
| CyberXYZ: Show All Packages |
Dependencies view: show every package again |
| CyberXYZ: Show Ignored Findings |
Show findings ignored in .cyberxyz/ignore.json, with the reason |
| CyberXYZ: Hide Ignored Findings |
Hide ignored findings again |
| CyberXYZ: Fix All |
Plan a fix for every fixable finding in the workspace, or in one manifest, and apply the ones you tick |
| CyberXYZ: Generate Lockfile |
Show or run the command that creates the lockfile for this manifest |
| CyberXYZ: Machines in My Org That Installed This |
Machines in your organization that installed this package through the CyberXYZ proxy or agent |
| CyberXYZ: Proxy Decisions for This Package |
Your organization's proxy install log for this package |
| CyberXYZ: Blast Radius |
Public packages that depend on this one, and whether their ranges admit the affected version |
| CyberXYZ: Open in CyberXYZ Dashboard |
Open the package, its dependency graph, the proxy monitor or environments in the dashboard |
| CyberXYZ: Export Fix History (JSON) |
Save the local fix history as JSON |
| CyberXYZ: Check Fix Requests |
Look for fix requests from your organization now |
| CyberXYZ: Clear Fix History |
Delete the local fix history (records already reported stay with your organization) |
| Refresh (views and menus only) |
Re-check the workspace (Dependencies view toolbar) |
| Go to Manifest Line (views and menus only) |
Jump to the line that declares a direct dependency (views) |
| Show Dependency Path (views and menus only) |
Show how a transitive package gets into the tree (views) |
| Fix (views and menus only) |
Fix one finding: the recommended upgrade, override or parent upgrade, with the alternatives (views) |
| Ignore… (views and menus only) |
Ignore an advisory, a version or a package, with a reason and an expiry date (views) |
| Remove Ignore (views and menus only) |
Remove an ignore entry (Issues view, with ignored findings shown) |
| Open Issues (views and menus only) |
Open the Issues view (status bar item) |
Settings
Open Settings (Ctrl+, / Cmd+,) and search for CyberXYZ.
| Setting |
Default |
Description |
xyz-scanner.apiUrl |
"https://api.cyberxyz.io" |
CyberXYZ API URL. Change it only for a self-hosted or dedicated CyberXYZ API. Machine setting: a workspace cannot override it, so a cloned repository cannot redirect your credentials. |
xyz-scanner.dashboardUrl |
(empty) |
CyberXYZ dashboard URL for deep links. Empty: derived from the API URL (api.cyberxyz.io becomes app.cyberxyz.io). Machine setting. |
xyz-scanner.scanWorkspaceOnStartup |
true |
Scan every manifest in the workspace when VS Code opens it (package names and versions are sent to CyberXYZ). Off: only manifests you open are scanned, until you run CyberXYZ: Scan All Files in Workspace. |
xyz-scanner.enableAutoScan |
true |
Scan a dependency manifest (package.json, requirements*.txt, pyproject.toml, Pipfile, go.mod, *.csproj) while you edit it. |
xyz-scanner.scanOnSave |
true |
Scan a dependency manifest when it is saved. |
xyz-scanner.scanTransitiveDependencies |
true |
Check every package in each dependency tree (direct and transitive) at the exact version your lockfile installs. Without a lockfile, the tree comes from CyberXYZ's registry graph (latest versions) and is marked approximate. Turn off to check direct dependencies only. |
xyz-scanner.behaviourSignals |
"directAndFlagged" |
Which packages get a CyberXYZ proxy decision (block / quarantine / alert) and its behaviour signals (new dependency injected, published very recently, unusual version jump, …). Known-malicious releases are checked for every package regardless. One of directAndFlagged, all, off. |
xyz-scanner.minSeverity |
"low" |
Minimum advisory severity to show. Advisories in CISA KEV (actively exploited) are always shown. One of low, medium, high, critical. |
xyz-scanner.maxDependencyDepth |
10 |
How many levels the Dependencies view expands (1-50). Every package in the tree is checked whatever this is; deeper levels are marked (… deeper levels hidden). Range 1-50. |
xyz-scanner.codeLens |
true |
Show CodeLens in manifests: a summary line, and status, upgrade, machines and blast radius above each dependency with an issue. |
xyz-scanner.importHovers |
true |
Show the package card when hovering an import in JavaScript/TypeScript, Python and Go files (from the last scan; no network call on hover). |
xyz-scanner.uploadScans |
true |
Share your IDE activity with your CyberXYZ organization: after a scan of the whole workspace, a summary (workspace name, ecosystems, number of manifests / lockfiles / packages checked, and each flagged package with its version, manifest path relative to the workspace, decision, advisory ids and fix version) goes to your organization's scan history, at most once per workspace every 12 hours unless the findings changed; and a daily heartbeat (extension and editor version, OS, this machine's hostname, number of workspace folders) so admins can see which version runs where. Only while signed in; never delays a scan. No source code or file contents are sent. |
xyz-scanner.reportFixes |
true |
Report fixes you apply (package, from → to version, manifest path relative to the workspace, advisories cleared, lock command result, this machine's hostname) to your CyberXYZ organization, so it sees what was fixed where. Best effort: never delays a fix. Sent only when the platform supports it; the local Fix History is kept either way. |
xyz-scanner.acceptFixRequests |
true |
Show fix requests from your CyberXYZ organization: an admin (or you, from the dashboard) can ask this editor to upgrade a package your last workspace scan reported, e.g. lodash 4.17.20 → 4.17.21. The extension checks for them when it starts and every 15 minutes while you are signed in, and shows a notification with Review & apply and Decline. A request names only a package and two versions: the change is planned here from your own manifest and lockfile, shown in the Fix all confirmation, and applied only when you confirm. When the local plan disagrees (a major version, the package is not here) the request is declined with the reason. Your answer (applied / declined / failed, and the fix-history record of the fix) is sent back. |
xyz-scanner.apiKey |
(empty) |
Deprecated. API keys are stored in VS Code's secret storage. Use "CyberXYZ: Sign In" or "CyberXYZ: Set API Key". |
xyz-scanner.enableTransitiveScan |
true |
Deprecated. Use xyz-scanner.scanTransitiveDependencies (on by default; reads the lockfile). |
Privacy
The extension sends CyberXYZ only what it needs to check your dependencies. The privacy details list what is sent and when; PRIVACY.md, shipped inside the extension package, lists every request and every field in it.
What is sent
- Package names, versions and ecosystems from your manifests and lockfiles, for the checks.
- Manifest paths relative to the workspace folder (for example
apps/web/package.json), the workspace name, this machine's hostname, the OS, and the extension and editor versions: with browser sign-in, with fix reports, with workspace-scan summaries and the daily heartbeat, and with the fix-request check, so your organization can see which machine a finding or fix belongs to.
- Your credential, as the
Authorization header, only to the configured API URL.
What is never sent: source code, file contents (lockfiles are parsed locally; only names and versions leave), absolute file paths, .env files or secrets, your ignore file, your settings, or telemetry.
Turning uploads off
| Setting |
Turns off |
xyz-scanner.uploadScans |
Workspace-scan summaries to your organization's scan history, and the daily heartbeat |
xyz-scanner.reportFixes |
Fix reports to your organization (the local Fix History is kept) |
xyz-scanner.acceptFixRequests |
The fix-request check (and its hostname) |
To stop all network calls, sign out (CyberXYZ: Sign Out), remove any API key, or uninstall the extension. Sessions and API keys are stored in VS Code's secret storage (your OS keychain), never in settings.json.
Troubleshooting
| Message |
What to do |
| "Sign in to check your dependencies" |
Run CyberXYZ: Sign In, or CyberXYZ: Set API Key |
| "Your CyberXYZ session expired" |
The session was unused for 90 days or revoked. Run CyberXYZ: Sign In |
| "Cannot reach CyberXYZ at ..." |
Check your connection or proxy, then Try Again. For a self-hosted API, check xyz-scanner.apiUrl (a user or machine setting) |
| "CyberXYZ rate limit reached" |
Wait a minute and scan again; ask your organization admin about the plan's limits if it keeps happening |
| "Approximate: registry graph" |
The manifest has no lockfile. Run CyberXYZ: Generate Lockfile for exact versions |
| "command not found: pip-compile" (or poetry, uv, pnpm, yarn) |
Use the Install button, or install the tool and restart VS Code so it picks up the new PATH |
| Packages show "not checked" |
You are signed out, or the scan hasn't run: click Scan All Files in Workspace |
| A finding you expected is missing |
Check Min Severity, whether it is ignored (Show Ignored Findings), and whether the installed version (from the lockfile) is already fixed |
| "N no upstream fix" (or, before 0.5.1, "N findings have no fixed version") |
No release fixes those advisories yet. Click Options for N unfixed (or Fix on the finding) for a partial upgrade when one exists, removing the dependency, an ignore with a reason and expiry, and links to the advisory and the package page. Before 0.5.1, findings were also listed here when the fix was known only from the advisories' fixed versions; update the extension and run Fix All again |
Support
License
Proprietary. Copyright CyberXYZ Security. See LICENSE.txt in the extension package.
| |