integrations / github-action

GitHub Action

Official action attestd-io/check-action. Pin with @v1. Calls the Attestd API from your workflow without a custom script.

Marketplace: github.com/attestd-io/check-action. Store your key as the repository secret ATTESTD_API_KEY.

modes

Deploy gate and lockfile scan

Deploy gate

Single product + version. Fail the job when risk meets fail_on. Use as a required check before deploy.

Lockfile scan

Path to requirements.txt or package-lock.json (v2/v3). Chunks into batch API calls. Typical PR use: fail_on: never plus the results artifact.

Provide either lockfile or product + version, not both.

deploy gate

Block a deploy on high or critical

.github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  security-check:
    runs-on: ubuntu-latest
    steps:
      - uses: attestd-io/check-action@v1
        with:
          api_key: ${{ secrets.ATTESTD_API_KEY }}
          product: nginx
          version: "1.20.0"
          fail_on: high

  deploy:
    needs: security-check
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying..."
lockfile scan

Scan package-lock.json on pull requests

Batches of 100 call POST /v1/check/batch. If a batch would exceed quota, that batch is rejected before billing. Earlier successful batches stay billed.

.github/workflows/attestd.yml
name: Attestd lockfile scan

on: [pull_request]

jobs:
  attestd:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Scan package-lock.json
        id: scan
        uses: attestd-io/check-action@v1
        with:
          api_key: ${{ secrets.ATTESTD_API_KEY }}
          lockfile: package-lock.json
          fail_on: never

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: attestd-scan
          path: ${{ steps.scan.outputs.results_path }}

Same pattern for pinned PyPI requirements:

yaml
- uses: attestd-io/check-action@v1
  with:
    api_key: ${{ secrets.ATTESTD_API_KEY }}
    lockfile: requirements.txt
    fail_on: high
inputs

Inputs

InputDescription
api_keyRequired. Attestd API key (atst_...).
productSingle-check slug. Mutually exclusive with lockfile.
versionSingle-check version. Required with product.
lockfilePath to requirements.txt or package-lock.json (v2/v3).
fail_oncritical | high (default) | elevated | any | never.
fail_on_provenance_missingIf true, fail when provenance is false (default false).
max_packagesLockfile safety cap (default 2000). Fails before API calls if exceeded.
results_fileLockfile JSON summary path (default attestd-scan-results.json).
base_urlOverride only for local/staging tests.

Outputs

Single-check outputs: risk_state, actively_exploited, fixed_version, cve_ids, supported, compromised, provenance, typosquat.

Lockfile outputs: packages_scanned, packages_flagged, packages_unsupported, highest_risk_state, results_path.

failure behavior

What fails the step

ConditionBehavior
Unsupported productWarns. Does not fail (unless typosquat). Not a safety signal.
risk_state >= fail_onFails the step. Default threshold is high.
Supply-chain compromiseFails unless fail_on is never.
Typosquat detectedFails unless fail_on is never.
Quota exceeded (429) mid lockfile scanFails. Reports packages already billed vs the rejected batch (rejected before billing).
Lockfile exceeds max_packagesFails before any API call.
requirements.txt ranges / VCS / editableSkipped with a warning. Only == pins are checked.
package-lock.json v1Fails with a clear upgrade message (v2/v3 required).
related