Skip to content
Phylax
Integration guides

Packages (PyPI / npm)

Verify what your build pulls in, before it runs.

Packages are the highest-volume artifact Phylax sees, and the only one where a single command pulls in hundreds of things you did not write. This guide takes you from nothing installed to a verified dependency tree.

1. Install Phylax

The CLI ships on npm and installs the phylax binary.

Terminal window
npm install -g @phyi/cli

Prefer not to install globally? Run it without installing:

Terminal window
npx @phyi/cli --version

Confirm it is on your PATH:

Terminal window
phylax --version

2. Authenticate (optional)

Every read endpoint is public, so verification works with no account at all. You only need a token when you want your organization’s policies applied to the verdict rather than the public default.

Terminal window
phylax auth login
phylax whoami

3. Verify, then install

This is the core loop. Verify the exact name and version you are about to add, read the verdict, and only then install it.

Step 1. Verify the package you intend to add.

Terminal window
phylax verify package pkg:npm/express@4.18.2

Step 2. Read the result.

verdict: allow
risk score: 12 / 100
provenance: verified
attestation: available

Step 3. Install the same version you just verified.

Terminal window
npm install express@4.18.2

4. Verify a whole lockfile

Verifying one package at a time is fine while you are adding a dependency. For an existing project, point Phylax at the lockfile instead: it resolves every pinned dependency and returns the strictest verdict in the tree.

Terminal window
phylax verify lockfile ./package-lock.json --fail-on block

Use the lockfile, not the manifest. A manifest records ranges; a lockfile records what you will actually install. The exit code carries the strictest verdict, so this drops straight into CI/CD Pipelines with no extra wiring.

Package references

Phylax identifies packages by package URL, the same pkg: string used by SBOM formats. It became an Ecma standard, ECMA-427, in December 2025, so the reference you pass Phylax is the one your SBOM, scanner and registry already agree on.

pkg:npm/express@4.18.2
pkg:pypi/requests@2.32.3
pkg:npm/%40asyncapi/specs@6.8.1
PartExampleNotes
Typenpm, pypiThe ecosystem. Determines how the rest is parsed.
Namespace@asyncapinpm scope or group. Percent-encode the @ as %40.
NameexpressRegistry name, case-sensitive for npm.
Version4.18.2Omit to resolve the latest published version.

The bare form works too. phylax verify package npm/express@4.18.2 is accepted and expanded for you.

What Phylax checks

Integrity Verifies checksums and detects tampered artifacts.
Provenance Validates origin, publisher identity, and build provenance.
License Confirms license information and flags incompatible terms.
Vulnerabilities Scans for known CVEs, malicious code, and risky dependencies.

Name confusion is folded into the provenance check. Typosquatting remains the cheapest attack on both registries: one 2024 campaign published over 500 variations of names like requests, TensorFlow and BeautifulSoup, and reqeusts reads as requests to a tired human every time.

Reading a verdict

verdict:
allow
risk score:
12 / 100
provenance:
verified
attestation:
available
Field reference
FieldMeaning
verdictallow, warn or block. Drives the exit code.
risk score0 to 100. Higher is worse. Thresholds are set by policy.
provenanceWhether the artifact traces to a verified publisher and build.
attestationWhether a signed attestation exists to fetch and verify offline.

Install is the dangerous step

Worth internalising: for packages, installing is not a separate, safe action that happens after verification. On both ecosystems, installing can execute code from the package before you have imported a single line of it.

Lifecycle scripts (preinstall, postinstall, prepare) run automatically with your full user privileges. They have been the lowest-friction malware path on npm for years.

npm v12, shipped July 2026, blocks install scripts, Git dependencies and remote sources by default. On anything older, set it yourself:

.npmrc
ignore-scripts=true
Terminal window
npm ci --ignore-scripts

Where the two ecosystems differ

npmPyPI
Install-time executionLifecycle scriptssetup.py in an sdist
Safe artifact formNo equivalentWheel (.whl)
Turn it offignore-scripts=true, default in v12+--only-binary=:all:
Pin the treepackage-lock.json + npm ci--require-hashes
Still exposed toImport-time and runtime code, bin entriesImport-time and runtime code

Defence in depth

No single control here is sufficient, and the recent incidents are precisely the cases where one control failed. These compose:

  • Verify the lockfile, not the manifest. Ranges resolve differently tomorrow.
  • Commit the lockfile and install from it with npm ci or --require-hashes.
  • Disable install-time execution, and do not treat that as having solved the problem.
  • Add a publication cooldown. Refuse versions published in the last N days, so you are never the one who finds the malicious release. Most compromised versions are pulled within hours.
  • Restrict CI egress. A payload that cannot reach its collection endpoint is a failed payload, and this is the control that holds when the others are bypassed.

Enforce all of this on every build with CI/CD Pipelines, check packages at the moment an agent loads them with the Agent Runtime Gate, or see every flag and exit code on the Phylax CLI page.

Did this page help you?