CLI Tool
Install and use the Ossprey CLI to scan projects and packages from your terminal or CI/CD pipeline.
Account requiredThis tool requires an account with Ossprey, and an API key. Visit ossprey.com to sign up for free.
The Ossprey CLI (ossprey) is a command-line scanner for the Ossprey supply-chain malware platform. It catalogues your project's dependencies into a custom SBOM (software bill of materials) format, submits it to the Ossprey API, and fails the build if any of those packages are known to contain malware. It parses the manifests of JS/Python projects, and resolves transitive dependencies with no installation.
The CLI supports:
- Scanning a project's dependencies via the
scancommand - Ad-hoc checking of dependencies via the
checkcommand - JS/Python package manager pass through, check packages before installation
ossprey npm i <package>etc.
The CLI ships as a single self-contained binary via GitHub Releases. There is no pip, npm or Homebrew package. It currently covers Python and JavaScript projects.
Installation
Prebuilt binariesPrebuilt binaries are published for Linux, macOS and Windows (amd64 and arm64). No interpreter or runtime is required. If you need help, please raise an issue on GitHub.
One-liner (Linux / macOS)
curl -fsSL https://github.com/ossprey/ossprey-cli/releases/latest/download/install.sh | sudo shThe script detects your OS and architecture, downloads the matching binary, verifies its sha256 checksum, and installs it to /usr/local/bin/ossprey.
Before installing, check out the full contents of the script here.
Override the defaults with environment variables to pin to a version:
# Pin a specific version
curl -fsSL https://github.com/ossprey/ossprey-cli/releases/latest/download/install.sh \
| OSSPREY_VERSION=v0.1.0 sudo -E sh
# Install to a user-writable dir (no sudo)
curl -fsSL https://github.com/ossprey/ossprey-cli/releases/latest/download/install.sh \
| OSSPREY_INSTALL_DIR=$HOME/.local/bin shManual download
Grab the binary directly from the releases page:
ossprey-linux-amd64β Linux x86_64ossprey-linux-arm64β Linux arm64ossprey-darwin-amd64β macOS Intelossprey-darwin-arm64β macOS Apple Siliconossprey-windows-amd64.exeβ Windows x86_64ossprey-windows-arm64.exeβ Windows arm64
chmod +x the binary and drop it on your PATH. Each asset ships with a .sha256 sidecar for verification. Pin a specific tag by replacing latest/download with download/<tag> in the URL.
From source
git clone https://github.com/ossprey/ossprey-cli.git
cd ossprey-cli
make tidy # first time
make build # produces bin/osspreyRequires Go 1.25 or above.
Once installed, verify it is working:
ossprey --version
ossprey --helpAuto scan dependencies before installation
Ossprey CLI ships with pass through support for common package managers for JS and Python ecosystems. We support npm, pip, poetry, uv, and yarn. Configuring your .bashrc or .zshrc with
alias npm="ossprey npm" will allow Ossprey CLI to be invoked before the NPM command. This will intercept package installations, and scan them. If we detect malware, we block the installation.
Authentication
The CLI requires an API key to submit scans to the Ossprey service. The key is read from the following sources, in order:
--api-keyflagOSSPREY_API_KEYenvironment variable (recommended for CI/CD)API_KEYenvironment variable (legacy fallback β preferOSSPREY_API_KEY)
Ossprey API keys look like ospy_ followed by 64 hex characters.
The --local, --dry-run-safe and --dry-run-malicious modes do not talk to the API and do not need a key.
Managing API keysFor details on generating and managing your API key, see the API Keys page in the dashboard.
scan β scan a project
scan β scan a projectCatalogue a directory and check it for malware.
ossprey scan [path] [flags]path defaults to the current directory.
Flags:
-o,--outputβ write the OSSBOM JSON to a file, in addition to running the scan.-v,--verboseβ verbose logging.--localβ catalogue only: dump the OSSBOM to stdout and exit. No API submission, no verdict, no key required.--dry-run-safeβ skip API submission and emit an empty vulnerability list. No key required.--dry-run-maliciousβ skip API submission and inject a test finding against the first component. Useful for testing alerting and CI/CD failure behaviour. No key required.--no-version-lookupβ don't query the registry to resolve unpinned dependencies; leave them versionless. See Unpinned dependencies below.--urlβ override the Ossprey API URL (defaulthttps://api.ossprey.com).--api-keyβ provide the API key on the command line instead of an environment variable.--versionβ print the CLI version.
Usage examples
Scan the current directory:
export OSSPREY_API_KEY=ospy_...
ossprey scan .Scan a specific directory:
ossprey scan ./my-project --api-key YOUR_KEYDry run to test your setup (no API key needed):
ossprey scan ./my-project --dry-run-safe -vCatalogue only, write the OSSBOM to a file:
ossprey scan . --local -o sbom-output.jsoncheck β scan named packages
check β scan named packagesScan one or more packages by name, without a project on disk.
ossprey check --eco-system pypi [email protected]
ossprey check -e npm [email protected] [email protected]When a version is omitted, the latest published version is resolved from the registry (PyPI or npm) and checked. Both the name@version and pip's name==version forms are accepted.
Flags:
-e,--eco-systemβ package ecosystem,pypiornpm(required).--urlβ override the Ossprey API URL.--api-keyβ API key (or environment variable).--dry-run-safe/--dry-run-maliciousβ same behaviour as forscan.
Exit codes match scan: 1 on a malware verdict or error, 0 otherwise.
Package-manager forwarder
Wrap an install so packages are checked before they hit your machine. If any package is flagged, the install is blocked (exit 1) and the real package manager is never invoked; otherwise the command is forwarded unchanged.
ossprey npm install [email protected] [email protected]
ossprey yarn add [email protected]
ossprey pip install foo==1.2.3
ossprey poetry add foo
ossprey uv pip install foo==1.2.3Supported managers: npm, yarn, pip, poetry, uv. Non-install subcommands (npm run, pip list, β¦) are forwarded straight through with no check.
There are two modes, picked automatically:
- Named packages (e.g.
ossprey npm install foo bar) β every package named on the command line is checked. Flags, local paths, archives and VCS/URL targets are passed through; only real registry packages are checked. Transitive dependencies are not resolved here β runossprey scanafter install for full-tree coverage. - Manifest install (e.g. bare
ossprey npm install,npm ci,poetry install,uv sync, orpip install -r requirements.txt) β no packages are named, so the forwarder scans the current directory and checks every declared dependency before forwarding. It does not fall through unchecked.
If the registry can't be reached to resolve an unpinned named version, that package is skipped (fail-open) so a registry outage never blocks development. An install whose only targets are local paths or URLs β nothing checkable, and no manifest to scan β is forwarded with a warning.
The forwarder disables flag parsing so every argument reaches the real manager, so it is configured only through the environment:
OSSPREY_API_KEYβ API key.OSSPREY_API_URLβ override the API URL (defaulthttps://api.ossprey.com).
Supported ecosystems
Python and JavaScript, via static catalogers. The CLI never executes your package manager. If your repo has only a manifest and no lockfile, expect direct dependencies only β supply a lockfile for full transitive coverage.
- Python β
requirements.txt,Pipfile.lock,poetry.lock,uv.lock,pdm.lock,setup.py,pyproject.toml, wheel / egg metadata. - JavaScript β
package.json,package-lock.json,yarn.lock,pnpm-lock.yaml.
Vendored dependency trees (anything under node_modules/) are skipped β the CLI catalogues what your manifests and lockfiles declare, so an installed tree is never double-counted.
Packages defined locally in your own project (workspace members, path dependencies) are flagged as local rather than looked up in a registry, so your first-party code is never mistaken for a published package.
Unpinned dependencies
When a dependency's version can't be determined β an unpinned range in a manifest such as click = "^8", with no lockfile to pin it against β the CLI defaults that component to the latest published version in its registry: the version a fresh install would pull today. This gives a realistic verdict for projects that use open ranges instead of silently dropping the dependency.
Registry lookups fail open. If a version can't be resolved (you're offline, or the package is private or removed), the component is left unversioned rather than dropped or failing the scan.
To skip these lookups β for a fully offline catalogue, or for reproducibility β pass --no-version-lookup, or set OSSPREY_RESOLVE_LATEST=0. The environment variable also covers the package-manager forwarders, whose arguments are passed through untouched and so can't take the flag.
Environment variables
| Variable | Purpose |
|---|---|
OSSPREY_API_KEY | API key. Read by every command, including the forwarders. |
API_KEY | Legacy fallback for OSSPREY_API_KEY. |
OSSPREY_API_URL | Override the API URL for the package-manager forwarders (default https://api.ossprey.com). scan and check use the --url flag instead. |
OSSPREY_RESOLVE_LATEST | Set to 0 to disable resolving unpinned dependencies to the latest published version. |
OSSPREY_SCAN_CONCURRENCY | How many manifests to parse in parallel (default 8). Lower it on constrained CI runners. |
Exit codes
The CLI uses exit codes to communicate scan outcomes, which is important for CI/CD integration:
- Exit 0 β no malware found, a
--localdump, or the scan was skipped by the API (e.g. quota exhausted). - Exit 1 β malware was found, or the scan itself failed (bad path, catalog error, API/network error, missing key).
- Exit 2 β the CLI crashed unexpectedly. Please raise an issue with the output.
To distinguish "clean" from "errored" in CI, check stderr or parse the OSSBOM emitted via -o.
Scans skipped by quotaIf your daily or monthly package quota is exhausted, the API skips the scan and the CLI prints
Ossprey scan skipped:with the quota reset time, then exits0β a quota limit fails open so it never breaks your build. Check your usage on the Account page.
Output
ossprey scan prints No malware found on success, or one Error: WARNING: <pkg>:<ver> contains malware. Remediate this immediately line per finding on failure.
Pass -o sbom.json to also write the full OSSBOM JSON (components and vulnerabilities) to disk, or --local to emit it to stdout instead of calling the API.
CI/CD integration
GitHub Actions
The Ossprey CLI works as a step in any GitHub Actions workflow. Here is an example that scans your repository on every pull request:
name: Ossprey Scan
on:
pull_request:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Ossprey
run: curl -fsSL https://github.com/ossprey/ossprey-cli/releases/latest/download/install.sh | sudo sh
# To pin a release, use:
# .../releases/download/<TAG>/install.sh
- name: Run Ossprey scan
env:
OSSPREY_API_KEY: ${{ secrets.OSSPREY_API_KEY }}
run: ossprey scan .The CLI exits non-zero on a malware verdict, which fails the workflow.
Keep your key secretStore your API key as a GitHub Actions secret called
OSSPREY_API_KEY. Never hard-code your key in a workflow file.
Other CI/CD systems
The CLI is a single static binary with no runtime dependencies, so it works in any environment. Install it via the one-liner or a pre-downloaded binary, set OSSPREY_API_KEY, and run ossprey scan . as a build step.
Updated 19 days ago
