CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/syft-generation

Generates, scans, and diffs Software Bills of Materials (SBOMs) with the Anchore stack - Syft generation from container images / directories / archives across OCI / Docker / Singularity formats (output CycloneDX-JSON / SPDX-JSON / Syft-JSON / table / GitHub-JSON, cosign attestation); the paired generate + scan workflow with Grype (`grype sbom:./sbom.json`, `--fail-on high`, `--only-fixed`, `.grype.yaml` ignore rules with mandatory `expires:`, EPSS/KEV prioritization); and SBOM-to-SBOM diffing via `cyclonedx diff --component-versions` to gate CI on net-new components and detect supply-chain drift between builds. Use when the team needs SBOM artifacts for compliance (US EO 14028, EU CRA, FDA medical-device guidance), SBOM-driven vulnerability scanning, or dependency-drift detection between releases.

77

Quality

97%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Medium

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

diff-ci-workflows.mdreferences/

SBOM-diff CI workflows

Full GitHub Actions workflows for the SBOM-diff step of syft-generation. The SKILL.md spine keeps the minimal jq gate; the complete CI-gate job, the allowlist pattern, and the nightly drift-detection workflow live here.

CI gate on net-new components

- name: SBOM diff gate
  run: |
    ADDED=$(jq '.added | length' diff-result.json)
    echo "Net-new components: $ADDED"
    if [ "$ADDED" -gt "0" ]; then
      echo "::error::Net-new components detected. Review diff-result.json."
      jq '.added' diff-result.json
      exit 1
    fi

To allow a pre-approved set of additions (a known intentional dependency upgrade), maintain an allowlist and subtract matches before the count check:

UNAPPROVED=$(jq --rawfile allow allowlist.txt \
  '[.added[] | select(.name as $n | $allow | test($n) | not)] | length' \
  diff-result.json)

Adjust the gate threshold and allowlist policy to the team's change-control requirements; the CI step above enforces zero-tolerance as the strictest form.

Nightly drift detection

For production image monitoring, run a nightly diff against the last known-good SBOM rather than comparing two build artifacts:

jobs:
  sbom-drift:
    runs-on: ubuntu-latest
    schedule:
      - cron: "0 2 * * *"
    steps:
      - name: Generate current SBOM
        run: syft myapp:production -o cyclonedx-json=sbom-current.json

      - name: Download last known-good SBOM
        run: |
          aws s3 cp s3://sbom-store/sbom-last-good.json sbom-baseline.json

      - name: Diff
        run: |
          cyclonedx diff sbom-baseline.json sbom-current.json \
            --component-versions --output-format json \
            > drift-result.json

      - name: Alert on drift
        run: |
          ADDED=$(jq '.added | length' drift-result.json)
          REMOVED=$(jq '.removed | length' drift-result.json)
          if [ "$ADDED" -gt "0" ] || [ "$REMOVED" -gt "0" ]; then
            echo "Supply-chain drift detected"
            cat drift-result.json
            # Pipe to Slack/PagerDuty/JIRA as needed
            exit 1
          fi

      - name: Rotate known-good on clean diff
        if: success()
        run: aws s3 cp sbom-current.json s3://sbom-store/sbom-last-good.json

The "rotate known-good on clean diff" step ensures the baseline advances only when the image passes the gate, catching regressions introduced in a later build.

SKILL.md

tile.json