feat(security): schedule the advisory early-warning scan - #7398
feat(security): schedule the advisory early-warning scan#7398Dongni-Yang wants to merge 8 commits into
Conversation
Public advisories can affect maintained packages weeks before they reach the reviewed corpus that npm audit enforces (#7276 timeline). Add an early-warning path and per-audit provenance so those windows become visible and provable from retained artifacts: - scripts/lib/advisory-early-warning.mts: dependency-free correlation of GitHub Security Advisory records (reviewed, unreviewed, and malware) against the reviewed-graph package inventories; exact npm name and parseable-range matches produce investigate signals, ambiguous or CPE-style matches stay informational and never block. - .github/workflows/advisory-early-warning.yaml: six-hourly paginated scan of all three advisory types, correlated against the inventory, reporting into one rolling security-labeled issue (marker- and author-verified, deduplicated by advisory id plus package). - scripts/audit-reviewed-npm-graph.mts and the wechat runtime audit action now write a *.provenance.json sidecar next to each raw report: scanner and npm/node versions, configured registry and derived bulk advisory endpoint, run start/end times, extracted advisory ids, and a failure marker whenever the audit attempt itself failed - including npm's parseable-error-JSON failure mode - so a failed attempt can never be mistaken for a comparable non-detection. - docs/security/advisory-early-warning.md: how the path works plus proposed defaults (scope, ownership, alert destination, SLA) pending maintainer confirmation. Refs #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CodeRabbit: every source file carries the SPDX header; match the sibling docs/security file comment syntax. Refs #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Narrow #7354 to its non-operational pieces per review: the correlation module, the local scan CLI, and the per-audit provenance sidecars. The six-hourly workflow (issues: write) and the proposed policy defaults move to a follow-up PR that stays draft until product/security owners sign off on #7338 scope, ownership, alert-destination, and response questions. Refs #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reinstates the operational slice split out of #7354: the six-hourly workflow (permissions: contents read, issues write) that fetches reviewed, unreviewed, and malware advisories naming reviewed-inventory packages, correlates them with the scan CLI, and routes signals into one rolling security-labeled issue; plus the proposed policy defaults for #7338 open policy questions. Stays draft until product/security owners record sign-off on #7338. Refs #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
📝 WalkthroughWalkthroughThe pull request adds a scheduled GitHub Actions workflow that collects and deduplicates npm advisories, correlates them into signals, enriches CVE-bearing signals with bounded NVD data, and maintains a rolling security issue. Documentation describes the operation and proposed policy defaults. ChangesAdvisory early-warning automation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant AdvisoryScanner
participant GitHubAdvisoriesAPI
participant NVD
participant GitHubIssuesAPI
GitHubActions->>AdvisoryScanner: List inventory packages
AdvisoryScanner->>GitHubAdvisoriesAPI: Fetch paginated advisories
GitHubAdvisoriesAPI-->>AdvisoryScanner: Return advisory records
AdvisoryScanner-->>GitHubActions: Write advisories.json and signals.json
GitHubActions->>NVD: Reconcile capped CVE set
NVD-->>GitHubActions: Return NVD records or unavailable status
GitHubActions->>AdvisoryScanner: Incorporate NVD annotations
AdvisoryScanner-->>GitHubActions: Write final signals.json
GitHubActions->>GitHubIssuesAPI: Find, create, or update rolling security issue
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit 045b81c in the TypeScript / code-coverage/cliThe overall coverage in commit 045b81c in the Show a code coverage summary of the most impacted files.
Updated |
PR Review Advisor — InformationalAdvisor assessment: Informational / high confidence Model lanes
Nemotron output stays in workflow artifacts and does not change the assessment above. E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: None 1 warning · 0 suggestionsWarningsWarnings do not block.
|
…ce records (#7354) ## Summary Implements the non-operational, code-shaped acceptance criteria of #7338: a correlation library and local CLI that surface public advisories before they reach the reviewed corpus `npm audit` enforces, and provenance records for every audit so disclosure-to-detection timelines are provable from retained artifacts. **Scope note (review follow-up):** per review, the scheduled workflow (`issues: write`) and its operating-policy documentation were split out to #7398, which stays draft until product/security owners record sign-off on #7338's scope / rescan-ownership / alert-destination / response-expectation criterion. This PR defines no operational surface: nothing here is scheduled, holds write permissions, or encodes policy. ## Changes - **Correlation module** (`scripts/lib/advisory-early-warning.mts`, dependency-free): parses GitHub Security Advisory records and correlates them against the reviewed-graph package inventories (`ci/reviewed-npm-audit.json` specs + locked-graph package-locks, alias-aware). Exact npm package + parseable-range matches emit `investigate` signals; ambiguous or CPE-style matches stay `informational` — per the issue, ambiguous matches never block or mutate anything. Unparseable ranges fail safe (noisy, never silent). - **Scan CLI** (`scripts/advisory-early-warning-scan.mts`): local-file-only driver over the module. `--list-packages` emits inventory package names (the input for `/advisories` API queries); `--advisories <file> [--output <file>]` correlates fetched records and prints/writes structured signals. Exits 0 with or without signals; no network or tokens; it does not modify inputs or external state, and `--output` writes the requested local signals file. - **Provenance sidecars**: `scripts/audit-reviewed-npm-graph.mts` (reviewed graphs) and `.github/actions/ci-wechat-runtime-audit/audit.sh` (wechat runtime graph) now write a `*.provenance.json` next to each raw report: scanner identity, npm/node versions, configured registry and derived bulk advisory endpoint, run start/end times, audited package identity, raw report path, extracted GHSA ids — and a `failure` marker whenever the audit attempt itself failed, **including npm's dominant failure mode of parseable error JSON** (verified against a captured dead-registry `npm audit --json` output), so a failed attempt can never masquerade as a clean non-detection. Sidecars ride the existing artifact uploads. - **Docs** (`docs/security/advisory-early-warning.md`): how the correlation works, what each advisory type contributes, CLI usage, and the provenance recorded per audit. Scheduled operation and the proposed policy defaults now live in #7398's version of this page, gated on #7338 sign-off. ## Scope notes - Covered from the issue's acceptance criteria: pre-reviewed-advisory fixture + correlation signal, ambiguous-match non-blocking, reviewed-audit enforcement untouched and authoritative, per-audit provenance incl. actual endpoint (verified empirically: npm ≥7 posts to the bulk endpoint only — the sidecar records no fictitious fallback). - Moved to #7398 (gated on the product/security-owner criterion): scheduled rescans on advisory-data changes, alert routing, and the policy defaults (scope, rescan ownership, alert destination, response SLAs). - Explicitly left as proposals or follow-ups: the npm advisory **database snapshot time** (not exposed by `npm audit`; the sidecar records endpoints + run window instead, and "last comparable non-detection" comes from diffing `advisoryIds` across retained runs), per-upstream-repo advisory polling (needs a package→repo map; named in the doc as the natural extension), Trivy/image-digest provenance, and the #7276 post-mortem classification. ## Testing - 67/67 across the two touched suites (`advisory-early-warning` 49, `reviewed-npm-audit` 18 incl. an integration-style test proving sidecar-write-before-rethrow with a fake npm); tsc strict clean; biome clean; shellcheck/bash -n clean. - Empirical verification on top of unit tests: live GitHub `/advisories` API calls (parameter semantics, pagination truncation repro, `type=malware` `affects` filtering), a captured dead-registry `npm audit` fixture for the failure-marker path, and standalone heredoc runs for the shell sidecar matrix. - Three adversarial local review rounds (premise incl. live-API ground-truthing, correctness incl. empirical repros, contract+security incl. injection tracing); final round dry apart from two Low findings fixed and re-verified before this PR. Refs #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added scheduled “Security / Advisory Early Warning” scan (every 6 hours) with manual trigger support, producing non-blocking correlation signals. - Added structured `npm audit` provenance sidecars (`npm-audit.provenance.json`) next to raw audit output, capturing timing, versions, and extracted advisory identifiers. - **Bug Fixes** - Improved resilience to malformed/non-JSON audit output and strengthened “fails closed” provenance failure reporting. - **Documentation** - Expanded security documentation to describe early-warning correlation logic and provenance artifacts. - **Tests** - Added/updated coverage for early-warning correlation and audit provenance generation behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Apurv Kumaria <akumaria@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Resolve to the rebase-equivalent tree after #7354 squash-merged: the branch payload is exactly the scheduled workflow and the doc's scheduled-operation/policy sections, applied on top of main's reviewed #7354 wording (review amendments preserved). Closes #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🌿 Preview your docs: https://nvidia-preview-pr-7398.docs.buildwithfern.com/nemoclaw |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
docs/security/advisory-early-warning.md (1)
6-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winFollow the documentation source conventions.
Put each sentence on one source line and rewrite the changed operational prose in direct, active second-person voice.
docs/security/advisory-early-warning.md#L6-L9: un-wrap the status sentence.docs/security/advisory-early-warning.md#L77-L87: un-wrap and directly address the reader in the scheduled-operation description.docs/security/advisory-early-warning.md#L91-L106: un-wrap and directly address the reader in the policy defaults.As per coding guidelines, “Write documentation in active voice, second person, present tense, and direct language. Keep one sentence per line in Markdown and MDX source files.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/security/advisory-early-warning.md` around lines 6 - 9, Update docs/security/advisory-early-warning.md:6-9, :77-87, and :91-106 so each sentence occupies one source line and the changed operational prose uses direct, active second-person, present-tense language; apply the requested wording changes to the status sentence, scheduled-operation description, and policy defaults.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/security/advisory-early-warning.md`:
- Around line 6-9: Update docs/security/advisory-early-warning.md:6-9, :77-87,
and :91-106 so each sentence occupies one source line and the changed
operational prose uses direct, active second-person, present-tense language;
apply the requested wording changes to the status sentence, scheduled-operation
description, and policy defaults.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 784aaca6-ac9e-4d01-875c-1a321ec0e424
📒 Files selected for processing (2)
.github/workflows/advisory-early-warning.yamldocs/security/advisory-early-warning.md
Resolve to the restructured non-operational slice: the NVD reconciliation library, scan-CLI plumbing (--nvd-records, --inventory, cveId), tests, and the reconciliation-semantics + #7276 post-mortem docs, rebased onto main after #7354 squash-merged. The scheduled workflow's NVD step and the policy-defaults doc section move to the sign-off-gated #7398, matching the #7354/#7398 split. Refs #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The operational half of the NVD reconciliation split (#7370 carries the library and CLI plumbing): the scheduled workflow queries NVD for up to 20 signal CVE ids per run (7 s spacing for the unauthenticated rate limit, cap logged when exceeded) and appends the agreement annotation to the rolling-issue lines. NVD being unreachable degrades to an "NVD: unavailable" note and never fails the run — deliberately softer than the fail-loud GitHub advisory fetch, since NVD is supplementary. Annotations extend line text only; the dedupe key is unchanged. Merge order: #7370 must land first — this workflow invokes the scan CLI's --nvd-records flag, which #7370 introduces. Refs #7338 Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/advisory-early-warning.yaml:
- Around line 101-153: Wire NVD metadata through
scripts/lib/advisory-early-warning.mts and
scripts/advisory-early-warning-scan.mts. Add each signal’s cveId (and required
NVD metadata) to the emitted signal shape, accept and parse the workflow’s
--nvd-records argument, and merge matching NVD records into the signals so the
existing workflow worklist and issue-body NVD notes are populated.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 7e49dab4-7fe8-41da-b2e9-2720f2b5826d
📒 Files selected for processing (2)
.github/workflows/advisory-early-warning.yamldocs/security/advisory-early-warning.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/security/advisory-early-warning.md
apurvvkumaria
left a comment
There was a problem hiding this comment.
Blocking pending design alignment.
This PR should not merge until product/security owners complete the design evaluation for the scanning tool, including alignment with the parallel OpenShell work. The scheduled workflow, supported-image scope, ownership model, alert destination, and response expectations need one agreed operating design before NemoClaw commits to this implementation.
Please keep this PR unmerged until that decision is recorded on #7338, then update the implementation and documentation to match the agreed design. This is an operational-design blocker, not a rejection of the underlying early-warning goal.
…-mortem (#7370) ## Summary The **non-operational NVD slice** of #7338: NVD as a supplementary reconciliation source (a pure library plus offline CLI plumbing) and the **#7276 post-mortem** answering the issue's "Questions to answer" — the post-mortem is an explicit #7338 acceptance checkbox. **Restructured 2026-07-24** to match the #7354/#7398 split: this PR was previously stacked on pre-narrowing #7354 and included the scheduled workflow's NVD step. That step (and the policy-defaults doc section) now belongs to the sign-off-gated #7398; this PR is rebased onto main and carries only pieces that define no operational surface — nothing here is scheduled, holds write permissions, or encodes policy. It can merge on normal review. ## Changes - **`scripts/lib/nvd-reconciliation.mts`** (new, pure, dependency-free): parses NVD 2.0 API records (malformed → null, never throws; live-verified against `services.nvd.nist.gov`, including a 358-criteria CPE record and the reserved-id empty envelope) and reconciles each signal: `corroborated` / `nvd-missing` / `nvd-divergent`. Annotations are **informational only** — they carry no action or confidence and cannot alter a signal's dedupe identity (test-asserted), per the issue's requirement that ambiguous NVD/CPE matches never become authoritative npm mappings. - **Signal plumbing**: `AdvisorySignal` gains an optional `cveId` from the GHSA record's `cve_id`; the scan CLI accepts `--nvd-records <file>` (offline attachment — the CLI never performs network requests) and `--inventory <file>` (hermetic test runs). - **Docs**: NVD reconciliation semantics, and the #7276 post-mortem classifying each finding per the acceptance criteria — `fast-uri`: reviewed-mapping delay, directly demonstrated; `@opentelemetry/core`: audit-coverage/execution-order gap; Jaeger: consistent but unproven; `tar`: unproven, evidence not retained. Post-mortem wording states plainly which covering mechanisms are merged and which ride the gated #7398. ## What moved to #7398 The scheduled workflow's NVD reconciliation step (rate-capped fetch, `NVD: unavailable` degradation, rolling-issue annotation) and the proposed policy defaults — operational surface under #7338's owner-sign-off gate. ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `no-docs-needed` - Evidence: `scripts/lib/nvd-reconciliation.mts` and `test/nvd-reconciliation.test.ts` now traverse nested NVD configuration nodes as an internal correctness fix for the documented vulnerable-CPE parsing contract; no user-facing command, flag, configuration, output schema, or workflow changes. - Agent: Codex Desktop <!-- docs-review-head-sha: 389a282 --> <!-- docs-review-agents-blob-sha: 9c9b36d --> ## Testing - `test/nvd-reconciliation.test.ts`: 122 tests green across the three suite files locally; tsc strict clean on both `.mts` entry points; biome, SPDX, test-size-budget, title-style, and source-shape guardrails verified locally. - CLI smoke-verified: `--list-packages` runs against the repo inventory. - Maintainer follow-up: `npx vitest run --project integration test/nvd-reconciliation.test.ts test/advisory-early-warning.test.ts` passes 93/93 with nested NVD configuration coverage. Refs #7338 (the issue closes via #7398 once product/security owners record sign-off) Signed-off-by: Dongni-Yang <dongniy@nvidia.com> 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Advisory early-warning signals can include an optional CVE identifier when available. * Added offline NVD supplementary reconciliation that annotates results with corroborated, nvd-missing, or nvd-divergent. * Added `--inventory <file>` for hermetic inventories and `--nvd-records <file>` to attach pre-fetched NVD reconciliation data without network access. * **Documentation** * Expanded early-warning correlation documentation, including NVD reconciliation behavior and the updated `#7276` post-mortem. * **Bug Fixes** * Malformed inventory entries now fail the run instead of silently shrinking the inventory. * **Tests** * Updated and expanded coverage for CVE extraction, NVD processing, and CLI offline behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Dongni-Yang <dongniy@nvidia.com> Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Apurv Kumaria <akumaria@nvidia.com>
|
Closing per maintainer direction: we are not adding scanning to the NemoClaw repository. This PR will not be merged. |
Summary
The operational slice split out of #7354 per review: the scheduled advisory early-warning workflow and the proposed operating-policy documentation. Draft until product/security owners record sign-off on #7338 — merging this PR closes #7338 (it satisfies the issue's last unchecked acceptance criterion; every other criterion shipped in the merged #7354).
Why this is separate
#7354 review (correctly) held that a scheduled workflow with
issues: writeplus its operating policy defines a supported surface, which #7338's unchecked acceptance criterion reserves for product/security owners: supported historical-image scope, rescan ownership, alert destination, and response expectations. #7354 (now merged) carries only the non-operational pieces (correlation module, local scan CLI, per-audit provenance sidecars). This PR carries the operational pieces and stays draft until the owners' decision lands on #7338.Changes
.github/workflows/advisory-early-warning.yaml: six-hourly + manual dispatch; paginated fetch of reviewed/unreviewed/malware advisories filtered byaffectsbatches of the reviewed inventory; correlation via the scan CLI; signals reported into one rollingsecurity-labeled issue (marker- and Actions-bot-author-matched, control-character-sanitized, deduped on advisory id + package). Non-blocking by design;permissions: contents: read, issues: write. Now also reconciles signals with NVD (folded in from feat(security): add the NVD reconciliation library and the #7276 post-mortem #7370 per the restructure): up to 20 CVE ids per run, 7 s spacing for the unauthenticated rate limit, cap logged when exceeded; NVD outages degrade to anNVD: unavailableannotation and never fail the run; annotations extend rolling-issue line text only, the dedupe key is unchanged.docs/security/advisory-early-warning.md: adds the "Scheduled operation" section (including the NVD reconciliation cadence/degradation wording) and the "Proposed policy defaults (pending maintainer confirmation)" section. Wording flips from proposed to accepted once Detect public advisories before reviewed ecosystem mappings reach scanners #7338 sign-off is recorded.Rebased onto main after #7354 merged; the NVD workflow step was folded in from #7370 when that PR was narrowed to its non-operational slice — keeping all operational surface in this one sign-off-gated PR. With this fold-in, the merged workflow satisfies #7338's desired behavior of using NVD as a supplementary reconciliation source.
Merge checklist
--nvd-recordsflag, which feat(security): add the NVD reconciliation library and the #7276 post-mortem #7370 introduces; merging this PR before feat(security): add the NVD reconciliation library and the #7276 post-mortem #7370 makes the six-hourly run fail on an unknown flagCloses #7338
Signed-off-by: Dongni-Yang dongniy@nvidia.com
🤖 Generated with Claude Code
Summary by CodeRabbit