cyberxyz-scanner
CyberXYZ Security CLI. Real-time supply-chain protection for npm, PyPI, Go and .NET (NuGet) on macOS, Linux and Windows.
The CLI pairs with the CyberXYZ platform to give you per-machine package inventory, proxy
enforcement on every npm, pip, go and dotnet install, and CI/CD gating on flagged
dependencies. It is the implementer's interface to a platform that also exposes the same
controls in a web dashboard.
Full documentation: cyberxyz.io/docs/cli.html covers install, login, proxy setup, every audit subcommand, API key auth, CI/CD integration, config / env vars, and troubleshooting. This README is the quick start.
Install
The package is published on PyPI as cyberxyz-scanner. The CLI binary it installs is named
xyz.
With pip
pip install cyberxyz-scanner
With uv
uv pip install cyberxyz-scanner
Verify the install:
xyz --help
Quick start (one-time per machine)
# 1. Sign in. Opens your browser at app.cyberxyz.io; sign in the way you do on the
# dashboard (password + authenticator app or passkey, or SSO), check the code
# matches the terminal, and approve. The CLI never sees your password.
xyz login
# 2. Enroll this machine. One command:
# - Registers the device with your organization
# - Points npm (~/.npmrc), pip, Go (GOPROXY) and NuGet at the CyberXYZ proxy,
# for each one that is installed
# - Installs the background service for dashboard "Scan now" support
# (LaunchAgent on macOS, systemd --user on Linux, Task Scheduler on Windows)
xyz proxy setup --machine-name "Alex's MacBook"
Over SSH or on a headless box, xyz login --no-browser prints the link and code to open
on any other device (the browser is also skipped automatically when SSH_CONNECTION is set
or Linux has no display). The legacy email and password prompt is still available as
xyz login --password (or $XYZ_EMAIL / $XYZ_PASSWORD for scripts); accounts with MFA
or an SSO-enforcing organization must use the browser login. xyz logout revokes the
session on the server and removes it locally.
The CLI 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 only sign in
once; a machine that stays off for 90 days signs out.
It is stored owner-only in ~/.xyz/config.json. Each
machine's session is listed under Settings > CLI sessions in the dashboard, where you
(or an org admin) can revoke it. Login codes expire after 10 minutes and work once: only
approve a code you just requested yourself, never one someone sent you.
That's it. Every later install on this device goes through the CyberXYZ proxy: the exact package version is checked before it downloads, blocked or quarantined packages are refused with the reason, and the install shows up in your dashboard.
For fleets, skip the interactive login: an org admin creates an enrollment token in the
dashboard (Machines > Enrollment) and MDM runs
xyz proxy setup --enrollment-token pxe_xyz_... (or places the token at
/Library/Application Support/CyberXYZ/enrollment-token).
For environments that should not run a long-running background process (CI build agents,
sealed builds), pass --no-install-daemon.
On company-managed machines, install the agent at system level so developers cannot stop it:
sudo xyz proxy setup --system # macOS / Linux
xyz proxy setup --system # Windows, from an elevated PowerShell
This installs a root/SYSTEM service (macOS LaunchDaemon io.cyberxyz.agent, Linux
cyberxyz-agent.service, Windows scheduled task CyberXYZAgent) that starts at boot and
restarts if it is killed. The macOS .pkg does the same, and enrolls automatically when MDM
places an enrollment token at /Library/Application Support/CyberXYZ/enrollment-token.
Without --system (or without admin rights) setup installs the per-user service as before.
Always-on protection
Every minute the background agent checks what each package manager will actually use, repairs anything that no longer points at the CyberXYZ proxy, and reports the result to the dashboard with its heartbeat. Repairs never remove a private or internal registry, and config files are only written for tools that are installed:
| Tool | What is checked and repaired |
|---|---|
| npm, pnpm | ~/.npmrc registry + token, pnpm's global rc; as root also <npm prefix -g>/etc/npmrc |
| yarn | ~/.yarnrc.yml npmRegistryServer (token scoped to the proxy host under npmRegistries) and registry in ~/.yarnrc |
| bun | ~/.bunfig.toml [install] registry |
| pip | user pip.conf / pip.ini: the proxy is the index-url; extra indexes on pypi.org are removed, private indexes are kept; as root also the system file |
| uv | uv.toml: the proxy is the default [[index]]; pypi.org indexes are removed, private indexes are kept; as root also the system uv.toml |
| Go | GOPROXY=<proxy>,direct (the proxy refuses blocked modules with 403, so there is no fall-through); <proxy> only while the network lock is on; as root also $GOROOT/go.env |
| NuGet | NuGet.Config: the CyberXYZ source is added and nuget.org sources removed; private feeds are kept |
| Poetry | cannot be forced globally, so it is covered by the network lock only |
The system-level agent does this for every local user account, writing files owned by that
user. The machine token is stored where the agent can always read it
(/Library/Application Support/CyberXYZ/machine-token, /etc/cyberxyz/machine-token,
%ProgramData%\CyberXYZ\machine-token, or ~/.xyz/machine-token per user), so deleting a
config file only gets it rewritten. Registry overrides in shell startup files
(NPM_CONFIG_REGISTRY, PIP_INDEX_URL, GOPROXY=direct, ...) and in the Windows user
environment are reported, never edited.
Network lock. When an org admin turns it on, the system-level agent also 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. NuGet is not locked yet (it relies on config). Edits to the
lock are reverted and reported, and the block is removed when the org turns it off.
xyz proxy remove and uninstalling the service are reported to the dashboard before anything
is removed. Under the system service, only an administrator can remove it
(sudo xyz proxy remove). xyz proxy status shows the per-tool report, the service level,
the network lock state, when the agent last reported, and whether the agent is running the CLI
version that is installed. It works without sudo under the system service: config tokens are
compared with a fingerprint (sha256) the service publishes, never with a per-user copy.
Upgrades. pip install -U / pipx upgrade cannot restart a root service. The agent
(1.4.66+) notices the new version on disk and restarts onto it by itself within a few minutes,
between jobs. sudo xyz proxy restart does it immediately; the first CLI run after an upgrade
says so when the system agent is still on older code.
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; the developer sees "retry in a minute") or allow unchecked. Org admins change it in Settings > Supply-chain proxy.
Audit installed packages
Each command below audits the matching ecosystem on this machine, runs the CyberXYZ watchlist + deep check on suspect packages, and uploads the full inventory to the platform.
xyz audit npm # local + global node_modules
xyz audit python # active Python environment via pip
xyz audit venvs # every virtualenv / conda / pipx environment on the disk
xyz audit go # modules of the current Go module / GOPATH
xyz audit nuget # packages.lock.json files under cwd
xyz audit ide # VS Code / Cursor / Windsurf / VSCodium extensions
xyz audit browser # Chrome / Edge / Brave / Firefox extensions
xyz audit system # Homebrew, apt, rpm, winget, Chocolatey, macOS apps
xyz audit models # AI model files and Hugging Face references (see below)
xyz audit # npm, python, venvs, go, ide, browser and system back-to-back
A bare xyz audit does not run nuget (it needs a lockfile) or models; run those on
their own.
By default each command uses the watchlist pre-filter for speed (~25-40s on a typical
machine). Pass --full to skip the pre-filter and deep-check every package (slower but
covers advisory-only matches at scan time).
Conda environments (1.4.70+): a Python package that conda installed from an Anaconda or
conda-forge channel is not a PyPI package, so xyz audit python / venvs tell the API
where it came from. A conda-only name that PyPI does not have (for example
anaconda-anon-usage) is listed as ? name@version not checked: conda channel defaults
instead of being quarantined as "not on the public registry"; there is no conda registry
we index to check it against. Known-malicious and advisory checks still run by version,
and anything pip or uv installed into a conda env gets the full PyPI checks. A package
counts as conda-installed only when its INSTALLER file says conda and the env's
conda-meta/ records it.
Fix, blast radius, SBOM and AI models (1.4.62+)
All four read the manifests and lockfiles in the current directory, the same ones
depalert scan reads: 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 fix: an upgrade plan for flagged dependencies
xyz fix # plan only: package, current, issue (KEV badge), → target, why
xyz fix --write # show a unified diff, confirm, then edit the specs
xyz fix --write --yes # no prompt (CI bots)
xyz fix --json
Every package is checked in one /proxy/check/batch call. For each flagged one
(block, quarantine, alert, or any advisory) the plan gives the nearest clean release
above the installed version. A clean installed version is never told to move. A
transitive package is traced to the direct dependency that pulls it ("via express →
debug, bump express"); transitive pins are never edited.
--write edits only direct dependency specs: package.json (keeps ^ / ~ / >=
and the file's formatting; complex ranges are listed for a manual edit) and == pins
in requirements*.txt (extras, markers and comments kept; hash-pinned lines are left
for pip-compile). Lockfiles are never touched: run npm install, poetry lock,
uv lock or pip-compile afterwards. Exit codes: 0 plan complete, 1 a flagged
package has no clean target, 4 backend unreachable.
xyz impact: who is exposed when a package goes bad
xyz impact debug --version 2.6.8 # ecosystem guessed from the project, else npm
xyz impact requests -e pypi --json
Prints the direct dependents and whether each declared range admits the affected version, how many packages reach it on a required path vs only through an optional extra, and the top paths. Run 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: CycloneDX 1.5 or SPDX 2.3
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 (pkg:npm/…, pkg:pypi/…, pkg:golang/…, pkg:nuget/…),
the version and a scope (required / optional; dev dependencies are excluded),
and the dependency graph comes from the lockfile when it records one. Vulnerabilities
list the advisory ids, CVSS and EPSS ratings, a cyberxyz:kev property for CISA KEV
entries, and the safe version as the recommendation.
xyz audit models: AI model artifacts
xyz audit models # cwd + 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 (files over --max-hash-size are listed as UNHASHED),
Hugging Face references in code (from_pretrained, hf_hub_download, pipeline(model=…),
snapshot_download, flagging trust_remote_code=True), and models in
~/.cache/huggingface/hub. Files are never loaded or unpickled. The table shows each
repo or file with its verdict, load safety, trust_remote_code and reasons. NOT WATCHED,
PENDING and UNSCANNED are not verdicts. Exit 1 when anything is MALICIOUS.
KEV
When an advisory is in CISA's Known Exploited Vulnerabilities catalog, a bold KEV
marker leads the score cell in depalert scan, the vulnerability tables and the
xyz fix plan, and SARIF results carry "kev": true (plus a kev rule tag).
Use CyberXYZ from AI coding agents (MCP)
xyz mcp serve is a Model Context Protocol server:
Claude Code, Cursor, VS Code (Copilot agent mode), Windsurf, Codex CLI and Gemini CLI
call it to check packages, vulnerabilities, dependencies and AI models before they add
or install anything. It uses your xyz login session (or XYZ_API_KEY), needs
Python 3.10+ (the mcp package installs automatically there), and only ever speaks the
protocol on stdout.
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
| Client | --scope user |
--scope project |
|---|---|---|
claude-code |
claude mcp add --scope user (else ~/.claude.json) |
claude mcp add --scope project (else .mcp.json) |
cursor |
~/.cursor/mcp.json |
.cursor/mcp.json |
vscode |
printed (code --add-mcp … / MCP: Open User Configuration) |
.vscode/mcp.json (servers, type: stdio) |
windsurf |
~/.codeium/windsurf/mcp_config.json |
global only |
codex |
~/.codex/config.toml [mcp_servers.cyberxyz] |
global only |
gemini |
~/.gemini/settings.json |
.gemini/settings.json |
Files are merged, never overwritten (other servers and settings stay), the previous
version is kept as .bak, and a file that is not plain JSON (comments) is left alone
with the snippet printed. --rules adds the CyberXYZ dependency policy where the agent
reads rules (CLAUDE.md, AGENTS.md, GEMINI.md, .github/copilot-instructions.md
between markers, after asking; .cursor/rules/cyberxyz.mdc, .windsurf/rules/cyberxyz.md).
Tools
| Tool | What the agent gets |
|---|---|
check_package / check_packages |
install-time decision (allow / alert / quarantine / block) with behaviour signals (malicious release, typosquat, install scripts, dependency confusion, org block), advisories with CVSS / EPSS / KEV / fixed-in, a safe version and a one-line recommendation |
upgrade_plan |
is the installed version affected, nearest clean release above it, latest clean |
scan_project |
every manifest / lockfile in the project checked, flagged packages with the path from a direct dependency, what to bump, npm overrides |
dependency_paths / package_dependencies / blast_radius |
why a transitive package is installed, what a package pulls in, who depends on a bad version |
get_vulnerability / search_vulnerabilities |
one advisory in full; the advisory corpus by package, text, ecosystem, severity |
model_risk / model_load_safety / check_model_file |
Hugging Face model dependency risk, per-file load safety, lookup by sha256 |
machines_with_package |
which machines in your organization installed a package, at which version |
Plus the cyberxyz-dependency-policy prompt and resource: check before adding, never
install block / quarantine, prefer the safe version, unknown needs a human, never
trust_remote_code or pickle-load a model that is not CLEAN.
Install hook (Claude Code). --hooks adds a PreToolUse hook on Bash that runs
xyz hook check-install: npm|pnpm|yarn|bun add/install <pkg>, pip / uv pip install <pkg>, uv add, poetry add, pipx install, go get / go install, and
dotnet add package are checked in one call, and blocked or quarantined packages are
denied with the reason and a safe version. Lockfile installs (npm install, npm ci,
pip install -r …) pass: the proxy checks what they fetch. --hook-strict asks you on
alerts; the hook fails open with a warning if CyberXYZ is unreachable unless
--hook-fail-closed is set. It never auto-approves a command.
Lookups from the MCP server and the hook identify themselves (X-XYZ-Client: mcp /
agent-hook) so the platform can keep them out of the install log: asking about a
package is not installing it.
Which installs did an agent make? (1.4.71+). Coding agents set a marker in the
shells where they run commands (AI_AGENT, CURSOR_AGENT, CODEX_THREAD_ID,
COPILOT_AGENT, GEMINI_CLI, ...). The CLI sends it as X-XYZ-Agent. For npm and pip,
opt in with xyz proxy agent-hints --enable (or xyz proxy setup --agent-hints): in an
agent's shell npm and pip then add xyz-agent/<name> to their user agent, and the
dashboard marks those installs and registry misses as agent-driven. A person's terminal
is unchanged, nothing is inferred, and --disable removes the hook.
Other useful commands
# One-off safety check on a single package + version
xyz check axios 1.14.1 -e npm
# CI/CD gate. Non-zero exit on flagged packages.
xyz depalert scan --package-lock package-lock.json --fail-on block
xyz depalert scan --requirements requirements.txt --fail-on quarantine
xyz depalert scan --requirements poetry.lock # also Pipfile.lock, uv.lock
xyz depalert scan --go-sum go.sum
xyz depalert scan -p axios@1.14.1 -p lodash@4.17.21
# SBOM upload (runs syft on a path, or takes a Syft / CycloneDX JSON SBOM)
xyz inventory upload ./my-app
xyz inventory upload --sbom syft.json
# Diagnostic / housekeeping
xyz --version
xyz proxy status # proxy config per tool, service level, network lock
xyz proxy whoami # what (org, machine) does my token resolve to
xyz proxy restart # restart the agent onto the installed CLI (sudo for the system service)
xyz proxy remove # restore default registries (reported to your dashboard)
xyz scans list # history of recent scans for your org
xyz upgrade # pull the latest release from PyPI
Code, IaC, secrets and image scanning (code-scan)
xyz code-scan runs open-source scanners installed on your machine (it can install missing
ones with your own package manager, after asking) and merges what they report into one table,
JSON document or SARIF 2.1.0 file. It works without logging in; when you are signed in the
results also go to your CyberXYZ dashboard (--no-upload or XYZ_NO_UPLOAD=1 to opt out;
secret values are never sent). For installed packages use xyz audit.
Run it from a project. /, 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 unless --force-target.
xyz code-scan secrets . # hardcoded credentials (values always redacted)
xyz code-scan iac ./infra # Terraform, CloudFormation, Kubernetes, Helm, Dockerfile
xyz code-scan image python:3.11-slim --sbom sbom.cdx.json # vulns + misconfig + secrets, CycloneDX SBOM
xyz code-scan code . # SAST with the built-in xyz rules
xyz code-scan code . --config ./my-rules.yml # add your own opengrep rules
xyz code-scan all . --format sarif -o xyz.sarif --fail-on high
xyz code-scan engines # which engines are installed, versions, paths
| Command | Engine | Fallback / option |
|---|---|---|
secrets |
gitleaks (dir on 8.19+, detect --no-git before) |
trivy fs --scanners secret, or --engine trivy |
iac |
trivy config |
checkov with --engine checkov |
image |
trivy image (vuln, misconfig, secret) |
--sbom FILE writes CycloneDX |
code |
opengrep + built-in xyz rules + any --config |
without opengrep: bandit for Python, gosec for Go |
all |
secrets + iac + code, merged |
--skip-missing runs whatever is installed; add --fail-on-partial to exit 5 when a scanner was skipped |
The built-in rules (xyz_cli/rules/) cover supply-chain patterns: shell=True and
os.system with dynamic commands, eval/exec 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 keys and private keys, disabled TLS verification
(verify=False, NODE_TLS_REJECT_UNAUTHORIZED=0, InsecureSkipVerify), child_process.exec
with template strings, and npm install scripts that download binaries. Without opengrep the
built-in rules do not run and xyz says so.
Common options: --format table|json|sarif, -o FILE, --fail-on critical|high|medium|low|none
(default low, meaning any non-info finding fails), --timeout SECONDS per engine (default
900). Severities are normalised to critical/high/medium/low/info, paths are relative to the
scanned directory, and duplicate findings are merged, including the same secret found by two
engines. Secret values are never printed in any format; secret findings carry no snippet.
SARIF suppressions (# nosec, nosemgrep, gitleaks:allow) are honoured.
| Exit | Meaning |
|---|---|
| 0 | Clean: nothing at or above --fail-on |
| 1 | Findings at or above --fail-on |
| 2 | Usage error |
| 3 | Engine not installed: a requested scanner could not run (the install command for your OS is printed) |
| 4 | Engine error: non-zero exit, timeout, or no report (the engine's stderr tail is printed) |
| 5 | Partial, opt-in (all --skip-missing --fail-on-partial): nothing at or above --fail-on in the scanners that ran, but at least one was skipped because its engine is missing. Without --fail-on-partial, --skip-missing exits 0 in that case, as before |
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). instead of No findings,
and JSON, SARIF (runs[0].properties) and the dashboard upload carry status
(complete / partial / failed), coverage and one scanners entry per requested scanner
(ran, skipped with reason: "engine missing", or failed with reason: "engine error").
Installing the engines. xyz never downloads an engine itself. It looks on PATH and in
the usual install folders (Homebrew's bin, ~/.local/bin, ~/.opengrep/cli). When an
engine is missing and you are at a terminal, it asks once for all of them:
Missing engines for this scan:
trivy brew install trivy
opengrep curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bash
(official opengrep install script; installs to ~/.opengrep/cli and links ~/.local/bin/opengrep)
Install trivy and opengrep now (opengrep runs its official install script)? [Y/n]
On yes it runs your own package manager (or opengrep's official script), checks the engine is
now there and prints its version and path, and continues the same scan. --install-engines
installs without asking (for setup scripts), --no-install never asks. In CI (CI,
GITHUB_ACTIONS, GITLAB_CI, ...) or without a terminal xyz never asks and never installs;
it prints the command. xyz code-scan engines lists every engine with its version, path and
install command; xyz code-scan engines --install installs the missing ones.
Which installer xyz picks, from what the machine already has:
| Engine | macOS | Linux | Windows |
|---|---|---|---|
| trivy | brew install trivy |
brew install trivy if Homebrew is present; otherwise Aqua's official apt or rpm repository steps are printed for you to run (they need sudo) |
winget install --id AquaSecurity.Trivy --exact, else scoop install trivy |
| gitleaks | brew install gitleaks |
brew install gitleaks; otherwise printed: sudo apt-get install -y gitleaks or go install |
winget install --id Gitleaks.Gitleaks --exact, else scoop install gitleaks |
| opengrep | official script curl -fsSL https://raw.githubusercontent.com/opengrep/opengrep/main/install.sh | bash (there is no Homebrew formula and no PyPI package; the script verifies the release signature when cosign is installed) |
same | official install.ps1 from the same repo, via PowerShell |
The fallbacks are printed only, never installed by xyz:
| Engine | macOS | Linux | Windows |
|---|---|---|---|
| bandit | pip install "bandit[sarif]" |
same | same |
| gosec | brew install gosec |
go install github.com/securego/gosec/v2/cmd/gosec@latest |
same as Linux |
| checkov | pip install checkov |
same | same |
In CI. GitHub Actions: run xyz code-scan all . --format sarif -o xyz.sarif and upload
the file with github/codeql-action/upload-sarif (set if: always() on the upload so
findings still show when the gate fails). Each run is tagged
automationDetails.id = xyz-code-scan/<scan>/, so secrets, iac and code can be
uploaded separately without replacing each other.
- run: pip install cyberxyz-scanner "bandit[sarif]"
- run: go install github.com/zricethezav/gitleaks/v8@latest && echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
- 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
GitLab CI: run the same command in a job and keep xyz.sarif (or --format json) as a job
artifact. GitLab's Security dashboard reads its own report format, not SARIF, so treat the
exit code as the gate.
Licensing. xyz uses Trivy (Apache-2.0), Gitleaks (MIT), Opengrep (LGPL-2.1) as external engines, plus bandit (Apache-2.0), gosec (Apache-2.0) and checkov (Apache-2.0) when present. They run as separate programs; none of them is bundled. The built-in rules are CyberXYZ's own, released under MIT. xyz does not use or reference Semgrep Registry rules.
CI/CD integrations
Set XYZ_API_KEY as a secret and add one of these; any push or PR that pulls in a
malicious or vulnerable package fails the build with a clear reason.
- GitHub Actions:
uses: CyberXYZSecurity/depalert-action@v1(GitHub Marketplace) - GitLab CI/CD catalog:
gitlab.com/cyberxyz/depalert - Azure DevOps Pipelines:
integrations/azure-pipelines/cyberxyz-supply-chain.yml - Or generate one:
xyz ci init
Route the job's own installs through the proxy (protect)
scan checks lockfiles after the fact. protect runs early in the job and points npm,
yarn, pip, uv, Go and NuGet at the CyberXYZ proxy, so a malicious version is refused at
install time, the same way it is on laptops. Recommended: protect before the install
steps, scan as the gate.
# GitHub Actions
- uses: CyberXYZSecurity/depalert-action@v1
with:
api-key: ${{ secrets.XYZ_API_KEY }}
mode: protect # network-lock: true also blocks the public registries on the runner
- run: npm ci # goes through the proxy
- uses: CyberXYZSecurity/depalert-action@v1
with:
api-key: ${{ secrets.XYZ_API_KEY }} # mode: scan (default) gates on the lockfiles
GitLab: include gitlab.com/cyberxyz/depalert/protect@1.2.0 and add
extends: .cyberxyz-protect (or - !reference [.cyberxyz-protect, before_script]) to the
jobs that install dependencies. Any other CI: eval "$(xyz ci protect --format shell)"
with XYZ_API_KEY set. If CyberXYZ is unreachable, protect warns and the build carries
on unprotected; pass --strict (strict: true) to fail it instead.
The Action (cli-version) and the GitLab components (cli_version) install the newest
1.4.x CLI, at least 1.4.66 (>=1.4.66,<1.5), so CLI fixes reach your pipelines without a
new action release and a 1.5 never arrives unannounced. Pin an exact version ("1.4.70")
if you need reproducible runs, or pass latest.
All of them run the same xyz depalert scan engine your laptops use. It reads
package-lock.json, requirements*.txt, Pipfile.lock, poetry.lock, uv.lock and
go.sum.
depalert scan exit codes
| Exit | Meaning |
|---|---|
| 0 | Allowed |
| 1 | Block |
| 2 | Quarantine |
| 3 | Alert |
| 4 | Error, including a manifest that could not be read (it is never treated as clean) |
Re-enroll, rotate, remove
To rotate the proxy token on a device, re-run xyz proxy setup --machine-name "..." as
the same user who enrolled it. The platform replaces the old token and the daemon picks up
the new one at next restart. A machine name registered by another member of your org
can only be re-issued by an org admin; pick a different --machine-name otherwise.
To remove a device cleanly, delete it from the dashboard Fleet view. The deletion sweeps proxy_install_log, proxy_tokens, cli_scans, customer_inventory_uploads, customer_package_inventory and scan_jobs in one transaction. Re-enroll with the same command above.
Platform
- Dashboard: https://app.cyberxyz.io
- Documentation: https://cyberxyz.io/docs/cli.html
License
Proprietary. See LICENSE.
Contact
Email: support@cyberxyz.io
Metadata
Release files for cyberxyz-scanner 1.4.72
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cyberxyz_scanner-1.4.72.tar.gz | 481.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cyberxyz_scanner-1.4.72-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 804.3 kB
Release files / cyberxyz_scanner-1.4.72.tar.gz
| Download URL | cyberxyz_scanner-1.4.72.tar.gz |
|---|---|
| Size | 481.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3df3f9dca145beeea1f0baa34d288ab0a3ae7b78af691dea40a59760e04aeb89
|
|
BLAKE2b-256 checksum How to use checksums |
2336ad4b7a6c0612c22a446cb3109e2d943277ded0117c83b1e8f55e4a0e2567
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / cyberxyz_scanner-1.4.72-py3-none-any.whl
| Download URL | cyberxyz_scanner-1.4.72-py3-none-any.whl |
|---|---|
| Size | 322.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9790a6d6fba1207ca274b0932502e660909ffe7f14e7c325f18cf5eea1ac88d8
|
|
BLAKE2b-256 checksum How to use checksums |
b39f937c5f5e5988231e9854346e3c845fb470d9f110227429897f949bfc86b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency log