CLI overview¶
Primary command:
trustcheck inspect <project>
Package vulnerability scan:
trustcheck scan <project>
Dependency-file inspection or vulnerability scan:
trustcheck inspect -f <filename>
trustcheck scan -f <filename>
Installed environment scan:
trustcheck environment --path .venv/lib/python3.12/site-packages
Dependency update trust diff:
trustcheck diff requirements-old.lock requirements-new.lock
trustcheck diff --base origin/main --head HEAD --github-pr
Show the installed package and report schema versions:
trustcheck --version
Check local resolver, index, and provenance-verification prerequisites:
trustcheck doctor
doctor verifies that the selected Python can run python -m pip, reports
unsupported pip versions, detects externally managed Python installs, checks
resolver sandbox runtime availability, and validates that any configured
container resolver image is pinned by digest.
Core flags¶
--version: inspect a specific release instead of the latest project version--expected-repo: require repository evidence to match an expected GitHub or GitLab repository--format FORMAT: choosetext,json,sarif,cyclonedx-json,cyclonedx-xml,cyclonedx-1.7-json,cyclonedx-1.7-xml,spdx-json,spdx-3-json,openvex, ormarkdown--output-file PATH: write the rendered report to a file and suppress stdout--verbose: include per-file provenance, digest, publisher, and note fields in text output--with-osv: query the public OSV API--osv-url URL: query an additional OSV-compatible API; repeatable--with-ecosystems: query the Ecosyste.ms OSV-compatible API--with-kev: enrich CVEs from the CISA Known Exploited Vulnerabilities catalog--with-epss: enrich CVEs with FIRST EPSS probability and percentile scores--with-deps: inspect direct runtime dependencies and summarize the highest-risk dependency--with-transitive-deps: inspect direct and transitive runtime dependencies recursively--inspect-artifacts: statically inspect downloaded wheels and sdists--dynamic-analysis: experimental; run bounded install analysis for downloaded artifacts in a disposable Docker container with no network, a non-root user, digest-pinned image policy, and strict CPU/RAM/PID/time limits--dynamic-python 3.11|3.12|3.13|3.14: select the bounded-analysis Python profile; profiles without a configured analyzer image fail as unsupported--dynamic-image IMAGE@sha256:DIGEST: override the analyzer image with an explicit digest-pinned imagescan --fast: resolve dependencies and query advisories only (default)scan --standard: add provenance for artifacts in the selected scopescan --full: add static, native-binary, release-history, and heuristic analysisscan --artifact-scope target|sdist|all: inspect the best target-compatible install artifact (default), source distributions, or the complete release--trusted-project NAME: add a project to the typosquatting reference set; repeatable--strict: apply the built-in strict policy--policy default|strict|internal-metadata: evaluate a built-in policy profile--policy-file PATH: load policy settings from a JSON file--trusted-publisher-organization [PROVIDER:]ORGANIZATION: require verified publishers to belong to an approved organization; repeatableinspect -f <filename>: inspect every package in a requirements, project TOML, or supported lockfile without vulnerability checksscan -f <filename>: scan every package in a requirements, project TOML, or supported lockfile using the selected scan profilediff OLD_FILE NEW_FILE: review only dependency graph entries whose version, source, or index origin changeddiff --base REF --head REF --github-pr: discover changed dependency files from Git refs, compare the base and head bytes, and optionally post Markdown with--commentenvironment: inspect exact distributions installed in the active interpreter, or in repeatable--pathlocations
Resolver flags¶
--constraint FILE: apply a pip constraints file; repeatable--extra NAME: select a project optional-dependency extra; repeatable--group NAME: select a standard or Poetry dependency group; repeatable--python-version VERSION: resolve for a target Python version--platform TAG: resolve for a target wheel platform; repeatable--implementation TAG: resolve for an interpreter implementation such ascp--abi TAG: resolve for a target wheel ABI; repeatable
Package index flags¶
--index-url URL: primary PEP 503/691 Simple Repository index--extra-index-url URL: additional index; repeatable--keyring-provider auto|disabled|import|subprocess: pip-compatible credential provider--allow-dependency-confusion: continue after a cross-index name collision that has been independently reviewed--allow-insecure-index: explicitly allow HTTP package indexes and artifact URLs from those indexes
--extra-index-url is secure by default: trustcheck requires HTTPS indexes
unless --allow-insecure-index is set, validates artifact URL schemes and
redirect targets, strips credentials on cross-origin redirects, checks every
resolved name independently on each configured index, and stops when public and
private indexes both provide the name. Index credentials are redacted from
errors and JSON output.
The resolver reports dependency-confusion evidence using explicit resolver
terminology: pip behaves as a version-priority resolver across configured
indexes, and index trust order is not enforced by pip. Do not use
--allow-dependency-confusion as an index-priority switch; use it only after
the intended source index and artifact hashes have been independently
reviewed.
Policy override flags¶
--require-verified-provenance none|all--allow-metadata-only--disallow-metadata-only--require-expected-repo-match--trusted-publisher-organization [PROVIDER:]ORGANIZATION--fail-on-vulnerability ignore|any|critical|kev|fixable--fail-on-risk-severity none|medium|high
Network and diagnostics flags¶
--config-file PATH: load JSON, standalone TOML, or[tool.trustcheck]settings frompyproject.toml--timeout FLOAT: set request timeout in seconds--retries INT: set transient retry count--backoff FLOAT: set retry backoff factor--cache-dir PATH: persist cached PyPI responses for repeated runs--offline: use cached responses only--debug: emit structured debug logs and print tracebacks for operational failures--log-format text|json: choose debug log format for--debug
Examples¶
Inspect a package:
trustcheck inspect requests
Show only known vulnerability records:
trustcheck scan sampleproject --version 4.0.0 --fast
Add selected-artifact provenance without deep archive inspection:
trustcheck scan -f requirements.txt --standard
Run full analysis on the target-compatible install artifact:
trustcheck scan sampleproject --version 4.0.0 --full --workers 8
Review the complete release under strict policy:
trustcheck scan sampleproject --full --artifact-scope all --strict
Query OSV in addition to PyPI and show source, severity, fixes, and advisory links:
trustcheck scan jinja2 --version 2.10.0 --with-osv
Query all built-in advisory providers and enrich CVE aliases:
trustcheck scan jinja2 \
--version 2.10.0 \
--with-osv \
--with-ecosystems \
--with-kev \
--with-epss
The OSV-compatible providers run concurrently and merge deterministically with PyPI records. A provider or enrichment failure is an operational failure rather than silently returning partial intelligence.
The config file can enable the same services and override enrichment endpoints:
{
"advisories": {
"osv": true,
"osv_urls": ["https://advisories.example.com"],
"ecosystems": true,
"kev": true,
"kev_url": "https://www.cisa.gov/example/known_exploited.json",
"epss": true,
"epss_url": "https://api.first.org/data/v1/epss"
}
}
Run with strict policy:
trustcheck inspect sampleproject --version 4.0.0 --strict
Inspect the package and its direct dependency set:
trustcheck inspect sampleproject --version 4.0.0 --with-deps
Inspect the full transitive dependency tree:
trustcheck inspect sampleproject --version 4.0.0 --with-transitive-deps
Scan every package listed in a requirements-style file:
trustcheck scan -f requirements.txt
Requirements scans are resolved as complete environments with pip's
installation-report interface. Nested -r requirements, nested -c
constraints, hashes, extras, editable requirements, direct URLs, and VCS
requirements use pip's own parsing and resolution behavior.
Trustcheck invokes pip through the supported subprocess CLI,
python -m pip; it does not import or call unsupported pip._internal
modules. Resolver diagnostics require pip >= 22.2, the first supported
compatibility floor for dry-run installation reports.
Apply an additional constraints file and resolve for a target:
trustcheck scan -f requirements.txt \
--constraint constraints.txt \
--python-version 3.12 \
--platform manylinux_2_28_x86_64 \
--implementation cp \
--abi cp312
Cross-target resolution uses wheels only because pip cannot safely build source distributions for a foreign interpreter or platform.
Pip can invoke build-backend metadata hooks while resolving source, editable,
local, or VCS requirements, including with --dry-run. Select an enforced
resolver policy for untrusted inputs:
trustcheck scan -f requirements.txt --sandbox auto
| Mode | Behavior |
|---|---|
warn |
Explicit compatibility mode. Run the host pip resolver and warn that metadata hooks may execute. |
off |
Run the host pip resolver without a warning. |
auto |
Default. Prefer Bubblewrap on Linux, then Docker/Podman; fall back to strict. |
container |
Run as UID/GID 65534 in a read-only Docker/Podman container with no capabilities, no-new-privileges, bounded PIDs, a temporary cache, and only staged resolver inputs mounted read-only. |
bubblewrap |
On Linux, unshare user, mount, IPC, UTS, cgroup, and PID namespaces; clear the environment; expose system paths and staged resolver inputs read-only. |
strict |
Reject editable, VCS, source-archive, local non-wheel, and direct non-wheel inputs; use isolated pip configuration, require wheels, and inject a temporary sitecustomize.py audit guard through a minimal PYTHONPATH so unexpected transitive source hooks fail closed. |
Container and Bubblewrap keep network access because dependency resolution must
reach configured indexes. They stage only requirement and constraint files,
dependency-group TOML, nested includes, and referenced local dependencies; the
project workspace, user home, and host pip cache are not mounted.
strict does not execute source metadata hooks; a source-only dependency fails
resolution unless the configured index provides a target-compatible wheel.
External keyring helpers are also unavailable in strict mode; use index URL
credentials or an authenticated index endpoint.
Container and Bubblewrap are the strong OS-sandbox modes. The strict mode is a
portable wheel-only fallback for systems where those runtimes are unavailable;
it constrains resolver inputs and child-process creation, but it is not a
filesystem or network namespace.
The container backend defaults to
python:3.13-slim@sha256:c33f0bc4364a6881bed1ec0cc2665e6c53c87a43e774aaeab88e6f17af105e4f.
Override it with --sandbox-image IMAGE@sha256:DIGEST; mutable tags are rejected.
Scan dependencies declared in a TOML project file:
trustcheck scan -f pyproject.toml
Plan secure dependency changes without invoking writers:
trustcheck scan -f requirements.txt \
--with-osv \
--plan-fixes \
--remediation-output reports/remediation.json
Regenerate and validate the exact patch in an isolated project mirror:
trustcheck scan -f pyproject.toml --with-osv --fix --dry-run
Apply the validated bytes transactionally after re-resolution, clean virtualenv
installation, pip check, configured validation commands, and a complete
rescan:
trustcheck scan -f uv.lock --with-osv --fix
--allow-constraint-changes permits only the minimum range change needed when
all secure releases are excluded. --source-manifest identifies the roots for
a generated lockfile. --max-fix-attempts bounds branch-and-bound resolution;
Trustcheck refuses application when the search cannot prove minimality.
Successful fix runs write a review patch such as trustcheck-fix.patch.
Optional validation commands are read from [tool.trustcheck.fix]:
[tool.trustcheck.fix]
test_commands = ["pytest -q", "python -m compileall src"]
--create-pr publishes the validated patch through fixed-argument git and
gh commands from a temporary worktree. Use --pr-base, --pr-branch,
--pr-title, and --pr-ready to control the pull request. Draft is the
default. See Safe remediation.
Select only particular extras and dependency groups:
trustcheck scan -f pyproject.toml --extra security --group test
Without --extra or --group, all statically declared extras and groups are
included for backward compatibility. Standard dependency-group
include-group entries are expanded with cycle detection.
Scan or inspect a standard PEP 751 lockfile or another supported lock:
trustcheck inspect -f pylock.toml --with-transitive-deps
trustcheck scan -f Pipfile.lock
Supported lock inputs are pylock.toml, named pylock.<name>.toml files,
Pipfile.lock, uv.lock, poetry.lock, and pdm.lock. Hash-pinned pip-tools
requirements files are recognized automatically, including nested -r
includes.
PEP 751 requires-python, environments, package markers, extras, default
groups, selected --extra/--group values, index origins, archives, sdists,
wheels, directories, and immutable VCS revisions are validated. A versionless
source-tree entry is reported as unsupported instead of being silently
reinterpreted as a public-index package.
Every artifact hash retained from a lockfile is verified against downloaded
bytes, independently of provenance and --inspect-artifacts. A mismatch or
unsupported algorithm produces a high-severity lockfile_hash_mismatch.
Resolve through a private index with keyring authentication:
trustcheck scan -f requirements.txt \
--index-url https://username@packages.example.com/simple \
--keyring-provider subprocess
The import provider requires pip install "trustcheck[keyring]". auto
tries the installed Python keyring and then the keyring CLI when available;
select disabled, import, or subprocess for deterministic behavior.
Audit installed distributions:
trustcheck environment
trustcheck environment --path .venv/lib/python3.12/site-packages
Installed scans use importlib.metadata and retain exact installed versions.
PEP 610 direct_url.json metadata is recorded for editable, local, and VCS
installations in combined JSON output.
Scan a requirements-style file and emit JSON:
trustcheck scan -f requirements.txt --format json
Emit SARIF with stable fingerprints and dependency-manifest locations:
trustcheck scan -f requirements.txt \
--format sarif \
--output-file reports/trustcheck.sarif
Emit SBOM, VEX, or Markdown documents:
trustcheck scan -f pylock.toml --format cyclonedx-json \
--output-file reports/trustcheck.cdx.json
trustcheck environment --format cyclonedx-xml \
--output-file reports/environment.cdx.xml
trustcheck scan -f requirements.txt --format spdx-json \
--output-file reports/trustcheck.spdx.json
trustcheck scan -f requirements.txt --format openvex \
--output-file reports/trustcheck.openvex.json
trustcheck scan -f requirements.txt --format markdown \
--output-file reports/trustcheck.md
See Industry output formats for versioned standards, field mappings, and CI guidance.
Create and enforce a trust manifest for a dependency file:
trustcheck manifest init -f requirements.lock \
--output trustcheck.manifest.json
trustcheck manifest verify -f requirements.lock \
--manifest trustcheck.manifest.json
trustcheck manifest update -f requirements.lock \
--manifest trustcheck.manifest.json
manifest init records the approved trust baseline for each resolved package.
manifest verify rescans the dependency file with full trust evidence and
returns exit code 4 when a package is missing from the manifest or regresses
on repository, owner, Trusted Publisher identity, workflow, SLSA builder, build
type, provenance coverage, attestation count, package index origin,
dependency-confusion state, native binaries, dynamic execution, or
malicious-package heuristic score. manifest update refreshes the baseline
after review while preserving existing package exceptions. Use package-level
exceptions with code, owner, reason, and expires fields to approve a
temporary violation until an ISO date or datetime.
Review a dependency update without rescanning the unchanged graph:
trustcheck diff requirements-old.lock requirements-new.lock
trustcheck diff requirements-old.lock requirements-new.lock \
--manifest trustcheck.manifest.json \
--format markdown
trustcheck diff --base origin/main --head HEAD --github-pr --comment
diff compares the old and new dependency graph, then collects full trust
evidence only for changed packages. It reports new direct and transitive
packages, new vulnerability or malicious-package signals, provenance loss,
repository, maintainer, Trusted Publisher, SLSA, license, wheel/sdist, native
binary, source-type, and package-index origin changes. When --manifest is
provided, the same approved trust baseline is enforced against changed package
versions. Output formats are text, json, markdown, and sarif.
--fail-on none|low|med|high controls the CI exit threshold, and
--dependency-file PATH restricts Git ref mode to one or more known files.
Inspect artifact contents for a package:
trustcheck inspect sampleproject --version 4.0.0 --inspect-artifacts --verbose
--inspect-artifacts never imports or executes package code. For wheels it
validates every non-RECORD file against its secure RECORD hash and size,
lists console scripts, parses bounded Python source with ast, and reports
unexpected top-level files. For sdists it gives install and build-hook source
extra weight. PE, ELF, and Mach-O files are inspected for imports,
architecture, signature-record presence, entropy, and embedded payload
signatures. When combined with dependency inspection, the same static checks
are applied to inspected dependency artifacts.
--dynamic-analysis is the explicit exception: it may execute downloaded
artifact build and install hooks inside a disposable Docker container using
--network none, a non-root user, a read-only root filesystem, dropped
capabilities, and bounded CPU, memory, process, and wall-clock limits. It is a
bounded install analysis, not comprehensive behavioral analysis. The result is
phased into archive validation, metadata preparation, wheel build, wheel
installation, and skipped optional probes, with best-effort behavioral evidence.
It rejects mutable image tags and is never enabled by default. Source builds do
not ship a generic default analyzer image; until release automation records
Trustcheck analyzer image digests, use --dynamic-image IMAGE@sha256:DIGEST.
An inconclusive or unsupported analysis is not a clean pass.
Typosquatting, dependency-confusion, ownership, repository, and release-cadence
heuristics run without --inspect-artifacts. Add local reference names with
repeatable --trusted-project NAME. Findings and scores are explicitly
heuristic indicators for review, not proof of malware.
When dependency inspection is enabled, trustcheck resolves the complete set
with pip first and uses the resulting exact version map while traversing
requires_dist metadata. --with-deps stops at immediate dependencies.
--with-transitive-deps continues recursively. The top-level result can be
escalated if an inspected dependency is review-required or high-risk.
When -f is used, trustcheck reads a requirements-style file, TOML project
file, or supported lockfile. inspect -f collects trust evidence without
vulnerability checks; scan -f checks only vulnerability records.
Requirements inputs are delegated to pip so their complete resolved set is
audited. TOML project files support
[project.dependencies], optional dependencies, standard
[dependency-groups], Poetry dependencies, and Poetry groups. Lockfile scans
support PEP 751 pylock.toml, Pipfile.lock, uv.lock, poetry.lock, and
pdm.lock; pip-tools hashes are retained from requirements files. Exact
resolved versions, index origins, artifact candidates, and hashes are retained
in machine-readable output.
Package releases and the machine-readable report schema are versioned
independently. Deep provenance analysis and malicious-package rule metadata are
represented in report schema 1.12.0.
For top-level package analysis, a complete absence of published provenance is typically surfaced as review-required. Stronger negative evidence such as failed verification, inconsistent provenance, or known vulnerabilities still drives high-risk outcomes.
Use a custom policy file:
trustcheck inspect sampleproject --version 4.0.0 --policy-file ./policy.json
Use cached responses only:
trustcheck inspect sampleproject --version 4.0.0 --cache-dir .trustcheck-cache --offline
When scan is used without -f, trustcheck scans the named PyPI package for
vulnerabilities only. In JSON mode, the output is a minimal object containing
project, version, package_url, and vulnerabilities. Advisory providers
query the exact selected package version. Records sharing a CVE or another
alias are merged across providers.