ci: extend supply-chain audit + smoke jobs to new lockfiles
Point the existing audit + install + content-sanity workflows at the two lockfiles PR #5604 introduced (studio/package-lock.json and studio/backend/core/data_recipe/oxc-validator/package-lock.json) so the Studio Tauri CLI holder and the oxc-validator runtime benefit from the same per-PR coverage the frontend already has. release-desktop.yml: - Tauri CLI install: `npm install --save-dev --prefix studio` -> `npm ci --prefix studio --no-fund --no-audit`. - Frontend install: `npm install --no-fund --no-audit` -> `npm ci --no-fund --no-audit`. - New "Lockfile supply-chain audit" step inserted BEFORE the Tauri CLI install so the structural audit fires before any tarball-side lifecycle script. studio-tauri-smoke.yml: - Tauri CLI install: `npm install --save-dev --prefix studio` -> `npm ci --prefix studio --no-fund --no-audit`. - Existing audit step relocated to run BEFORE the Tauri CLI install (same ordering rationale). wheel-smoke.yml: - One-line content-sanity assertion ensuring the oxc-validator package-lock.json is shipped in the wheel. security-audit.yml: - `paths` trigger gains the 4 new entries (oxc + Tauri CLI holder package.json + package-lock.json). - `Scanned:` summary string updated to list the two new lockfiles. - OSV-scanner picks up `--lockfile=` for both. - Two new `npm audit` steps: oxc-validator runtime + Studio Tauri CLI holder. - `npm audit signatures` block split into three (frontend / oxc / Tauri CLI), each preceded by `npm ci --ignore-scripts` in its own directory. - `check_new_install_scripts.py` invocation extended to diff both new lockfiles base->head, with `git show ... 2>/dev/null || echo '{}'` fallback for PRs whose base predates #5604. - `upload-artifact` paths extended for the new log files. Deliberately NOT included: removing `continue-on-error` from the existing `scan_npm_packages` job. That is a policy flip from advisory to blocking and is orthogonal to install-path hardening.
This commit is contained in:
parent
8dce77f80d
commit
5cfbb7b6cf
4 changed files with 150 additions and 31 deletions
33
.github/workflows/release-desktop.yml
vendored
33
.github/workflows/release-desktop.yml
vendored
|
|
@ -361,14 +361,21 @@ jobs:
|
|||
with:
|
||||
node-version: 24
|
||||
|
||||
- name: Lockfile supply-chain audit (pre-install scan)
|
||||
shell: bash
|
||||
# Runs BEFORE any `npm ci` so the structural audit
|
||||
# (lockfile_supply_chain_audit.py) catches an injection-pattern
|
||||
# lockfile before any tarball-side lifecycle script runs. The
|
||||
# `npm ci` invocations below consume committed lockfiles
|
||||
# (shipped in #5604) so they refuse to deviate from the
|
||||
# audited shape.
|
||||
run: python3 scripts/lockfile_supply_chain_audit.py
|
||||
|
||||
- name: Install pinned Tauri CLI
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
# required for `vite build`. The pre-install lockfile structural
|
||||
# audit (lockfile_supply_chain_audit.py) is the practical defence
|
||||
# against the npm postinstall-dropper class -- it fires BEFORE any
|
||||
# tarball runs, on the injection pattern itself rather than an
|
||||
# advisory-DB lookup.
|
||||
run: npm install --save-dev --prefix studio @tauri-apps/cli@2.10.1 --no-fund --no-audit
|
||||
# `npm ci --prefix studio` consumes the committed
|
||||
# studio/package-lock.json (shipped in #5604) and refuses to
|
||||
# install if the resolved tree drifts from that lockfile.
|
||||
run: npm ci --prefix studio --no-fund --no-audit
|
||||
|
||||
- name: Verify pinned Tauri CLI
|
||||
shell: bash
|
||||
|
|
@ -443,13 +450,11 @@ jobs:
|
|||
|
||||
- name: Install frontend dependencies
|
||||
working-directory: studio/frontend
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
# required for `vite build`. The pre-install lockfile structural
|
||||
# audit (lockfile_supply_chain_audit.py) is the practical defence
|
||||
# against the npm postinstall-dropper class -- it fires BEFORE any
|
||||
# tarball runs, on the injection pattern itself rather than an
|
||||
# advisory-DB lookup.
|
||||
run: npm install --no-fund --no-audit
|
||||
# `npm ci` consumes the committed studio/frontend/package-lock.json
|
||||
# and refuses to install if the resolved tree drifts from that
|
||||
# lockfile. The pre-install audit step above already verified the
|
||||
# lockfile shape before any lifecycle script runs.
|
||||
run: npm ci --no-fund --no-audit
|
||||
|
||||
# ── Rust ──
|
||||
- name: Install Rust stable
|
||||
|
|
|
|||
125
.github/workflows/security-audit.yml
vendored
125
.github/workflows/security-audit.yml
vendored
|
|
@ -53,6 +53,10 @@ on:
|
|||
- 'studio/backend/requirements/**'
|
||||
- 'studio/frontend/package.json'
|
||||
- 'studio/frontend/package-lock.json'
|
||||
- 'studio/backend/core/data_recipe/oxc-validator/package.json'
|
||||
- 'studio/backend/core/data_recipe/oxc-validator/package-lock.json'
|
||||
- 'studio/package.json'
|
||||
- 'studio/package-lock.json'
|
||||
- 'studio/src-tauri/Cargo.toml'
|
||||
- 'studio/src-tauri/Cargo.lock'
|
||||
- 'pyproject.toml'
|
||||
|
|
@ -278,7 +282,7 @@ jobs:
|
|||
{
|
||||
echo "## Lockfile supply-chain audit"
|
||||
echo
|
||||
echo "Scanned: studio/frontend/package-lock.json + studio/src-tauri/Cargo.lock"
|
||||
echo "Scanned: studio/frontend/package-lock.json + studio/backend/core/data_recipe/oxc-validator/package-lock.json + studio/package-lock.json + studio/src-tauri/Cargo.lock"
|
||||
echo
|
||||
echo "No structural anomalies or known IOC strings."
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
|
@ -307,6 +311,42 @@ jobs:
|
|||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# npm: oxc-validator runtime (data_recipe parser sandbox)
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
- name: npm audit (oxc-validator runtime)
|
||||
continue-on-error: true
|
||||
working-directory: studio/backend/core/data_recipe/oxc-validator
|
||||
run: |
|
||||
set +e
|
||||
npm audit --audit-level=high | tee ../../../../../logs-npm-audit-oxc.txt
|
||||
npm audit --json > ../../../../../logs-npm-audit-oxc.json || true
|
||||
{
|
||||
echo "## npm audit (oxc-validator runtime)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 ../../../../../logs-npm-audit-oxc.txt
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# npm: Studio Tauri CLI holder
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
- name: npm audit (Studio Tauri CLI holder)
|
||||
continue-on-error: true
|
||||
working-directory: studio
|
||||
run: |
|
||||
set +e
|
||||
npm audit --audit-level=high | tee ../logs-npm-audit-tauri-cli.txt
|
||||
npm audit --json > ../logs-npm-audit-tauri-cli.json || true
|
||||
{
|
||||
echo "## npm audit (Studio Tauri CLI holder)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 ../logs-npm-audit-tauri-cli.txt
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# cargo: Studio Tauri shell
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
|
|
@ -348,6 +388,8 @@ jobs:
|
|||
/tmp/osv-scanner --version
|
||||
/tmp/osv-scanner scan source \
|
||||
--lockfile=studio/frontend/package-lock.json \
|
||||
--lockfile=studio/backend/core/data_recipe/oxc-validator/package-lock.json \
|
||||
--lockfile=studio/package-lock.json \
|
||||
--lockfile=studio/src-tauri/Cargo.lock \
|
||||
--lockfile=requirements.txt:audit-reqs/unsloth-deps.txt \
|
||||
--lockfile=requirements.txt:audit-reqs/studio.txt \
|
||||
|
|
@ -639,6 +681,10 @@ jobs:
|
|||
logs-pip-audit.txt
|
||||
logs-npm-audit.txt
|
||||
logs-npm-audit.json
|
||||
logs-npm-audit-oxc.txt
|
||||
logs-npm-audit-oxc.json
|
||||
logs-npm-audit-tauri-cli.txt
|
||||
logs-npm-audit-tauri-cli.json
|
||||
logs-cargo-audit.txt
|
||||
logs-osv-scanner.txt
|
||||
logs-semgrep.txt
|
||||
|
|
@ -1077,7 +1123,15 @@ jobs:
|
|||
working-directory: studio/frontend
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: npm audit signatures (informational)
|
||||
- name: Install oxc-validator deps (--ignore-scripts)
|
||||
working-directory: studio/backend/core/data_recipe/oxc-validator
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: Install Studio Tauri CLI holder deps (--ignore-scripts)
|
||||
working-directory: studio
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: npm audit signatures (Studio frontend, informational)
|
||||
# Surfaces unsigned / mis-signed packages from the npm
|
||||
# transparency log. continue-on-error during baseline-build
|
||||
# phase; promote to hard gate once the lockfile is fully
|
||||
|
|
@ -1089,7 +1143,37 @@ jobs:
|
|||
LOG=logs-audit-signatures.txt
|
||||
npm audit signatures 2>&1 | tee "$LOG"
|
||||
{
|
||||
echo "## npm audit signatures"
|
||||
echo "## npm audit signatures (Studio frontend)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$LOG"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: npm audit signatures (oxc-validator, informational)
|
||||
working-directory: studio/backend/core/data_recipe/oxc-validator
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set -o pipefail
|
||||
LOG=logs-audit-signatures-oxc.txt
|
||||
npm audit signatures 2>&1 | tee "$LOG"
|
||||
{
|
||||
echo "## npm audit signatures (oxc-validator)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$LOG"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: npm audit signatures (Studio Tauri CLI holder, informational)
|
||||
working-directory: studio
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set -o pipefail
|
||||
LOG=logs-audit-signatures-tauri-cli.txt
|
||||
npm audit signatures 2>&1 | tee "$LOG"
|
||||
{
|
||||
echo "## npm audit signatures (Studio Tauri CLI holder)"
|
||||
echo
|
||||
echo '```'
|
||||
tail -200 "$LOG"
|
||||
|
|
@ -1101,16 +1185,40 @@ jobs:
|
|||
run: |
|
||||
set -e
|
||||
BASE_SHA="${{ github.event.pull_request.base.sha }}"
|
||||
git show "$BASE_SHA:studio/frontend/package-lock.json" \
|
||||
> /tmp/base-package-lock.json
|
||||
# `|| echo '{}'` fallback covers PRs whose base predates the
|
||||
# new lockfiles (they only landed in #5604); without it the
|
||||
# diff step would crash trying to read a non-existent blob.
|
||||
git show "$BASE_SHA:studio/frontend/package-lock.json" 2>/dev/null \
|
||||
> /tmp/base-package-lock.json \
|
||||
|| echo '{}' > /tmp/base-package-lock.json
|
||||
git show "$BASE_SHA:studio/backend/core/data_recipe/oxc-validator/package-lock.json" 2>/dev/null \
|
||||
> /tmp/base-package-lock-oxc.json \
|
||||
|| echo '{}' > /tmp/base-package-lock-oxc.json
|
||||
git show "$BASE_SHA:studio/package-lock.json" 2>/dev/null \
|
||||
> /tmp/base-package-lock-tauri-cli.json \
|
||||
|| echo '{}' > /tmp/base-package-lock-tauri-cli.json
|
||||
|
||||
- name: Diff for newly-added install-script deps
|
||||
- name: Diff for newly-added install-script deps (Studio frontend)
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
python3 scripts/check_new_install_scripts.py \
|
||||
--base /tmp/base-package-lock.json \
|
||||
--head studio/frontend/package-lock.json
|
||||
|
||||
- name: Diff for newly-added install-script deps (oxc-validator)
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
python3 scripts/check_new_install_scripts.py \
|
||||
--base /tmp/base-package-lock-oxc.json \
|
||||
--head studio/backend/core/data_recipe/oxc-validator/package-lock.json
|
||||
|
||||
- name: Diff for newly-added install-script deps (Studio Tauri CLI holder)
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
python3 scripts/check_new_install_scripts.py \
|
||||
--base /tmp/base-package-lock-tauri-cli.json \
|
||||
--head studio/package-lock.json
|
||||
|
||||
- name: Skip install-script diff (non-PR trigger)
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
|
|
@ -1121,6 +1229,9 @@ jobs:
|
|||
if: always()
|
||||
with:
|
||||
name: npm-audit-signatures-log
|
||||
path: studio/frontend/logs-audit-signatures.txt
|
||||
path: |
|
||||
studio/frontend/logs-audit-signatures.txt
|
||||
studio/backend/core/data_recipe/oxc-validator/logs-audit-signatures-oxc.txt
|
||||
studio/logs-audit-signatures-tauri-cli.txt
|
||||
if-no-files-found: ignore
|
||||
retention-days: 30
|
||||
|
|
|
|||
22
.github/workflows/studio-tauri-smoke.yml
vendored
22
.github/workflows/studio-tauri-smoke.yml
vendored
|
|
@ -60,14 +60,19 @@ jobs:
|
|||
with:
|
||||
workspaces: studio/src-tauri -> target
|
||||
|
||||
- name: Lockfile supply-chain audit (pre-install scan)
|
||||
# Runs BEFORE any npm install / npm ci so the structural audit
|
||||
# (lockfile_supply_chain_audit.py) catches an injection-pattern
|
||||
# lockfile before a single postinstall script is executed.
|
||||
run: python3 scripts/lockfile_supply_chain_audit.py
|
||||
|
||||
- name: Install pinned Tauri CLI (matches release-desktop.yml)
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
# required for `vite build`. The pre-install lockfile structural
|
||||
# audit (lockfile_supply_chain_audit.py) is the practical defence
|
||||
# against the npm postinstall-dropper class -- it fires BEFORE any
|
||||
# tarball runs, on the injection pattern itself rather than an
|
||||
# advisory-DB lookup.
|
||||
run: npm install --save-dev --prefix studio @tauri-apps/cli@2.10.1 --no-fund --no-audit
|
||||
# `npm ci --prefix studio` consumes the committed
|
||||
# studio/package-lock.json (shipped in #5604) and refuses to
|
||||
# install if the resolved tree drifts from that lockfile. The
|
||||
# pre-install audit above already verified the lockfile shape
|
||||
# itself before any tarball-side lifecycle script runs.
|
||||
run: npm ci --prefix studio --no-fund --no-audit
|
||||
|
||||
- name: Verify pinned Tauri CLI version
|
||||
run: |
|
||||
|
|
@ -75,9 +80,6 @@ jobs:
|
|||
echo "$out"
|
||||
[ "$out" = "tauri-cli 2.10.1" ] || { echo "::error::expected tauri-cli 2.10.1, got $out"; exit 1; }
|
||||
|
||||
- name: Lockfile supply-chain audit (pre-install scan)
|
||||
run: python3 scripts/lockfile_supply_chain_audit.py
|
||||
|
||||
- name: Frontend build (npm ci, vite)
|
||||
working-directory: studio/frontend
|
||||
# Lifecycle scripts (esbuild native-binary postinstall, etc.) are
|
||||
|
|
|
|||
1
.github/workflows/wheel-smoke.yml
vendored
1
.github/workflows/wheel-smoke.yml
vendored
|
|
@ -87,6 +87,7 @@ jobs:
|
|||
n = z.namelist()
|
||||
checks = {
|
||||
"lockfile shipped": any(s.endswith("studio/frontend/package-lock.json") for s in n),
|
||||
"oxc lockfile shipped": any(s.endswith("oxc-validator/package-lock.json") for s in n),
|
||||
"frontend dist shipped": any(s.endswith("studio/frontend/dist/index.html") for s in n),
|
||||
"no node_modules": not any("studio/frontend/node_modules/" in s for s in n),
|
||||
"no bun.lock": not any(s.endswith("studio/frontend/bun.lock") for s in n),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue