Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions .github/workflows/osv-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@
# 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 weekly to
# catch advisories disclosed after a dependency was already merged.
# 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.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
#
# Triage / allow-listing unfixable advisories: see SECURITY.md and osv-scanner.toml
# (auto-loaded from the repo root by OSV-Scanner).
Expand All @@ -22,7 +31,7 @@ on:
push:
branches: [main]
schedule:
- cron: "17 4 * * 1" # Mondays 04:17 UTC
- cron: "17 4 * * *" # daily, 04:17 UTC
workflow_dispatch:

# Least privilege: the scan only needs to read the checked-out source.
Expand All @@ -46,8 +55,39 @@ jobs:
# 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@9fd1bcce27f67e3bd819a0a7620e332803dc43bc # 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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 1.0.0-beta.13 — 2026-08-10

### Fixes
- Bump the `postcss` override from `8.5.23` to `8.5.26` to pull in `nanoid@^3.3.17`, clearing a high-severity OSV advisory (GHSA-2v37-7h3g-55p8) against the transitively-locked `nanoid@3.3.16`. (#670)
- Move the `Supply Chain` workflow's scheduled OSV-Scanner run from weekly to daily, and optionally post the daily run's failures to Slack when `SLACK_WEBHOOK_URL` is configured — a scheduled failure on `main` previously surfaced only when the next PR happened to touch the lockfile, since a red scheduled run has no PR author to notice it. PR and push runs don't post; those failures are already visible to whoever opened or merged the PR. The notify step needed its own `failure()` clause — a bare `if:` without one is implicitly ANDed with `success()`, so without it the step would have been silently skipped every single time (the one time it's meant to run is exactly when the job already failed) — and now retries the webhook POST 3 times, exiting nonzero on exhaustion so a broken webhook fails visibly instead of a green step that posted nothing. (#670)

## 1.0.0-beta.13 — 2026-08-07

### Fixes
Expand Down
10 changes: 8 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ advisories **and** the [OpenSSF malicious-packages feed](https://github.com/ossf

**Policy: block on any finding.** The gate fails on *any* known-vulnerable or
malicious package in the tree — not just newly introduced ones. It runs on every
PR, on pushes to `main`, and weekly (to catch advisories disclosed after a
dependency was already merged).
PR, on pushes to `main`, and daily (to catch advisories disclosed after a
dependency was already merged). A daily run that fails on `main` — where there's
no PR author already looking at the check — also posts to Slack, via the
`SLACK_WEBHOOK_URL` repository secret.

### 2. Socket — behavioral early-warning

Expand Down Expand Up @@ -71,3 +73,7 @@ These steps live outside the repo and require admin access:
3. *(Optional)* For a Socket CI gate in addition to the App, add a
`SOCKET_SECURITY_API_KEY` repository secret and the Socket CI action — deferred
until tuned, since behavioral findings can have false positives.
4. **Slack alert on a failed daily scan**: set the `SLACK_WEBHOOK_URL` repository
secret to a Slack Incoming Webhook URL (the same secret `integration-suite`
already posts to). Without it, the daily job still runs and still fails CI on a
finding — it just skips the Slack POST and logs that the secret is unset.
6 changes: 3 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"yaml": "^2.9.0"
},
"overrides": {
"postcss": "8.5.23",
"postcss": "8.5.26",
"eslint-plugin-react-hooks": "7.0.1",
"vite": "8.0.16",
"undici": "7.29.0",
Expand Down