Skip to content

TrustCheck Package Scanner

TrustCheck Package Scanner is the repository's first-class composite GitHub Action. Callers do not need to install Python packages or invoke the CLI themselves.

Minimal dependency gate

This complete step is under ten lines and fails the job when strict policy evaluation fails:

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

actions/checkout is required for file targets. It is optional when target is only a PyPI package name.

The action asks the CLI for JSON internally so it can set outputs, then writes the requested report format to a workflow artifact. By default that artifact is trustcheck-report.txt; set format: json to upload trustcheck-report.json. A policy failure still uploads its report before failing the job.

This is a documented minor-version behavior change from the early Action, which always uploaded a JSON report path. Existing consumers that parse the artifact file should set format: json or an explicit report-path ending in .json. Step outputs such as policy-passed, recommendation, and report-path remain stable and continue to be derived from the internal JSON result.

Stable releases publish a full version tag such as v3.0.0 and update the compatible major ref v3. Use @v3 for compatible updates. For immutable release gates, pin Halfblood-Prince/trustcheck and supporting actions to full 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
      sandbox: auto

Pre-commit and monorepos

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

repos:
  - repo: https://github.com/Halfblood-Prince/trustcheck
    rev: v3
    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, discover supported dependency files and aggregate repository-relative results:

trustcheck-workspace . --format sarif

trustcheck-workspace accepts --baseline and --policy-overrides for per-project policies.

Trust manifest gate

For dependency files with an approved baseline, run the CLI after checkout to block trust regressions across otherwise clean upgrades:

steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-python@v6
    with:
      python-version: "3.12"
  - run: python -m pip install trustcheck
  - run: |
      trustcheck manifest verify \
        -f requirements.lock \
        --manifest trustcheck.manifest.json

Create the baseline with trustcheck manifest init, review the JSON, commit it with the dependency file, and use trustcheck manifest update only after reviewing an intentional publisher, provenance, index, artifact, or heuristic change.

Pull request trust diff

For dependency update pull requests, compare the base and head dependency files and review only packages whose resolved version, source, or index origin changed:

permissions:
  contents: read
  pull-requests: write

steps:
  - uses: actions/checkout@v7
    with:
      fetch-depth: 0
  - uses: actions/setup-python@v6
    with:
      python-version: "3.12"
  - run: python -m pip install trustcheck
  - run: |
      trustcheck diff \
        --base origin/main \
        --head HEAD \
        --github-pr \
        --manifest trustcheck.manifest.json \
        --format markdown \
        --comment

trustcheck diff collects full trust evidence only for changed direct and transitive packages. It flags newly introduced packages, vulnerability and malicious-package signals, provenance loss, repository or Trusted Publisher identity changes, wheel or sdist native binaries, license changes, private-index origin changes, and trust-manifest violations. Omit --comment and use --format sarif --output-file trustcheck-diff.sarif when the workflow uploads findings to GitHub code scanning instead of posting a PR comment.

Supported targets

The target input accepts:

  • a PyPI package name, such as sampleproject
  • requirements.txt or another requirements-style .txt file
  • pyproject.toml
  • PEP 751 pylock.toml or a named pylock.<name>.toml file
  • Pipfile.lock
  • uv.lock
  • poetry.lock
  • pdm.lock

File targets use trustcheck scan. Package names use trustcheck inspect.

Package repository verification

expected-repo applies to package targets:

- uses: Halfblood-Prince/trustcheck@v3
  with:
    target: sampleproject
    expected-repo: https://github.com/pypa/sampleproject
    policy: strict

A single expected repository is not meaningful for a multi-package dependency file, so the action rejects expected-repo when target is a file.

Dependencies, vulnerability intelligence, and artifacts

- uses: Halfblood-Prince/trustcheck@v3
  with:
    target: uv.lock
    policy: strict
    with-osv: "true"
    with-ecosystems: "true"
    with-kev: "true"
    with-epss: "true"
    with-transitive-deps: "true"
    inspect-artifacts: "true"
    trusted-projects: |
      internal-sdk
      internal-auth

with-deps and with-transitive-deps are mutually exclusive, matching the CLI. Artifact inspection remains static and never imports inspected packages.

Custom policy file

Pass a repository-relative JSON policy path:

- uses: Halfblood-Prince/trustcheck@v3
  with:
    target: pyproject.toml
    policy: .github/trustcheck-policy.json

The file uses the same schema as CLI --policy-file.

Remediation pull requests

Plan a repair and upload the machine-readable patch bundle:

- uses: Halfblood-Prince/trustcheck@v3
  with:
    target: requirements.txt
    with-osv: "true"
    remediation: plan
    remediation-path: reports/remediation.json

Create a validated draft pull request:

permissions:
  contents: write
  pull-requests: write

steps:
  - uses: actions/checkout@v7
    with:
      fetch-depth: 0
  - uses: Halfblood-Prince/trustcheck@v3
    with:
      target: uv.lock
      with-osv: "true"
      remediation: fix
      create-pr: "true"
      pr-base: main

The action never changes workflow permissions. PR mode requires the caller to grant contents: write and pull-requests: write, and requires an authenticated gh CLI. Draft is the default; set pr-ready: "true" to request review immediately.

Trustcheck's own CI also runs GitHub Dependency Review on pull requests. That lightweight gate blocks newly introduced vulnerable dependencies at moderate or higher severity and denies AGPL/GPL license introductions before merge.

Release artifact scanning

Trustcheck's own release workflows build standalone Windows and Linux executables. Windows artifacts are scanned with Microsoft Defender's MpCmdRun.exe; Linux artifacts are scanned with ClamAV. Clean binaries, checksums, and scanner reports are retained as workflow artifacts by the Binary Security workflow.

Inputs

Input Default Description
target required Package name or supported dependency file.
policy default default, strict, or a custom JSON policy path.
expected-repo empty Expected repository for a package target.
trusted-publisher-organizations empty Whitespace- or newline-separated [provider:]organization publisher allowlist entries.
with-osv false Query OSV and GitHub advisory data.
osv-urls empty Whitespace- or newline-separated custom OSV-compatible API base URLs.
with-ecosystems false Query the Ecosyste.ms OSV-compatible advisory service.
with-kev false Enrich CVEs with the CISA KEV catalog.
with-epss false Enrich CVEs with FIRST EPSS scores and percentiles.
with-deps false Inspect direct runtime dependencies.
with-transitive-deps false Inspect the complete runtime dependency tree.
inspect-artifacts false Statically inspect wheel and sdist contents.
index-url empty Primary PEP 503/691 Simple Repository index.
extra-index-urls empty Whitespace- or newline-separated additional indexes.
keyring-provider auto auto, disabled, import, or subprocess.
allow-dependency-confusion false Continue after reporting a cross-index project-name collision.
allow-insecure-index false Explicitly allow HTTP Simple Repository indexes and their artifact URLs.
trusted-projects empty Whitespace- or newline-separated names added to the typosquatting reference set.
workers 8 Bound concurrent target, advisory, and network work from 1 through 64, or -1 for all available CPU cores.
sandbox strict Resolver isolation: off, warn, auto, container, bubblewrap, or strict.
sandbox-image empty Digest-pinned OCI image for container resolution.
advisory-snapshots empty Whitespace- or newline-separated advisory snapshot paths.
write-advisory-snapshot empty Write a merged versioned advisory snapshot.
max-advisory-age 168 Maximum accepted snapshot age in hours.
advisory-snapshot-identity empty Trusted Sigstore certificate identity for snapshot verification.
advisory-snapshot-issuer empty Expected OIDC issuer for the snapshot signer.
sign-advisory-snapshot false Sign written snapshots using ambient Sigstore identity.
allow-unsigned-advisory-snapshot false Explicit compatibility mode for unsigned snapshots.
resume-state empty Checkpoint path for resumable dependency-file scans.
enable-plugins false Experimental: enable installed Trustcheck entry-point plugins.
plugins empty Whitespace- or newline-separated [kind:]name plugin allowlist.
plugin-config empty JSON configuration path keyed by plugin name.
remediation none none, plan, or fix for dependency-file targets.
dry-run false Regenerate and validate the exact patch without applying it.
allow-constraint-changes false Permit minimum required declared-range changes.
source-manifest empty Source requirements or pyproject.toml for a generated lock.
remediation-path trustcheck-remediation.json Machine-readable patch bundle path.
max-fix-attempts 256 Bound for minimal secure resolution attempts.
create-pr false Publish a validated fix through git and gh.
pr-base empty Pull request base branch.
pr-branch generated Pull request head branch.
pr-title generated Pull request title.
pr-ready false Create a ready PR instead of a draft.
format text text, json, sarif, cyclonedx-json, cyclonedx-xml, cyclonedx-1.7-json, cyclonedx-1.7-xml, spdx-json, spdx-3-json, openvex, or markdown.
report-path derived Report location; the default extension follows format.
artifact-name trustcheck-report Uploaded workflow artifact name.
python-version 3.12 Python version used by the action.

Private-index credentials can be supplied through URL user information, .netrc, or the configured keyring provider. Reports redact URL passwords.

All external Actions used by Trustcheck's own workflows and composite Action are pinned to full commit SHAs. The composite Action installs runtime and build dependencies from requirements/action.lock with --require-hashes, then installs Trustcheck with dependency resolution and build isolation disabled. With multiple indexes, a normalized name found on more than one index fails closed unless allow-dependency-confusion is explicitly enabled.

Outputs

Output Description
recommendation Overall recommendation such as verified, review-required, or high-risk.
policy-passed true only when policy passes and the scan has no operational failures.
report-path Absolute path to the generated report.
remediation-status not-requested, planned, validated, applied, pull-request-created, blocked, or failed.
applied-fixes Number of dependency upgrades in the remediation.
patch-path Absolute path to the remediation bundle.
pr-branch Created remediation branch.
pr-url Created pull request URL.

Use outputs in later workflow steps:

- uses: Halfblood-Prince/trustcheck@v3
  id: trustcheck
  with:
    target: requirements.txt

- run: echo "Recommendation is $RECOMMENDATION"
  env:
    RECOMMENDATION: ${{ steps.trustcheck.outputs.recommendation }}

Custom report names

Use distinct artifact names when invoking the action more than once in a job:

- uses: Halfblood-Prince/trustcheck@v3
  with:
    target: poetry.lock
    report-path: reports/trustcheck-poetry.json
    artifact-name: trustcheck-poetry

Upload SARIF to code scanning

The action always audits once. It derives SARIF from the same canonical JSON result used for the recommendation and policy outputs.

- uses: Halfblood-Prince/trustcheck@v3
  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 }}

SARIF findings use stable fingerprints and point to the dependency manifest and declaration line when available.

CLI fallback

The CLI remains available for other CI systems:

trustcheck scan -f requirements.txt --policy strict --format json

GitHub users should prefer the action because it handles installation, report upload, outputs, and exit-code propagation consistently.