trustcheck [](https://awesome.re)

July 5, 2026 ยท View on GitHub

trustcheck Awesome

CI Source Build CodeQL pip-audit Bandit Semgrep Adversarial fuzzing Windows Defender ClamAV Ruff mypy Coverage PyPI Python 3.11 | 3.12 | 3.13 | 3.14 PyPI Downloads TrustCheck Package Scanner

Get it from the Snap Store Get it from PyPI

trustcheck is a Python package and CLI for evaluating the trust posture of PyPI releases before they are installed, promoted, or approved.

It combines PyPI metadata, vulnerability records, provenance availability, cryptographic attestation verification, Trusted Publisher identity hints, and repository matching into a single operator-friendly report.

Packages that publish no provenance are treated as needing review rather than as automatic high-risk findings, while invalid provenance, partial coverage, repository mismatches, and known vulnerabilities remain stronger negative signals.

Choose your workflow

CommandUse it to
scanaudit a project
inspectassess one package release
installverify before installing
diffreview a dependency PR
manifestlock approved trust evidence
impactprioritize by observed usage

Latest benchmark

Generated 2026-07-04T12:38:12.871592+00:00 on Python 3.14.6 with pip-audit 2.10.1. Corpus 2026.06 contains 133 entries; this fixed-input --no-deps comparison covers 112 comparable package entries.

ToolCold p50Warm p50Warm p95Peak RSSRequests p50Recall
trustcheck scan --fast16.00 s14.20 s14.44 s78.0 MiBunknown1
pip-audit36.69 s38.51 s39.82 s75.6 MiBunknown1

Alias-aware agreement: 1.0 across 105 compared packages and 263 matched advisories. Resolver exact match: True (trustcheck 22, pip-audit 22).

What it checks

For a selected package version, trustcheck can:

  • fetch project and release metadata from PyPI
  • verify published provenance against artifact digests
  • interpret SLSA v1 build definitions, builders, source materials, commits, workflows, and resolved build dependencies
  • detect mutable workflow references, unpinned build actions, and source-to-artifact inconsistencies
  • surface Trusted Publisher repository and workflow identity hints
  • compare signer, repository, workflow, builder, build type, and source commit evidence across release history
  • verify source/release parity so declared repositories, release tags, artifacts, and attestations agree on one source commit
  • compare expected repository input against declared and attested signals
  • flag publisher drift, missing verification, and known vulnerabilities
  • scan requirements files, project TOML, pylock.toml, Pipfile.lock, pip-tools output, and uv.lock, poetry.lock, or pdm.lock
  • resolve complete dependency sets with pip installation reports, including constraints, nested requirements, extras, dependency groups, editable requirements, and VCS references
  • audit the active Python environment or arbitrary site-packages directories
  • resolve against PEP 503/691 private indexes with optional keyring credentials
  • block dependency-confusion collisions across public and private indexes
  • preserve and verify lockfile artifact hashes before trusting downloaded bytes
  • verify and install dependencies in one gate with a temporary local wheelhouse and reproducible lock, report, and attestation evidence
  • prioritize vulnerable packages by observed first-party imports, dependency reachability, test-only usage, development-only usage, and unresolved dynamic imports
  • plan, dry-run, apply, or publish the smallest validated secure dependency upgrade set without silently widening declared constraints
  • review dependency update pull requests by comparing only changed lockfile packages, trust metadata, artifacts, index origins, licenses, and manifest expectations
  • batch OSV queries, bound concurrent target work, and store responses by verified SHA-256 content digest
  • consume offline advisory snapshots, resume interrupted scans, and load explicitly enabled advisory, index, artifact, policy, or renderer plugins
  • optionally inspect wheel and sdist contents without importing or executing package code
  • score typosquatting, dependency-confusion, package-history, source-code, and native-binary heuristic indicators without claiming a malware verdict
  • emit text, JSON, SARIF 2.1.0, CycloneDX 1.6 or 1.7 JSON/XML, SPDX 2.3 or SPDX 3 JSON, OpenVEX 0.2.0, or Markdown
  • emit a concise decision report for release gates and pull request checks

Check local prerequisites before relying on resolver isolation, private indexes, or provenance verification:

trustcheck doctor

Every push also builds standalone Windows and Linux executables. The Windows artifact is scanned with Microsoft Defender's MpCmdRun.exe; the Linux artifact is scanned with ClamAV. Clean binaries, checksums, and scanner reports are retained as workflow artifacts by Binary Security.

Installation

Install from PyPI:

pip install trustcheck

Install the optional Python keyring provider when private-index credentials are stored in an in-process keyring backend:

pip install "trustcheck[keyring]"

Project defaults can live in .trustcheck.toml or under [tool.trustcheck] in pyproject.toml. CLI flags override environment variables, which override project configuration. See the configuration guide.

Or install the Snap Store package:

sudo snap install trustcheck

The Snap command is trustcheck. If the shell reports command not found immediately after installation, start a new login session or add Snap's command directory to the current shell:

export PATH="/snap/bin:$PATH"
trustcheck --version

You can always bypass shell PATH lookup with:

snap run trustcheck inspect requests

PyPI installation requirements:

  • Python >=3.11
  • Network access to PyPI

Machine-readable reports currently use JSON schema 1.11.0. Package and report schema versions are independent so documentation-only package releases do not force contract churn.

Pre-commit and monorepos

Trustcheck publishes a first-party hook for changed dependency files:

repos:
  - repo: https://github.com/Halfblood-Prince/trustcheck
    rev: v2
    hooks:
      - id: trustcheck

The hook runs --fast --no-deps --with-osv, preserves lockfile artifact hashes, deduplicates filenames, and merges failures across every changed dependency file. For monorepos, trustcheck-workspace . --format sarif discovers supported files, aggregates repository-relative results, and accepts --baseline plus --policy-overrides for per-project policies.

Use a trust manifest to approve the current dependency identities and block future trust regressions even when an upgrade is vulnerability-free:

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

The manifest records source repository and owner, verified Trusted Publisher identity and workflow, SLSA builder and build type, provenance and attestation coverage, package index origin, malicious-package score ceiling, native-binary allowance, dynamic-execution allowance, and expiring package exceptions.

Review dependency update pull requests with a trust diff that inspects only packages whose resolved version or source changed:

trustcheck diff requirements-old.lock requirements-new.lock
trustcheck diff --base origin/main --head HEAD --github-pr --format markdown
trustcheck diff --base origin/main --head HEAD --github-pr --comment

The diff highlights new direct and transitive packages, vulnerability and malicious-package signals, provenance loss, repository or Trusted Publisher changes, wheel or sdist native-binary changes, license and private-index origin changes, and trust-manifest violations when --manifest is provided. Use --format sarif to upload findings to code scanning.

TrustCheck Package Scanner

Use the TrustCheck Package Scanner action to scan a checked-in dependency file before merge:

steps:
  - uses: actions/checkout@v7
  - uses: Halfblood-Prince/trustcheck@v2
    with:
      target: requirements.txt
      policy: strict

For a protected release gate, pin both actions to commit SHAs. GitHub treats a full commit SHA as the only immutable Action reference:

steps:
  - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
  - uses: Halfblood-Prince/trustcheck@<full-release-commit-sha>
    with:
      target: requirements.txt
      policy: strict

The action installs and runs trustcheck, uploads trustcheck-report.json as a workflow artifact, and fails the job with the CLI's exit code when policy evaluation fails. target also accepts a PyPI package name, pyproject.toml, pylock.toml, Pipfile.lock, uv.lock, poetry.lock, or pdm.lock. Each stable release publishes an immutable full version tag and updates the compatible major action tag used above.

Produce SARIF for GitHub code scanning without repeating the audit:

- uses: Halfblood-Prince/trustcheck@v2
  id: trustcheck
  with:
    target: requirements.txt
    format: sarif

- uses: github/codeql-action/upload-sarif@v4
  if: always()
  with:
    sarif_file: ${{ steps.trustcheck.outputs.report-path }}

See the CI integration guide for custom policies, OSV, dependency traversal, outputs, and report naming.

Quick start

Inspect the latest release:

trustcheck inspect requests

Inspect a specific version:

trustcheck inspect sampleproject --version 4.0.0

Show only known vulnerabilities for a release:

trustcheck scan sampleproject --version 4.0.0 --fast

Scan profiles make the analysis depth explicit. --fast (the default) performs dependency resolution and advisory lookup only. --standard adds provenance, while --full adds static archives, native binaries, release history, and malicious-package heuristics. Artifact breadth defaults to the best compatible wheel for the requested target, with an sdist fallback.

trustcheck scan -f requirements.txt --standard
trustcheck scan sampleproject --version 4.0.0 --full --workers 8
trustcheck scan sampleproject --full --artifact-scope all --strict

Use --artifact-scope sdist for source review or --artifact-scope all for a strict whole-release review. Release and promotion policies should scan every published artifact, including wheels for other operating systems and architectures:

trustcheck scan -f requirements.lock --full --artifact-scope all --strict

Verify and install the exact resolved dependency graph in one workflow:

trustcheck install -r requirements.txt --policy strict
trustcheck install -r requirements.txt --lock trustcheck.lock
trustcheck install requests==2.32.5 --require-provenance

trustcheck install resolves the complete graph, verifies the selected artifacts, materializes a temporary verified wheelhouse, and invokes pip with --no-index --find-links plus hash-pinned exact requirements. Nothing is installed if policy, provenance, advisory, hash, artifact, or private-index origin checks fail. Each run writes trustcheck.lock, trustcheck-install-report.json, and trustcheck-install-attestation.json.

Prioritize vulnerable packages by observed application usage:

trustcheck impact -f requirements.lock --source .
trustcheck impact -f requirements.lock --source src --source services/api --format json

trustcheck impact combines the resolved dependency graph with a conservative static import graph from first-party source, console-script metadata, pytest plugins, and common framework imports. Findings are classified as directly used, transitively reachable, test-only, development-only, not observed in project source, or unknown due to dynamic loading. It never claims a dependency is not exploitable; no first-party usage means only that static analysis did not observe it, and dynamic imports, plugins, and runtime configuration still require manual review.

Enrich vulnerability intelligence with OSV and GitHub Advisory Database data:

trustcheck scan jinja2 --version 2.10.0 --with-osv

Merge OSV, Ecosyste.ms, a private OSV-compatible service, CISA KEV, and FIRST EPSS intelligence:

trustcheck scan jinja2 \
  --version 2.10.0 \
  --with-osv \
  --with-ecosystems \
  --osv-url https://advisories.example.com \
  --with-kev \
  --with-epss

Gate only critical, known-exploited, or fixable vulnerabilities:

trustcheck scan -f pylock.toml --fail-on-vulnerability kev

Require verified publishers to belong to an approved organization:

trustcheck inspect sampleproject \
  --version 4.0.0 \
  --trusted-publisher-organization github:pypa

Custom policy files can suppress a specific advisory temporarily, but every suppression must name an owner, justification, and ISO expiration date.

Inspect a package and its direct dependencies:

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

Inspect every package listed in a requirements-style file:

trustcheck inspect -f requirements.txt

Resolution uses pip install --dry-run --report and includes transitive packages selected by pip:

trustcheck scan -f requirements.txt \
  --constraint constraints.txt \
  --python-version 3.12 \
  --platform manylinux_2_28_x86_64 \
  --implementation cp \
  --abi cp312

Pip may invoke build-backend metadata hooks even in dry-run mode. Trustcheck can isolate that resolver invocation:

trustcheck scan -f requirements.txt --sandbox auto

--sandbox auto is the default. It prefers Bubblewrap on Linux, then Docker or Podman, and falls back to strict wheel-only resolution when no runtime is available. The full mode set is:

  • warn: explicitly preserve host pip behavior and emit an execution-risk warning
  • off: preserve pip behavior without the warning
  • container: run pip as an unprivileged process in a read-only Docker/Podman container with dropped capabilities and only staged resolver inputs mounted
  • bubblewrap: run pip in low-privilege Linux namespaces with a read-only staged input tree, read-only system paths, and a cleared environment
  • strict: reject editable, VCS, local non-wheel, direct non-wheel, and source archive inputs, ignore user pip configuration, and require wheels for every resolved package; child-process creation is denied so unexpected transitive source hooks and VCS commands fail closed

Container and Bubblewrap modes retain network access for package-index resolution. Requirements, nested includes, constraints, dependency-group files, and referenced local dependencies are copied to a temporary input tree; the project workspace is not mounted. Container images must be pinned by a full SHA-256 digest when supplied with --sandbox-image. Cross-target resolution is always wheel-only.

Inspect dependencies declared in a TOML project file:

trustcheck inspect -f pyproject.toml

Plan the smallest constraint-compatible secure upgrade set:

trustcheck scan -f requirements.txt \
  --with-osv \
  --plan-fixes \
  --remediation-output reports/trustcheck-remediation.json

Generate and validate the exact patch without changing dependency files:

trustcheck scan -f pyproject.toml --with-osv --fix --dry-run

Apply the same transaction only after re-resolution, a clean virtualenv install, pip check, configured validation commands, and a complete rescan:

trustcheck scan -f uv.lock --with-osv --fix

Configured fix validation commands live under [tool.trustcheck.fix]:

[tool.trustcheck.fix]
test_commands = ["pytest -q", "python -m compileall src"]

Successful fix runs write a review patch such as trustcheck-fix.patch and record the exact path in the remediation output.

Secure versions excluded by a declared range remain blocked unless --allow-constraint-changes is passed. Editable, local-path, direct-archive, and VCS dependencies are reported as requiring human remediation.

Select project extras and dependency groups:

trustcheck scan -f pyproject.toml --extra security --group test

Inspect exact direct and transitive versions from a supported lockfile:

trustcheck inspect -f pylock.toml --with-transitive-deps
trustcheck scan -f Pipfile.lock

Run a bounded, resumable scan and publish an advisory snapshot:

trustcheck scan -f requirements.txt \
  --with-osv \
  --workers 8 \
  --resume-state .trustcheck/scan-state.json \
  --write-advisory-snapshot .trustcheck/advisories.json \
  --sign-advisory-snapshot

Signed snapshots include source URLs, generation and expiration times, and a SHA-256 digest of canonical advisory records. Reading one requires the trusted Sigstore certificate identity and accepts snapshots for at most seven days by default; adjust that bound with --max-advisory-age HOURS.

Enable an installed, signed plugin explicitly:

trustcheck scan -f requirements.txt --plugin policy:company-policy

Every plugin must be explicitly allowlisted. Trustcheck verifies its signed trustcheck-plugin.json name, kind, entry point, and API version before using a spawned resource-bounded worker. Optional signer fingerprints live under _trustcheck.trusted_signers in plugin config. Each call is reported in diagnostics.plugin_executions with status, duration, and isolation state.

Hash-pinned pip-tools output is detected automatically. Every retained lockfile hash is emitted in combined JSON and checked against the downloaded artifact. This integrity check does not require --inspect-artifacts.

Resolve and audit from a private PEP 503/691 index:

trustcheck scan -f requirements.txt \
  --index-url https://username@packages.example.com/simple \
  --keyring-provider subprocess

Adding a public fallback is deliberately guarded:

trustcheck scan -f requirements.txt \
  --index-url https://username@packages.example.com/simple \
  --extra-index-url https://pypi.org/simple

If the same normalized project name exists on both indexes, the scan stops with a dependency-confusion error. --allow-dependency-confusion is available for a source collision that has been independently reviewed; the finding remains in combined JSON.

Audit the active environment:

trustcheck environment

Audit one or more explicit site-packages directories:

trustcheck environment --path .venv/lib/python3.12/site-packages

Statically inspect wheel and sdist contents:

trustcheck inspect sampleproject --version 4.0.0 --inspect-artifacts --verbose

Artifact inspection validates wheel RECORD hashes, lists console scripts, parses Python source with ast, detects suspicious capability combinations, and compares wheel and sdist metadata. PE, ELF, and Mach-O files are inspected for imported libraries, embedded signature presence, entropy, and embedded payload signatures. It reads archive bytes only and never imports the inspected package.

For behavior evidence, --dynamic-analysis is available as an explicit opt-in. It executes downloaded artifacts in a disposable Docker container with no network, a non-root user, dropped capabilities, and strict CPU, memory, process, and wall-clock limits. The dynamic-analysis image is digest-pinned by default, and mutable image tags are rejected. It is never enabled by default.

Name, index, ownership, repository, and release-cadence heuristics run during normal inspection. Add organization-specific reference names with repeatable --trusted-project:

trustcheck inspect -f requirements.txt \
  --trusted-project internal-sdk \
  --trusted-project internal-auth

Require a release to match an expected repository:

trustcheck inspect sampleproject \
  --version 4.0.0 \
  --expected-repo https://github.com/pypa/sampleproject

Require source/release provenance parity for a package release:

trustcheck inspect sampleproject \
  --version 4.0.0 \
  --source-release-provenance \
  --release-tag v4.0.0

Emit JSON for another tool:

trustcheck inspect sampleproject --version 4.0.0 --format json

Emit only the gate decision fields:

trustcheck scan -f requirements.txt --summary

Emit combined JSON for a requirements-style, TOML, or lockfile scan:

trustcheck scan -f requirements.txt --format json

Write SARIF, SBOM, VEX, or Markdown output directly to a file:

trustcheck scan -f requirements.txt \
  --format sarif \
  --output-file reports/trustcheck.sarif

trustcheck scan -f pylock.toml \
  --format cyclonedx-json \
  --output-file reports/trustcheck.cdx.json

Supported industry formats are sarif, cyclonedx-json, cyclonedx-xml, cyclonedx-1.7-json, cyclonedx-1.7-xml, spdx-json, spdx-3-json, openvex, and markdown. The unversioned CycloneDX and SPDX format names remain compatible aliases for CycloneDX 1.6 and SPDX 2.3. SBOM exports retain package purls, vulnerabilities, provenance coverage, artifact hashes, recommendations, and policy violations.

Emit only vulnerability records as JSON:

trustcheck scan sampleproject --version 4.0.0 --format json

Fail CI when full verification is missing:

trustcheck inspect sampleproject --version 4.0.0 --strict

Starter policy bundles include startup, regulated, enterprise-private-index, release-gate, and open-source-maintainer:

trustcheck scan -f requirements.txt --policy release-gate

Use it from Python:

from trustcheck import inspect_package

report = inspect_package("sampleproject", version="4.0.0", include_dependencies=True)
print(report.recommendation)

Documentation

Full documentation: https://halfblood-prince.github.io/trustcheck/

Project support:

License

Trustcheck Personal Use License