integration

CI/CD Integration

Block deployments when a dependency has a critical or high risk state. The check adds roughly one second to your pipeline — one API call per dependency, parallelisable.

pattern

Check script

Write a small script that checks your pinned dependency versions and exits non-zero if any are risky. The CI job calls this script; a non-zero exit fails the pipeline.

scripts/check_deps.py
# scripts/check_deps.py
import os
import sys
import attestd

DEPENDENCIES = [
    ("nginx",   "1.24.0"),
    ("log4j",   "2.17.1"),
    ("openssh", "9.8p1"),
]

client = attestd.Client(api_key=os.environ["ATTESTD_API_KEY"])
failed = False

for product, version in DEPENDENCIES:
    try:
        result = client.check(product, version)
        status = f"[{result.risk_state.upper()}]"
        if result.risk_state in ("critical", "high"):
            print(f"  FAIL {status} {product} {version}", file=sys.stderr)
            if result.fixed_version:
                print(f"       Upgrade to: {result.fixed_version}", file=sys.stderr)
            failed = True
        else:
            print(f"  PASS {status} {product} {version}")
    except attestd.AttestdUnsupportedProductError:
        # Outside coverage — apply your policy: block | warn | skip
        print(f"  FAIL [OUTSIDE COVERAGE] {product} — unknown risk", file=sys.stderr)
        failed = True

sys.exit(1 if failed else 0)
github actions

GitHub Actions

Add your API key as a repository secret named ATTESTD_API_KEY (Settings → Secrets → Actions). The workflow below runs on every push to main and every pull request.

.github/workflows/security.yml
name: Security Risk Check

on:
  push:
    branches: [main]
  pull_request:

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

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install attestd
        run: pip install attestd

      - name: Check dependency risk
        env:
          ATTESTD_API_KEY: ${{ secrets.ATTESTD_API_KEY }}
        run: |
          python scripts/check_deps.py
gitlab ci

GitLab CI

Add ATTESTD_API_KEY as a CI/CD variable (Settings → CI/CD → Variables).

.gitlab-ci.yml
risk-check:
  stage: test
  image: python:3.12
  before_script:
    - pip install attestd
  script:
    - python scripts/check_deps.py
  variables:
    ATTESTD_API_KEY: $ATTESTD_API_KEY
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"
tips

Pin versions in CI

Check the exact versions you ship. Checking a version range defeats the purpose — you want to know if the version currently pinned in your lockfile is risky.

Block on critical and high; warn on elevated

A common policy: fail the pipeline on critical or high, emit a warning for elevated, and pass for low and none. Adjust based on your risk tolerance.

Decide on outside-coverage policy up front

The script above blocks on outside coverage ("fail safe"). If you want to warn instead, catch AttestdUnsupportedProductError and print a warning without setting failed = True.

Cache results in long pipelines

Results are stable within a data refresh cycle (6 hours). If you check the same versions in multiple pipeline stages, cache the output to avoid redundant API calls.