XYZ CLI · 1.4.74 · Docs

The xyz command,
the full reference.

Every xyz command, checked against --help in 1.4.74: browser sign-in, the always-on install firewall for npm, pip, Go and NuGet, machine audits, code scanning, CI/CD gating and MCP for AI coding agents, on macOS, Linux and Windows.

  • 1.4.74// cyberxyz-scanner
  • 90 days// sliding session
  • 4// ecosystems at install
// install
$pipx install cyberxyz-scanner
// sign in, then protect this machine
$xyz login
$xyz proxy setup
$xyz proxy status

or pip install cyberxyz-scanner · Python 3.8+

01 · setup

Install

The CLI is published on PyPI as cyberxyz-scanner; the command it installs is xyz. It runs on macOS, Linux and Windows with Python 3.8 or newer (3.10 or newer for xyz mcp). pipx keeps it in its own environment, which is what we recommend:

shell
pipx install cyberxyz-scanner

# or
pip install cyberxyz-scanner
uv pip install cyberxyz-scanner

# verify
xyz --version
xyz --help

This page describes 1.4.74. xyz upgrade installs the latest release.

02 · setup

Quick start

shell
xyz login            # sign in through your browser
xyz proxy setup      # route npm, pip, Go and NuGet installs through CyberXYZ (sudo ... --system on managed machines)
xyz proxy status     # is every package manager routed? is the agent current?
xyz audit            # inventory and check what is already installed

From then on every install on the machine goes through the CyberXYZ proxy: the exact version is checked before it downloads, blocked or quarantined packages are refused with the reason, and the install shows up in your dashboard.

03 · setup

Sign in

shell
xyz login                 # opens your browser and shows a code (XXXX-XXXX)
xyz login --no-browser    # SSH / headless: prints the link and code instead

xyz login uses the browser device flow. It opens app.cyberxyz.io/cli/activate and prints a code. Sign in on the dashboard the way you usually do (password plus an authenticator app or a passkey, or SSO), check that the code matches the one in your terminal, and click Approve. The CLI never sees your password. Over SSH, or on Linux with no display, the link and code are printed automatically. Codes expire after 10 minutes and work once.

Only approve a code you just requested yourself. Approving a code someone sent you signs their terminal in as you.

Sessions are 90 days, sliding. The session stays signed in while you use it and expires after 90 days without use. While the CyberXYZ agent runs on the machine it refreshes the session daily, so you sign in once; a machine that stays off for 90 days signs out. The session is stored owner-only in ~/.xyz/config.json and listed in the dashboard under Settings > CLI sessions, where you or an org admin can revoke it. xyz logout revokes it on the server and removes it locally.

xyz login --password is the legacy email and password prompt (--email, or $XYZ_EMAIL and $XYZ_PASSWORD for scripts). Accounts with MFA, and organizations that require MFA or enforce SSO, must use the browser login.

04 · setup

API keys

For CI runners and headless servers, create an API key in the dashboard (Settings > API keys, it starts with sk_xyz_) and set it in the environment. No xyz login is needed.

shell
export XYZ_API_KEY=sk_xyz_...
xyz check axios 1.7.7 --ecosystem npm    # confirms the key authenticates
xyz --api-key sk_xyz_... audit npm       # or pass it for one command

xyz status and xyz info show the sign-in stored in ~/.xyz/config.json, so with only XYZ_API_KEY set they can say "Not logged in" while every request still uses the key. Use xyz check or xyz scans list to confirm the key works. For fleets, use an enrollment token instead (Managed machines).

05 · the firewall

The proxy and the agent

xyz proxy setup

shell
xyz proxy setup
xyz proxy setup --machine-name "Alex MacBook"
xyz proxy setup --no-install-daemon        # CI agents and sealed builds: no background service

One command registers the machine with your organization, points npm, pnpm, yarn, bun, pip, uv, Go and NuGet at the CyberXYZ proxy (each one only if it is installed), and installs the background agent that keeps them routed and runs dashboard Scan now jobs. If you are not signed in and the terminal is interactive, it offers the browser sign-in first.

OptionWhat it does
--machine-name TEXTThe name shown on the Machines page. Defaults to the hostname
--systemInstall the agent as a root/SYSTEM service (needs sudo, or an elevated PowerShell). See Managed machines
--enrollment-token TEXTOrg enrollment token (pxe_xyz_...) for zero-touch setup with no xyz login. Also read from $XYZ_ENROLLMENT_TOKEN or /Library/Application Support/CyberXYZ/enrollment-token
--install-daemon / --no-install-daemonAlso register the background service (default on)
--proxy-url, --pip-proxy-url, --go-proxy-url, --nuget-proxy-urlOverride the proxy endpoints (defaults: npm-proxy, pip-proxy, go-proxy and nuget-proxy.cyberxyz.io)
--localPoint at a local proxy (http://localhost:4873) for testing

Always-on protection

Every minute the agent checks what each package manager will actually use, repairs anything that no longer points at the proxy, and reports the result to the dashboard. Repairs never remove a private or internal registry, and config files are only written for tools that are installed.

ToolWhat is checked and repaired
npm, pnpm~/.npmrc registry and token, pnpm's global rc; as root also the global npmrc
yarn~/.yarnrc.yml npmRegistryServer and registry in ~/.yarnrc
bun~/.bunfig.toml [install] registry
pipThe user pip.conf / pip.ini: the proxy is the index-url; extra indexes on pypi.org are removed, private indexes are kept
uvuv.toml: the proxy is the default index; pypi.org indexes are removed, private indexes are kept
GoGOPROXY=<proxy>,direct (the proxy refuses blocked modules with 403, so there is no fall-through); proxy-only while the network lock is on
NuGetNuGet.Config: the CyberXYZ source is added and nuget.org sources removed; private feeds are kept
PoetryCannot be forced globally, so it is covered by the network lock only

Registry overrides in shell startup files (NPM_CONFIG_REGISTRY, PIP_INDEX_URL, GOPROXY=direct, ...) and in the Windows user environment are reported, never edited.

If CyberXYZ is unreachable

The proxy reuses its verdict for any package it checked in the last 24 hours. For anything else your org's setting decides: block (the default, fail-closed; the developer sees "retry in a minute") or allow unchecked. Org admins change it under Settings > Supply-chain proxy.

xyz proxy status

shell
xyz proxy status

Shows the routing report for each package manager, the service level (per-user or system), the network lock, when the agent last reported (a report older than 15 minutes is flagged), and whether the agent runs the CLI version that is installed. It works without sudo under the system service.

xyz proxy restart

shell
sudo xyz proxy restart        # macOS / Linux, system service
xyz proxy restart             # per-user service, or an elevated PowerShell on Windows

pipx upgrade and pip install -U replace the code but cannot restart a root service. From 1.4.66 the agent notices the new version and restarts onto it by itself within a few minutes, between jobs. xyz proxy restart does it now. The first CLI run after an upgrade prints the restart command when the system agent is still on older code (XYZ_NO_UPGRADE_HINT=1 turns that off).

xyz proxy whoami and xyz proxy remove

shell
xyz proxy whoami     # what (organization, machine) does my proxy token resolve to?
xyz proxy remove     # restore the default registries (sudo under the system service)

whoami tells you whether your npm and pip config carry a machine token (px_xyz_) or a credential with no machine attribution. remove reports the removal to the platform first, then clears the proxy entries and the service. To retire a machine and its token, delete it from the dashboard's Machines page. To rotate a machine's token, run xyz proxy setup --machine-name "..." again as the same user.

xyz proxy daemon

You do not start the agent by hand: xyz proxy setup installs it (a LaunchAgent on macOS, a systemd user unit on Linux, a Task Scheduler entry on Windows). It polls for Scan now jobs from the dashboard and runs the matching audit. For debugging:

shell
xyz proxy daemon --once                      # one poll, then exit
xyz proxy daemon --max-jobs 3
xyz proxy daemon --install-service           # add --system for the root/SYSTEM service
xyz proxy daemon --uninstall-service
06 · the firewall

Managed machines

shell
# macOS / Linux
sudo xyz proxy setup --system

# Windows, from an elevated PowerShell
xyz proxy setup --system

--system installs a root/SYSTEM service (macOS LaunchDaemon io.cyberxyz.agent, Linux cyberxyz-agent.service, Windows scheduled task CyberXYZAgent) that starts at boot, restarts if it is killed, cannot be stopped by the developer, and repairs every local user's package-manager config. The machine token is kept where only the agent can read it, so deleting a config file only gets it rewritten. Drift, tampering, uninstalls and machines that stop reporting raise alerts for org admins. Under the system service only an administrator can remove it.

MDM enrollment

An org admin creates an enrollment token in the dashboard (Machines > Enrollment). The macOS .pkg installs the system service and enrolls automatically when MDM places the token at /Library/Application Support/CyberXYZ/enrollment-token. Otherwise pass it:

shell
sudo xyz proxy setup --system --enrollment-token pxe_xyz_...

Network lock

When an org admin turns it on (Settings > Supply-chain proxy), the system agent maps the public registries (registry.npmjs.org, registry.yarnpkg.com, registry.npmmirror.com, pypi.org, files.pythonhosted.org, proxy.golang.org) to 0.0.0.0 in the hosts file, so tools that ignore config still cannot reach them. Edits to the lock are reverted and reported. NuGet is not locked yet; it relies on config. xyz proxy status shows whether the lock is on.

07 · audits

Audit a machine

The proxy covers what is installed from now on. xyz audit covers what is already there: it checks the packages against the malicious-package watchlist, deep-checks the suspects, and uploads the full inventory to your dashboard.

shell
xyz audit              # npm, python, venvs, go, ide, browser and system, back to back
xyz audit npm          # node_modules on this machine, global packages included (--no-global to skip)
xyz audit python       # the active Python environment (pip list)
xyz audit venvs        # every virtualenv, conda and pipx environment on the disk
xyz audit go           # go list -m all
xyz audit nuget        # packages.lock.json under the current directory (--lock-file PATH)
xyz audit ide          # VS Code, Cursor, Windsurf and VSCodium extensions
xyz audit browser      # Chrome, Edge, Brave and Firefox extensions
xyz audit system       # Homebrew, apt, rpm, winget, Chocolatey, macOS apps
xyz audit models       # local AI model files and Hugging Face references
OptionWhereWhat it does
--fullnpm, python, go, nugetCheck every package instead of only the watchlist matches. Slower; covers advisory matches at scan time
--jsonallJSON instead of the table
--output FILE, --format json|sarifnpm, python, go, nugetWrite findings to a file; .sarif is for GitHub Code Scanning
--legacypython, goThe pre-1.4.13 scripts (much slower)
--no-verifyideSkip the upstream phantom-version check (no network calls)

xyz audit models

shell
xyz audit models                           # current directory and the Hugging Face cache
xyz audit models ./ml --no-hf-cache
xyz audit models --aibom -o aibom.cdx.json # CycloneDX 1.6 ML-BOM

Finds model files (.safetensors .bin .pt .pth .ckpt .gguf .onnx .pkl .h5) and hashes them with a streamed sha256, finds Hugging Face references in code (from_pretrained, hf_hub_download, pipeline(model=...), snapshot_download, and flags trust_remote_code=True), and reads ~/.cache/huggingface/hub. Files are never loaded or unpickled. Files larger than --max-hash-size (default 20 GiB) are listed as UNHASHED. NOT WATCHED, PENDING and UNSCANNED are not verdicts. Exits 1 when anything is MALICIOUS. AI model coverage is part of the Business plan and above (pricing).

08 · dependencies

Check, fix, impact, SBOM

xyz fix, xyz sbom and xyz depalert scan read the manifests and lockfiles in the current directory: package.json / package-lock.json, requirements*.txt, Pipfile / Pipfile.lock, pyproject.toml / poetry.lock / uv.lock, go.mod / go.sum and NuGet packages.lock.json.

xyz check

shell
xyz check axios 1.7.7                        # npm by default
xyz check requests 2.31.0 --ecosystem pypi --json
xyz check org.apache.logging.log4j:log4j-core 2.14.1 -e maven

The proxy's verdict for one PACKAGE VERSION, with the signals and a safe version.

xyz fix

shell
xyz fix                        # plan only: package, current, issue (KEV badge), target, why
xyz fix --write                # show a diff, confirm, then edit the specs
xyz fix --write --yes          # no prompt (bots)
xyz fix --json

For each flagged package (block, quarantine, alert or any advisory) the plan gives the nearest clean release above the installed version. A transitive package is traced to the direct dependency that pulls it in ("via express → debug, bump express"). --write edits only direct specs in package.json (keeping ^, ~ and >=) and == pins in requirements*.txt; lockfiles are never edited, so run npm install, poetry lock, uv lock or pip-compile afterwards. The plan is uploaded to your dashboard when you are signed in (--no-upload to skip). Exit codes: 0 plan complete, 1 a flagged package has no clean target, 4 backend unreachable.

xyz impact

shell
xyz impact debug --version 2.6.8       # ecosystem guessed from the project, else npm
xyz impact requests -e pypi --json
xyz impact lodash --top 20 --no-local

The blast radius of a package: its direct dependents and whether each declared range admits the affected version, how many packages reach it on a required path versus only through an optional extra, and the top paths. Inside a project it also says whether this project reaches it, and through which direct dependency. "Not yet indexed" means the path is unknown, not that there is none.

xyz sbom

shell
xyz sbom -o sbom.cdx.json                  # CycloneDX 1.5 JSON, with a vulnerabilities section
xyz sbom --format spdx -o sbom.spdx.json   # SPDX 2.3 JSON
xyz sbom --no-verdicts                     # components only, no network call

Components carry a purl, the version and a scope (dev dependencies are excluded); the dependency graph comes from the lockfile when it records one. Vulnerabilities list the advisory ids, CVSS and EPSS, a cyberxyz:kev property for CISA KEV entries, and the safe version.

KEV

When an advisory is in CISA's Known Exploited Vulnerabilities catalog, a bold KEV marker leads the score in depalert scan, the vulnerability tables and the xyz fix plan, and SARIF results carry "kev": true.

09 · code

Code scanning

xyz code-scan runs open-source engines installed on your machine and merges what they report into one table, JSON document or SARIF 2.1.0 file. It works without signing in; when you are signed in the results also go to the dashboard's XYZ Scan page: each finding with its rule, file, line and a short snippet. Secret findings carry no snippet and secret values are never sent. --no-upload or XYZ_NO_UPLOAD=1 keeps a run local.

shell
xyz code-scan secrets .                    # hardcoded credentials (values always redacted)
xyz code-scan iac ./infra                  # Terraform, CloudFormation, Kubernetes, Helm, Dockerfiles
xyz code-scan code .                       # SAST with the built-in xyz rules
xyz code-scan code . --config ./my-rules.yml
xyz code-scan ci .                         # GitHub Actions, GitLab CI and Azure Pipelines hardening
xyz code-scan image python:3.11-slim --sbom sbom.cdx.json
xyz code-scan all . --format sarif -o xyz.sarif --fail-on high
xyz code-scan engines                      # what is installed, versions, paths
CommandEngineFallback or option
secretsgitleakstrivy, or --engine trivy
iactrivycheckov with --engine checkov
codeopengrep + the built-in xyz rules + any --configwithout opengrep: bandit (Python), gosec (Go)
cibuilt in, no engine to installGitHub Actions, GitLab CI and Azure Pipelines; --first-party-pins sets the severity for tag-pinned actions/* and github/* actions
imagetrivy (vulnerabilities, misconfigurations, secrets)--sbom FILE writes CycloneDX
allsecrets + iac + code, merged--skip-missing, --fail-on-partial

The built-in rules cover supply-chain patterns: shell=True and os.system with dynamic commands, eval of downloaded data, curl | sh in scripts, CI files and Dockerfiles, pickle.load, torch.load without weights_only=True, trust_remote_code=True, hardcoded cloud and private keys, disabled TLS verification, child_process.exec with template strings, and npm install scripts that download binaries. Without opengrep they do not run, and xyz says so.

Installing the engines

xyz never downloads an engine binary itself. When one is missing and you are at a terminal, it asks once for all of them and runs your own installer: Homebrew (macOS and Linux), winget then Scoop (Windows), and opengrep's official install script (there is no Homebrew formula or PyPI package for it). Linux apt and rpm steps need sudo, so they are printed, not run. After installing, it re-checks and continues the same scan.

shell
xyz code-scan engines                 # found or missing, version, path, install command
xyz code-scan engines --install       # install the missing core engines (add --yes to skip the question)
xyz code-scan all . --install-engines # install without asking (setup scripts)
xyz code-scan all . --no-install      # never ask

In CI, or without a terminal, xyz never asks and never installs, even with --install-engines; it prints the command.

What gets scanned

Inside a git repository, the files git would commit (tracked, plus untracked but not ignored). Gitignored local secret files such as .env are listed apart at INFO. Dependency, build and cache folders (node_modules, venv, dist, build, .next, target, caches, browser profiles) are always skipped. --all-files scans everything; --exclude GLOB skips more.

Target guard. /, your home, the temp directory, or a folder with no project markers (.git, package.json, pyproject.toml, go.mod, *.csproj, ...) is scanned only after a yes on a terminal. In CI or without a terminal it is refused (exit 2) unless --force-target (or XYZ_CODE_SCAN_FORCE_TARGET=1).

Partial scans and exit codes

A run that skipped a scanner is never reported as clean. The table ends with, for example, Partial: secrets scanned, IaC and SAST skipped (engines missing), and JSON, SARIF and the dashboard upload carry status (complete, partial or failed), coverage and one entry per scanner. Common options: --format table|json|sarif, -o FILE, --fail-on critical|high|medium|low|none (default low: any non-info finding fails) and --timeout SECONDS per engine (default 900).

ExitMeaning
0Clean: nothing at or above --fail-on
1Findings at or above --fail-on
2Usage error, including a refused target
3Engine not installed (the install command for your OS is printed)
4Engine error: non-zero exit, timeout or no report
5Partial, opt-in: all --skip-missing --fail-on-partial found nothing in the scanners that ran, but one was skipped. Without --fail-on-partial, --skip-missing exits 0 in that case

In GitHub Actions

yaml
- run: pip install cyberxyz-scanner "bandit[sarif]"
- run: xyz code-scan all . --skip-missing --format sarif -o xyz.sarif --fail-on high
- uses: github/codeql-action/upload-sarif@v3
  if: always()
  with:
    sarif_file: xyz.sarif

Each run is tagged automationDetails.id = xyz-code-scan/<scan>/, so secrets, iac and code can be uploaded separately. In GitLab CI, keep the SARIF or JSON as a job artifact and treat the exit code as the gate. The engines are separate programs, none of them bundled: Trivy (Apache-2.0), Gitleaks (MIT), Opengrep (LGPL-2.1), plus bandit, gosec and checkov (Apache-2.0) when present.

10 · pipelines

CI/CD

Two steps work together. Protect runs early in the job and routes the job's own npm, yarn, pip, uv, Go and NuGet installs through the proxy, so a malicious version is refused at install time on the runner. Scan gates the build on the lockfiles. The CI/CD gate guide has the full GitHub Actions, GitLab CI and Azure DevOps templates, thresholds and a live blocked pull request.

  • 01
    GitHub Actions:CyberXYZSecurity/depalert-action@v1, with mode: protect (optional network-lock: true, strict: true) and the default mode: scan.
  • 02
    GitLab CI/CD catalog:gitlab.com/cyberxyz/depalert provides scan@1.2.0 and protect@1.2.0; protect is a hidden job, .cyberxyz-protect, used with extends: or !reference [.cyberxyz-protect, before_script].
  • 03
    Any other CI:the two commands below, with XYZ_API_KEY set as a secret.

xyz ci init

shell
xyz ci init                              # provider detected from the git remote
xyz ci init --fail-on quarantine
xyz ci init --provider gitlab --print    # print the file instead of writing it

Writes the xyz depalert scan gate into the repository's CI (--provider auto|github|gitlab|azure, --path, --force to overwrite). It then tells you the one step it cannot do: adding XYZ_API_KEY as a CI secret.

xyz ci protect

shell
xyz ci protect --format github              # GitHub: appends to $GITHUB_ENV, masks the token
eval "$(xyz ci protect --format shell)"     # GitLab and any shell
xyz ci protect --format azure               # Azure: ##vso[task.setvariable] lines
OptionWhat it does
--format github|gitlab|shell|azureHow the environment is handed to later steps (default shell)
--network-lockAlso blackhole the public registries in /etc/hosts (needs root or passwordless sudo)
--strictExit non-zero when protection could not be applied. Without it the job continues unprotected with a warning
--machine-name TEXTDefault ci/<provider>/<repo>
--dotenv FILEAlso write the non-secret variables to a dotenv file (GitLab artifacts:reports:dotenv); token-bearing variables are never written there
--no-config-filesOnly emit environment; do not write ~/.npmrc, pip.conf, NuGet.Config or the Go env file
--api-key, --api-urlDefault $XYZ_API_KEY and $XYZ_API_URL

xyz depalert scan

shell
xyz depalert scan --package-lock package-lock.json
xyz depalert scan --requirements requirements.txt --fail-on quarantine
xyz depalert scan --requirements poetry.lock        # also Pipfile.lock and uv.lock, detected from the file
xyz depalert scan --go-sum go.sum
xyz depalert scan -p axios@1.14.1 -p lodash@4.17.21
xyz depalert scan --package-lock package-lock.json --upload   # also send the result to the dashboard's CI gates

--fail-on block|quarantine|alert sets the narrowest verdict that fails the build (default block). Also --pipfile-lock, --poetry-lock, --uv-lock, -e ECOSYSTEM for -p input, and --json.

ExitMeaning
0All clean
1Block: a known malicious version, a critical advisory on that version, or your org block list
2Quarantine
3Alert only
4Could not check: backend unreachable, or a manifest was unreadable. Never treated as clean
11 · ai agents

AI coding agents (MCP)

xyz mcp serve is a Model Context Protocol server that Claude Code, Cursor, VS Code (Copilot agent mode), Windsurf, Codex CLI and Gemini CLI call to check packages, advisories, dependencies and AI models before they add or install anything. It uses your xyz login session (or XYZ_API_KEY) and needs Python 3.10 or newer.

shell
xyz mcp install --client claude-code --hooks        # MCP server + install hook, user scope
xyz mcp install --client cursor --scope project --rules
xyz mcp install --client all --dry-run              # show every diff, change nothing
xyz mcp status                                      # which clients are configured, does auth work
xyz mcp serve --tools                               # list the tools
OptionWhat it does
--clientclaude-code, cursor, vscode, windsurf, codex, gemini or all (repeatable, required)
--scope user|projectEvery project on this machine, or files in the current directory (default user)
--hooksClaude Code: add a PreToolUse hook that checks package installs (--hook-strict asks on alerts, --hook-fail-closed denies when CyberXYZ is unreachable)
--rulesAdd the CyberXYZ dependency policy to the client's agent rules (CLAUDE.md, AGENTS.md, GEMINI.md, .cursor/rules, ...)
--dry-run, --yesShow the diffs only; do not ask before appending to rules files

Every edited file is merged, never overwritten, and the previous version is kept as .bak. The tools: check_package and check_packages (install-time decision, signals, advisories with CVSS, EPSS, KEV and fixed-in, a safe version), upgrade_plan, scan_project, dependency_paths, package_dependencies, blast_radius, get_vulnerability, search_vulnerabilities, model_risk, model_load_safety, check_model_file and machines_with_package, plus the cyberxyz-dependency-policy prompt.

xyz hook check-install

The hook that --hooks installs. Before Claude Code runs a shell command, it reads the command the way the shell does and checks npm|pnpm|yarn|bun add/install <pkg>, pip and uv pip install (including the exact pins in -r requirement files), uv add, poetry add, pipx install, go get / go install and dotnet add package in one call. Blocked or quarantined packages are denied with the reason and a safe version. Lockfile installs pass: the proxy checks what they fetch. It fails open with a warning if CyberXYZ is unreachable unless --fail-closed, and it never auto-approves a command.

The hosted MCP server

Nothing to install: https://mcp.cyberxyz.io/mcp speaks MCP over HTTP. Without a token it offers the public tier (the public verdict, advisories, package search and model reports). With Authorization: Bearer <token>, where the token is a dashboard API key (sk_xyz_) or the token xyz login creates, it offers the signed-in tools; scan_project is replaced by check_dependencies because the hosted server cannot read your files.

shell
claude mcp add --transport http cyberxyz https://mcp.cyberxyz.io/mcp \
  --header "Authorization: Bearer <token>"

Lookups from the MCP servers and the hook identify themselves, so asking about a package is never counted as installing it.

12 · platform

The dashboard

Signed in, the CLI reports to your organization. Where each run lands:

CommandIn the dashboardOpt out
xyz audit (all subcommands)XYZ Scan page, machine audits; the machine's inventoryalways uploads
xyz audit modelsXYZ Scan page, AI models--no-upload
xyz fixXYZ Scan page, project dependencies--no-upload
xyz code-scanXYZ Scan page, code; secrets triage--no-upload, XYZ_NO_UPLOAD=1
xyz depalert scan --uploadXYZ Scan page, CI gatesoff by default
The proxy and the agentProxy Monitor (every install) and Machines (routing report, agent version, network lock, alerts)xyz proxy remove

Secrets triage. On a code scan's report, mark each secret rotated, removed, false positive, accepted risk (with an expiry) or assigned. A removed secret is verified by the next scan.

From the terminal:

shell
xyz scans list --limit 10 --type npm       # your organization's scan history (--user EMAIL, --output-json)
xyz scans show <scan_id>
xyz history                                 # short form of scans list
xyz report html scan.json --open            # render a saved scan, audit or SARIF file
xyz report pdf scan.json                    # needs WeasyPrint
xyz report last
xyz diff base.json head.json --fail-on high # compare two scan or SARIF files; fails only on ADDED findings
xyz remediate run --dry-run                 # admin-approved removals queued for this machine

SBOM inventory

shell
xyz inventory upload ./my-app                         # runs syft locally
xyz inventory upload --sbom syft.json --source-ref "release-2026-09"
xyz inventory exposure <inventory_id> --all-rows

Exit codes for inventory upload: 0 no flagged rows, 1 a known-malicious row, 2 critical or high advisories only.

13 · reference

Command reference

Every command in 1.4.74. xyz COMMAND --help shows the options.

CommandWhat it does
login, logoutBrowser sign-in (MFA, SSO, passkeys); revoke and clear the session
status, infoSession, machine and environment; API version, health and your sign-in
proxy setup | status | restart | whoami | remove | daemon | agent-hintsRoute installs through the proxy and manage the agent; optionally tag installs made by AI coding agents
audit [npm | python | venvs | go | nuget | ide | browser | system | models | exposure]Audit what is installed on this machine; exposure lists the credentials an install-time payload could read
check PACKAGE VERSIONThe proxy's verdict for one package version
fix, impact, sbomUpgrade plan; blast radius; CycloneDX or SPDX SBOM
code-scan secrets | iac | code | ci | image | all | enginesSecrets, IaC, SAST, CI pipeline hardening and container-image scanning
depalert scanCI/CD gate on lockfiles or inline packages
ci init | protectWrite the gate into your pipeline; route a CI job's installs through the proxy
mcp install | serve | statusMCP server for AI coding agents
hook check-installClaude Code install hook
scans list | show, historyScan history
report html | pdf | last, diffRender and compare saved scans
inventory upload | exposureUpload an SBOM and get exposure
remediate runRun admin-approved removals queued for this machine
package NAME, vuln ID, recent, statsSearch advisories by package or id, recent advisories, database statistics
upgradeUpgrade the CLI to the latest release

Global options: --api-key, --api-url, --debug, --version.

14 · maintenance

Upgrade and sign out

shell
xyz upgrade            # or: pipx upgrade cyberxyz-scanner
xyz logout

xyz upgrade upgrades cyberxyz-scanner in the environment that runs the CLI and restarts a per-user agent. A root agent restarts onto the new version by itself within a few minutes; sudo xyz proxy restart does it now. xyz logout revokes the CLI session and clears it; the proxy stays wired up.

15 · reference

Config and env vars

VariableEffect
XYZ_API_KEYAPI key (sk_xyz_) used instead of a login session. The usual choice for CI
XYZ_API_URLPlatform base URL. Default https://api.cyberxyz.io
XYZ_ENROLLMENT_TOKENOrg enrollment token for xyz proxy setup
XYZ_NPM_PROXY_URL, XYZ_PIP_PROXY_URL, XYZ_GO_PROXY_URL, XYZ_NUGET_PROXY_URLProxy endpoints the agent enforces when setup did not record one
XYZ_EMAIL, XYZ_PASSWORDLegacy password login only
XYZ_NO_UPLOAD=1Turn the dashboard upload off by default (--upload still wins)
XYZ_NO_UPGRADE_HINT=1Hide the "system agent is on older code" line
XYZ_CODE_SCAN_FORCE_TARGET=1Same as --force-target
XYZ_DASHBOARD_URLDashboard base URL for links in the output

Local state lives in ~/.xyz/: config.json holds the CLI session (owner-only). Under the system service the machine token lives in /Library/Application Support/CyberXYZ/, /etc/cyberxyz/ or %ProgramData%\CyberXYZ\; otherwise in ~/.xyz/machine-token. Pass --debug for verbose output.

16 · help

Troubleshooting

You seeWhat to do
Agent code : 1.4.68 running, 1.4.74 installed in xyz proxy status, or the upgrade hintThe agent is outdated. Run sudo xyz proxy restart (an elevated PowerShell on Windows), or wait a few minutes: agents from 1.4.66 restart themselves
A tool shows NOT ROUTEDRun xyz proxy setup again, or wait for the agent's next check (every minute). Check your shell startup files for NPM_CONFIG_REGISTRY, PIP_INDEX_URL or GOPROXY=direct, which are reported but never edited
The last report is older than 15 minutesThe agent is not running. xyz proxy restart; if it is not installed, xyz proxy setup (add --system on managed machines)
engine not installed: IaC scanning needs trivy on PATH (exit 3)xyz code-scan engines --install, or the printed command. --skip-missing runs what is installed
Partial: secrets scanned, IaC and SAST skippedSome engines are missing, so this is not a clean result. Install them, or add --fail-on-partial so CI fails (exit 5)
Code scan refuses the target (exit 2)You pointed it at /, your home, the temp directory or a folder with no project markers. Run it from the project, or pass --force-target
xyz fix exits 1A flagged package has no clean release above the installed version. See the options for findings with no fixed version: a partial upgrade, removal, or an ignore with an expiry
Session expired, or "not logged in"The session was unused for 90 days or revoked. Run xyz login. With only XYZ_API_KEY set, xyz status says "not logged in" but requests still use the key
xyz login --password: "This account requires MFA/SSO"Use plain xyz login (browser sign-in)
Installs land as unattributed in the dashboardxyz proxy whoami. If the config carries no machine token, run xyz proxy setup --machine-name "..." again
A package still installs from nuget.orgNuGet is not covered by the network lock; check NuGet.Config in xyz proxy status
Scan now does nothingxyz proxy status shows whether the agent runs and when it last reported. xyz proxy restart, or xyz proxy daemon --once to debug. Machines set up with --no-install-daemon cannot run Scan now
depalert scan exits 4CyberXYZ could not be reached or a manifest could not be read; the result is never treated as clean. Check XYZ_API_KEY and the file path
17 · links

Resources

CLI FAQ

Questions, answered.

How do I install the CLI?

pipx install cyberxyz-scanner (or pip install cyberxyz-scanner), then xyz login (browser sign-in) and xyz proxy setup. The command is xyz, and xyz upgrade keeps it current.

Do I need an account to scan a package?

Enrolment ties results to your organisation and unlocks the install proxy and the dashboard. For a single public verdict without an account, the package checker on the website answers the same question.

What is the difference between the CLI and the install proxy?

The CLI answers when you ask. The proxy answers on every install, including the ones a script starts without you. Most teams run both: the proxy as the always-on gate, the CLI for audits and CI.

Does scanning send my source code anywhere?

Dependency scans send only package names and versions. xyz code-scan runs its engines on your machine; when you are signed in it uploads each finding with its file, line and a short code snippet (secret findings carry no snippet, and secret values are never sent). --no-upload keeps everything local.

// the ask

Catch it in the editor,
not in production.

See the extension, the CLI and the dashboard in a 15-minute walkthrough. The extension is included in every plan, from $25 per developer per month, with a 30-day proof of value.

  • ✓ In every plan, from $25/dev/month
  • ✓ npm · PyPI · Go · NuGet
  • ✓ 30-day proof of value
✓

Thanks! We'll be in touch.

Check your inbox. We'll reach out within 24 hours.

Get a demo

We'll respond within 24 hours. No spam, ever.