Reviewed local mirror for pinned Forgejo supply-chain scans
  • Go 89.4%
  • Python 7.7%
  • Shell 2.4%
  • Makefile 0.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Noel bcbae548ab chore: refresh Forgejo action mirror
Signed-off-by: Noel <n@noeljackson.com>
2026-08-17 04:19:53 +02:00
.github fix: check out reusable workflow source 2026-08-10 17:09:14 +02:00
cmd fix: discover Forgejo workflows during policy scans 2026-08-17 03:43:10 +02:00
docs fix: discover Forgejo workflows during policy scans 2026-08-17 03:43:10 +02:00
examples security: harden scanner trust boundaries 2026-07-26 00:38:49 +02:00
hooks build: add Homebrew formula + hook portability fix 2026-05-14 12:05:27 +02:00
internal fix: discover Forgejo workflows during policy scans 2026-08-17 03:43:10 +02:00
iocs security: harden scanner trust boundaries 2026-07-26 00:38:49 +02:00
scripts fix Dependabot update classification (#61) 2026-08-08 15:06:31 +02:00
testdata/image add fail-closed source and OCI supplychain scans (#19) 2026-07-19 20:26:34 +02:00
.gitignore security: harden scanner trust boundaries 2026-07-26 00:38:49 +02:00
.goreleaser.yaml security: harden scanner trust boundaries 2026-07-26 00:38:49 +02:00
action.yml fix: isolate composite Go bootstrap per runner invocation (#54) 2026-08-04 09:32:26 +02:00
go.mod build(deps): bump github.com/Masterminds/semver/v3 from 3.3.1 to 3.5.0 (#60) 2026-08-08 15:29:02 +00:00
go.sum build(deps): bump github.com/Masterminds/semver/v3 from 3.3.1 to 3.5.0 (#60) 2026-08-08 15:29:02 +00:00
LICENSE add fail-closed source and OCI supplychain scans (#19) 2026-07-19 20:26:34 +02:00
main.go security: harden scanner trust boundaries 2026-07-26 00:38:49 +02:00
Makefile build: inject Version via -ldflags, fall back to ReadBuildInfo 2026-05-14 11:43:30 +02:00
README.md fix: discover Forgejo workflows during policy scans 2026-08-17 03:43:10 +02:00

supplychain

supplychain is a read-only repository, dependency, and opt-in host-forensics scanner. Repository scans detect known malicious packages, lockfile drift, install hooks, dropped payloads, maintainer changes, fresh npm releases, and strict Bun registry metadata without executing code from the repository being inspected. A tracked vendored-artifact manifest can additionally bind copied browser assets to exact members of signed npm registry tarballs; undeclared minified web assets and runtime package-CDN references fail closed. Host persistence and shell-history checks are isolated under audit-system, so repository findings stay scoped to the selected target.

Start here

GitHub Action

Pin the action to a full commit SHA:

name: supplychain

on:
  pull_request:
  push:
    branches: [main]
  schedule:
    - cron: "17 7 * * 1"
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: supplychain-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  scan:
    uses: noeljackson/supplychain/.github/workflows/scan.yml@FULL_COMMIT_SHA
    with:
      policy: strict

The reusable workflow checks out its own source at the exact called-workflow commit, builds it with Go module checksum verification, and scans the caller checkout without running package-manager or project scripts. Pair it with the repository controls in the GitHub Actions guide.

To add the caller workflow to a repository:

supplychain init github --ref=FULL_COMMIT_SHA

Gitea uses the composite action through an absolute, SHA-pinned URL. See the Gitea guide, or generate the per-repository workflow:

supplychain init gitea --ref=FULL_COMMIT_SHA

The root composite action is also available inside an existing job:

- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
  with:
    persist-credentials: false
- uses: noeljackson/supplychain@FULL_COMMIT_SHA
  with:
    policy: strict
    image: app:test
    fail-on-severity: high

Strict scans also run zizmor offline against GitHub, Gitea, and Forgejo Actions definitions, failing on medium-or-higher, medium-confidence findings and workflow schema errors without exposing a GitHub token to the analyzer. They also run Gitleaks with redaction and analytics disabled so checked-out repository secrets fail closed without printing secret values. The scanner stages a temporary hard-link view of tracked and non-ignored untracked files, so generated dependencies and build artifacts are excluded without copying secret-bearing source files or following repository symlinks. Repository-controlled Gitleaks config and ignore files are ignored by default. Reviewed inline gitleaks:allow comments are the simplest explicit exception mechanism. Repositories with several narrowly documented public-value exceptions may opt in to a tracked config with gitleaks-config; the scanner rejects untracked, external, and symlinked policy files, and never honors .gitleaksignore.

When image is set, the action creates an SPDX JSON SBOM with Syft and scans that exact document with Grype. The sbom action output is suitable for later artifact upload or attestation. Gitleaks, Syft, Grype, and OSV Scanner are installed from cooldown-aged, immutable releases whose expected SHA-256 hashes live in this repository. Strict source scans fail if OSV Scanner is absent or fails. A target with no supported package sources is reported as not_applicable, not as lost coverage. Image scans require a fresh, hash-valid Grype database and a successful update check. Image scans always use isolated explicit Syft and Grype configs and scrub their configuration environment variables, so a repository cannot weaken inventory with .syft.yaml or the gate with .grype.yaml. A reviewed, tracked OpenVEX document may be selected explicitly with vex; untracked, external, oversized, and symlinked policy files are rejected.

The reusable workflow is source-only because reusable jobs cannot see an image built in a caller job. Use the composite action in the same job, after docker build, when image scanning is required. If an earlier step or job has already run the source gate, set scan-source: false on the post-build action to install and run only Syft and Grype.

- uses: noeljackson/supplychain@FULL_COMMIT_SHA
  with:
    scan-source: false
    image: app:test
    fail-on-severity: high
    only-fixed: true
    vex: security/app.openvex.json

Local image scan with already-installed Syft and Grype:

supplychain image --sbom=app.spdx.json --fail-on=high --only-fixed \
  --vex=security/app.openvex.json app:test

Bun verification

supplychain verify-bun --minimum-age-days=7 .
supplychain verify-bun --minimum-age-days=30 \
  --write-baseline --baseline=.supplychain/bun-baseline.json .

The verifier requires registry-only lock entries, SHA-512 integrity matching the npm packument, a valid npm ECDSA registry signature, and a publication timestamp older than the configured window. A reviewed baseline also detects maintainer changes, integrity drift, new packages, and loss of advertised npm provenance.

Local use

make test
make install
supplychain ci --policy=strict .
supplychain secrets .

For all commands and local helper requirements, see the usage guide.

Normal workstation scans may refresh public IOC data. CI always uses the IOC snapshot embedded in the pinned scanner source. The global action downloads only its pinned, hash-checked OSV/zizmor/Syft/Grype helper versions. Network-contained runners can additionally use --osv-offline with a preloaded OSV Scanner offline database. That mode disables OSV API queries and dependency resolution and fails closed instead of falling back to online scan syntax.