build(deps): Bump google/osv-scanner-action/osv-scanner-action from 9fd1bcce27f67e3bd819a0a7620e332803dc43bc to f4cfcc01edc9c8b756a9b873b7a623ca674da51e #800
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Supply-chain security gate. | |
| # | |
| # Scans the resolved dependency tree (bun.lock) against the OSV.dev database — | |
| # which aggregates GitHub/npm security advisories AND the OpenSSF | |
| # malicious-packages feed — and FAILS on any known-vulnerable or known-malicious | |
| # package (block-on-any-finding policy). OSV-Scanner exits non-zero when it finds | |
| # anything, which fails this job. | |
| # | |
| # Runs on every PR (incl. Dependabot bumps), on pushes to main, and daily to | |
| # catch advisories disclosed after a dependency was already merged — a PR is | |
| # the only thing that surfaced a scheduled failure before this, so a scan that | |
| # broke on `main` between PRs went unnoticed until the next one happened to | |
| # touch the lockfile. | |
| # | |
| # A daily scheduled failure also posts to Slack (see the notify step below, | |
| # gated on github.event_name == 'schedule') — PR and push runs don't, since | |
| # those failures are already visible to whoever opened or merged the PR | |
| # without needing a second channel. Posting is itself optional: it silently | |
| # no-ops when the SLACK_WEBHOOK_URL repository secret isn't set. | |
| # | |
| # Triage / allow-listing unfixable advisories: see SECURITY.md and osv-scanner.toml | |
| # (auto-loaded from the repo root by OSV-Scanner). | |
| # | |
| # Third-party actions are pinned to a commit SHA (we're a supply-chain tool — | |
| # practice what we preach). | |
| name: Supply Chain | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| schedule: | |
| - cron: "17 4 * * *" # daily, 04:17 UTC | |
| workflow_dispatch: | |
| # Least privilege: the scan only needs to read the checked-out source. | |
| # contents:read is also available to Dependabot PRs (read-only token), so the | |
| # gate enforces on dependency-bump PRs too. | |
| permissions: | |
| contents: read | |
| jobs: | |
| osv-scanner: | |
| name: OSV-Scanner | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| # No git ops after checkout; don't leave the token in .git/config. | |
| persist-credentials: false | |
| # Both lockfiles, in one scan. `Cargo.lock`'s 238 packages were covered by | |
| # nothing at all — not this job, which was only ever given `bun.lock`, and | |
| # not Dependabot, which had no `cargo` ecosystem — for a TLS stack that | |
| # compiles into a root-installed system service. | |
| - name: Scan bun.lock and Cargo.lock for known-vulnerable / malicious dependencies | |
| id: scan | |
| uses: google/osv-scanner-action/osv-scanner-action@f4cfcc01edc9c8b756a9b873b7a623ca674da51e # v2.3.8 | |
| with: | |
| scan-args: |- | |
| --lockfile=bun.lock | |
| --lockfile=Cargo.lock | |
| # Only the schedule run notifies — nothing on main touched the lockfile, | |
| # so nobody is watching it the way a PR author watches their own checks | |
| # or a push failure shows up against the commit they just merged. Same | |
| # webhook + `node -e … | curl` idiom integration-suite/run.sh uses. | |
| # `failure()` is required, not decorative: a bare `if:` expression is | |
| # implicitly ANDed with success(), so without it this step would be | |
| # skipped every time — the one time it's meant to run is exactly when | |
| # the job already failed. | |
| - name: Notify Slack on failure | |
| if: failure() && steps.scan.outcome == 'failure' && github.event_name == 'schedule' | |
| env: | |
| SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
| run: | | |
| if [ -z "$SLACK_WEBHOOK_URL" ]; then | |
| echo "(no SLACK_WEBHOOK_URL set — not posted)" >&2 | |
| exit 0 | |
| fi | |
| run_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" | |
| text="🔴 *Supply Chain scan failed* on \`${GITHUB_REF_NAME}\` (${GITHUB_EVENT_NAME}) — known-vulnerable or known-malicious dependency detected. <${run_url}|View run>" | |
| payload="$(node -e 'const t=require("fs").readFileSync(0,"utf8");process.stdout.write(JSON.stringify({text:t}))' <<<"$text")" | |
| for attempt in 1 2 3; do | |
| code="$(curl -sS --connect-timeout 10 --max-time 30 \ | |
| -o /dev/null -w '%{http_code}' -X POST -H 'Content-type: application/json' \ | |
| --data "$payload" "$SLACK_WEBHOOK_URL" 2>/dev/null || echo 000)" | |
| if [ "$code" = 200 ]; then echo "✓ posted to Slack webhook"; exit 0; fi | |
| echo "⚠️ Slack webhook POST attempt $attempt returned HTTP $code" >&2 | |
| [ "$attempt" -lt 3 ] && sleep 5 | |
| done | |
| echo "✗ Slack webhook POST failed after 3 attempts" >&2 | |
| exit 1 |