Skip to content

ci(security): add dependency review and bun audit checks#858

Merged
Nagi-ovo merged 4 commits into
Nagi-ovo:mainfrom
HavenXia:ci/vuln-check
Jul 22, 2026
Merged

ci(security): add dependency review and bun audit checks#858
Nagi-ovo merged 4 commits into
Nagi-ovo:mainfrom
HavenXia:ci/vuln-check

Conversation

@HavenXia

@HavenXia HavenXia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Closes #850

Adds the two dependency vulnerability checks approved in #850:

  • Dependency Review — runs on PRs, fail-on-severity: high. Covers what GitHub's dependency graph sees (direct deps + Actions); bun.lock transitives are handled by the audit job below.
  • Bun Audit — audits the full lockfile. Advisory findings never fail pull_request / push / workflow_dispatch (severity counts + Bun version in the job summary, raw JSON as artifact); schedule runs fail on high/critical findings to notify maintainers. Operational failures fail on every event: the step fails closed on missing, empty, or structurally invalid audit output instead of treating it as "no findings". The per-event behavior is documented at the top of the workflow file.

Per the maintainer constraints: no dependabot.yml, the workflow never modifies package.json / bun.lock, actions are pinned to release commit SHAs, and the Bun version matches ci.yml (1.3.12) to avoid result drift.

Validation

  • Local run against current main reproduces the triage baseline exactly: 99 advisories (3 critical / 40 high / 48 moderate / 8 low); simulated pull_request exits 0, schedule exits 1.
  • Fork validation runs (source-only PR not triggering the audit, lockfile-touching PR with both checks green, manual workflow_dispatch with summary, fail-closed fault injection) are linked in the comments below.
  • Fork PR behavior: runs get a read-only GITHUB_TOKEN; the workflow needs no secrets.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SAMGouFiJj4UQfDAJvJkZ4

Two dependency vulnerability checks per the approved plan:

- dependency-review: fails PRs introducing dependencies with high+
  advisories. Covers what GitHub's dependency graph sees (direct deps
  and Actions; bun.lock transitives are out of its reach).
- bun audit: audits the full lockfile. Report-only and green on
  pull_request/push/workflow_dispatch (severity counts in the job
  summary, raw JSON as artifact); scheduled runs fail on high/critical
  findings to notify maintainers.

The workflow is check/report only: it never modifies package.json or
bun.lock and opens no upgrade PRs. Actions are pinned to release
commit SHAs; Bun version matches ci.yml to avoid result drift.

Closes Nagi-ovo#850

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PVZLWprb3HLfiDvc6YuHNw
@HavenXia

HavenXia commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Validation evidence (runs on my fork):

Scenario Result
Source-only PR — Security workflow must not trigger HavenXia/voyager#1: only CI ran, no Security checks
package.json-touching PR — both checks appear, report-only green HavenXia/voyager#2run: Dependency Review ✅ / Bun Audit ✅
Manual workflow_dispatch — job summary with severity counts + Bun version run
Push to main (paths-filtered) — report-only green, JSON artifact uploaded run

@HavenXia
HavenXia marked this pull request as ready for review July 22, 2026 16:36

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 609e27be6b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread .github/workflows/security.yml Outdated
bun audit --json > audit.json || true
# An invalid file means the audit itself broke (network, registry) —
# that must fail on every event, unlike advisory findings below.
jq empty audit.json

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail closed when audit output is empty

Because line 70 masks every bun audit nonzero exit with || true, a registry/network failure or unsupported audit command can leave audit.json as a zero-byte file; jq empty audit.json exits successfully on empty input, so the severity variables become empty and the scheduled high/critical gate evaluates as zero. In that scenario the security workflow goes green without actually auditing dependencies, so this validation needs to require real JSON content before treating the audit as report-only.

Useful? React with 👍 / 👎.

@anontokyo-dev anontokyo-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review result: changes requested

I verified the approved #850 scope and the supplied fork evidence.

Verified

  • ✅ The PR only adds .github/workflows/security.yml; it does not add Dependabot or modify package.json / bun.lock.
  • ✅ Permissions are limited to contents: read, and checkout credential persistence is disabled.
  • ✅ Every Action is pinned to a full SHA that resolves to a stable release:
    • actions/checkoutv4.3.1
    • actions/dependency-review-actionv4.9.0
    • oven-sh/setup-bunv2.2.0
    • actions/upload-artifactv7.0.1
  • ✅ Bun 1.3.12 matches the existing CI workflow.
  • ✅ Fork evidence is reproducible: source-only PR skips Security; dependency-manifest PR runs both checks green; dispatch and push are report-only green.
  • ✅ I downloaded the dispatch artifact and confirmed valid JSON with 99 advisories, including 3 critical and 40 high.
  • ✅ No UI is changed, so screenshots are not required; the linked workflow runs are the appropriate evidence.

Blocking P1

The latest Codex finding is valid:

#858 (comment)

bun audit --json > audit.json || true masks every non-zero exit. A zero-byte file then passes jq empty audit.json with exit code 0; the count variables become empty, Bash treats the scheduled high/critical total as zero, and the workflow can report success without performing an audit.

Please fail closed before counting advisories. At minimum:

  1. Capture the audit exit status instead of discarding it blindly.
  2. Require audit.json to be non-empty.
  3. Validate the expected JSON structure, not only JSON syntax.
  4. Continue treating a valid advisory result as report-only for PR/push/dispatch, while actual command/network/output failures fail every event.

Please add validation evidence showing that:

  • normal audit JSON still produces the expected 99 / 3 critical / 40 high summary and remains green for dispatch;
  • an empty or malformed audit output fails the job;
  • the scheduled high/critical enforcement path still exits non-zero.

All current CI checks are green, but this P1 must be fixed before approval. This PR changes the sensitive .github/workflows/** path, so even after technical approval it still requires Nagi's explicit pre-merge confirmation.

Capture the audit exit code instead of masking it, reject empty output
and JSON that is not an advisory map, and treat a nonzero exit with
zero parsed advisories as a failed audit. Findings remain report-only
on pull_request/push/workflow_dispatch; infrastructure failures now
fail on every event.

Addresses the P1 in the Nagi-ovo#858 review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAMGouFiJj4UQfDAJvJkZ4
@HavenXia

Copy link
Copy Markdown
Contributor Author

P1 addressed in ffff4fa — the audit step now fails closed:

  • captures the bun audit exit code instead of masking it with || true
  • rejects empty output ([ -s audit.json ]) and JSON that is not an advisory map (jq -e structural check: top-level object, every entry an object with severity)
  • treats a nonzero exit with zero parsed advisories as a failed audit (cross-check)
  • advisory findings remain report-only on pull_request / push / workflow_dispatch; the scheduled high/critical enforcement is unchanged

Requested evidence

Path Result
Normal audit JSON, workflow_dispatch (fixed code) ✅ green, summary shows 99 total / 3 critical / 40 high — run
Normal audit JSON, push to main (fixed code) ✅ green — run
Empty audit output (fault injection, HavenXia/voyager#3) ❌ fails: bun audit produced no outputrun
Malformed audit output (same PR, second commit) ❌ fails: output is not the expected advisory maprun
Scheduled high/critical enforcement (schedule cannot be triggered manually) exit 1 preserved — local matrix below
Local 8-path matrix against the extracted step logic
PASS real (event=pull_request want=0 got=0)      # counts: 99 / 3 critical / 40 high / 48 moderate / 8 low
PASS real (event=workflow_dispatch want=0 got=0)
PASS real (event=schedule want=1 got=1)          # enforcement path still exits nonzero
PASS empty (event=pull_request want=1 got=1)
PASS malformed (event=schedule want=1 got=1)
PASS badstruct (event=pull_request want=1 got=1) # valid JSON, wrong shape
PASS crosscheck (event=pull_request want=1 got=1) # exit!=0 with zero advisories
PASS clean-exit0 (event=pull_request want=0 got=0) # clean tree stays green

@HavenXia
HavenXia requested a review from anontokyo-dev July 22, 2026 17:16
@anontokyo-dev

Copy link
Copy Markdown
Collaborator

Re-review status for ffff4fa7

The blocking P1 is technically addressed. I verified the implementation and the supplied fork runs:

  • bun audit exit status is captured instead of masked.
  • ✅ Empty output fails the audit step with the expected error.
  • ✅ Malformed JSON fails the audit step with the expected structural-validation error.
  • ✅ Valid advisory JSON remains report-only for dispatch/push and still reports the 99 / 3 critical / 40 high baseline.
  • ✅ The scheduled high/critical enforcement path remains non-zero in the supplied matrix.
  • ✅ Dependency Review, Bun Audit, Format, Lint, Typecheck, Test, i18n, all four browser builds, and Native Swift/Xcode are green on the current head.
  • ✅ No UI is changed, so screenshots are not applicable; the linked workflow runs are the correct evidence.

Small required consistency update

The workflow header still says PR, push, and dispatch are “always green.” That is now intentionally false: advisories are report-only on those events, but missing/malformed output and audit failures fail closed on every event. Please update lines 6–8 to say that advisory findings do not fail those events, while operational/output failures do. Please make the same wording correction in the PR description.

The latest repository Codex review still covers 609e27be6b, not current head ffff4fa7c9. After the wording update, let CI and automatic review cover the new final head; no manual re-trigger is needed. This remains a sensitive .github/workflows/** change and still requires Nagi’s explicit final pre-merge approval after technical approval.

Operational failures (missing, empty, or malformed audit output) fail
on every event; the header comment now states this instead of calling
pull_request/push/dispatch always green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAMGouFiJj4UQfDAJvJkZ4

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 392754e6e8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

persist-credentials: false
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4
with:
fail-on-severity: high

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add dev scopes to dependency review

For PRs that add or upgrade a vulnerable devDependency, this check remains green: the dependency-review-action docs list fail-on-scopes with a default of runtime, and the Bun audit job is report-only on PRs, pushes, and manual runs. Since this repo relies heavily on dev tooling for building and shipping the extension, a high/critical advisory in a newly introduced build dependency would not be blocked until the weekly scheduled audit; add an explicit fail-on-scopes: development, runtime, unknown (or the intended scope list) alongside the severity gate.

Useful? React with 👍 / 👎.

fail-on-scopes defaults to runtime only, which would let a PR introduce
a vulnerable devDependency unblocked until the weekly audit. Build and
release tooling is part of the extension's supply chain, so block
development and unknown scopes as well.

Addresses the P2 in the Nagi-ovo#858 review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAMGouFiJj4UQfDAJvJkZ4
@HavenXia

Copy link
Copy Markdown
Contributor Author

P2 addressed in 66249b4fail-on-scopes: runtime, development, unknown added next to the severity gate. Build/release tooling is part of the extension's supply chain, so development-scoped advisories now block PRs too; unknown fails closed.

Evidence (HavenXia/voyager#4, fault-injection PR adding lodash@4.17.20 to devDependencies):

  • ❌ Dependency Review fails and names the dev-scoped advisories (GHSA-35jh-r3h4-6jhm command injection, GHSA-r5fr-rjxr-66jc code injection, both high) — run
  • ✅ Bun Audit on the same PR stays report-only green, per the approved behavior
  • ✅ This PR's own Dependency Review remains green (no dependencies introduced), confirming the stricter scopes add no noise

@Nagi-ovo

Copy link
Copy Markdown
Owner

@anontokyo-dev Please review. LGTM

@anontokyo-dev

anontokyo-dev commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Final re-review status for 66249b4

The implementation is technically ready from my manual review:

  • ✅ The previous fail-closed P1 remains fixed: empty, malformed, structurally invalid, and inconsistent audit output cannot pass silently.
  • ✅ The latest Codex P2 is fixed with fail-on-scopes: runtime, development, unknown.
  • ✅ I verified the fork fault-injection run: a high-severity vulnerability added only to devDependencies makes Dependency Review fail and reports both lodash advisories, while Bun Audit remains report-only as designed.
  • ✅ Dependency Review, Bun Audit, Format, Lint, Typecheck, Test, i18n, Chrome/Edge/Firefox/Safari builds, and Native Swift/Xcode all pass on 66249b4.
  • ✅ The contributor has supplied validation for the affected workflow paths, including normal, report-only, scheduled-enforcement, empty-output, malformed-output, wrong-shape, cross-check, and development-scope cases.
  • ✅ No UI is changed, so screenshots are not applicable; the linked workflow runs are the correct evidence.
  • ⚠️ This changes the sensitive .github/workflows/** path.

Remaining review gate

The latest repository Codex review covers 392754e6, while the current head is 66249b4. Please run the repository Codex review on the current head. If it returns clean, I can replace my earlier changes-requested review with approval and send the final merge recommendation.

@Nagi-ovo

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 66249b4016

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@anontokyo-dev anontokyo-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at 66249b4

  • ✅ The fail-closed audit handling is verified.
  • ✅ Runtime, development, and unknown dependency scopes are enforced.
  • ✅ The fault-injection evidence covers affected behavior and failure paths.
  • ✅ All required CI checks pass, including Security, quality checks, tests, i18n, four browser builds, and Native Swift/Xcode.
  • ✅ The repository Codex review now covers the exact current head and reports no major issues.
  • ✅ No UI is changed, so screenshots are not applicable.

Technical review is complete. This PR changes the sensitive .github/workflows/** path, so merge still requires the final maintainer authorization.

@Nagi-ovo
Nagi-ovo merged commit 4c94575 into Nagi-ovo:main Jul 22, 2026
13 checks passed
@Nagi-ovo

Copy link
Copy Markdown
Owner

Thanks so much!!!

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

You are welcome! The technical approval is recorded on the current head, and the PR is ready for the final merge authorization.

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

Merged successfully as 4c94575af0. Dependency Review and fail-closed Bun Audit checks are now part of the repository security workflow. Thank you @HavenXia for the careful implementation, fault-injection evidence, and review follow-through! 🎇🎇🎇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CI] Add dependency vulnerability checks to CI

3 participants