Operator procedures for automated dependency vulnerability scanning, alerting, and blue-green / canary deployment gates.
┌──────────────────────────────────────────────────────────────────┐
│ CI/CD Pipeline (.github/workflows/dependency-scan.yml) │
│ │
│ pnpm audit ──► npm audit ──► OSV-Scanner ──► SBOM gen │
│ │ │ │ │ │
│ └──────────────┴───────────────┴───────────────┘ │
│ │ │
│ ▼ │
│ scripts/check-deployment-gate.mjs │
│ ──► blocks deploy if critical vulnerabilities found │
│ ──► warns on high, passes on medium/low │
│ │ │
│ ▼ │
│ Runtime Dashboard (/dashboard/vulnerability) │
│ ──► useDependencyScan hook │
│ ──► POST /api/telemetry/vulnerability │
│ ──► DependencyScanner service (src/services/dependencyScan.ts)│
└──────────────────────────────────────────────────────────────────┘
| Path | Role |
|---|---|
src/lib/vulnerability/types.ts |
Shared types, severity levels, performance budgets |
src/lib/vulnerability/scanner.ts |
Pure functions: parse lockfiles, build findings, canary gating |
src/lib/vulnerability/advisorySource.ts |
npm audit + OSV API adapters |
src/lib/vulnerability/redact.ts |
Redact sensitive package names from telemetry |
src/services/dependencyScan.ts |
Service orchestrator, registry, history, singleton |
src/hooks/useDependencyScan.ts |
React subscription + periodic scanning |
src/utils/vulnerabilityTelemetry.ts |
Telemetry reporter with offline queue fallback |
src/app/api/telemetry/vulnerability/route.ts |
Monitoring ingest endpoint |
src/components/dashboard/VulnerabilityDashboard.tsx |
Operator dashboard |
src/app/dashboard/vulnerability/page.tsx |
Dashboard route |
.github/workflows/dependency-scan.yml |
CI/CD pipeline |
scripts/check-deployment-gate.mjs |
Deployment gate decision |
| Signal | Source | Alert when |
|---|---|---|
| Critical vulnerabilities | pnpm audit / npm audit / OSV |
criticalCount > 0 |
| High vulnerability rate | CI gate output | highRate > 5% in canary |
| Scan latency | metrics.durationMs / withinBudget |
P99 >= 100ms |
| Canary hold | checkCanaryGate() reason |
promote === false after min samples |
Open /dashboard/vulnerability to inspect:
- last scan status and duration,
- per-finding table (package, version, severity, advisory ID, fix available),
- severity breakdown (critical / high / medium / low),
- canary promote / hold recommendation,
- total dependencies scanned and advisory source version.
The telemetry route logs at different levels:
console.errorfor critical vulnerabilities,console.warnfor high-severity findings,console.infootherwise.
Wire log drains (CloudWatch, Datadog, etc.) to these messages for paging.
- Open
/dashboard/vulnerabilityand click Run scan. - For each critical finding:
- Determine if the vulnerable package is in the direct dependency tree or transitive.
- Check
fixedInfield for the patched version. - Update
package.jsondependencies or add a resolution override. - Run
pnpm update <package>to apply the fix.
- For high findings, schedule a fix within the next change window.
- Confirm
withinBudgetis true; if not, reduce advisory source work.
- CI runs
dependency-scan.ymlon every push tomainandrelease/*. - The
check-deployment-gate.mjsscript reads aggregated scan results. - If
criticalCount > 0, the gate blocks the build (exit code 1). - Operators must resolve all critical CVEs before the inactive slot can be promoted.
- After resolution, redeploy to the inactive slot; the gate re-runs automatically.
- Flip the edge router / CDN to the new slot (instant cutover).
- Keep the previous slot warm for rapid rollback.
- CI sets
DEPLOY_CHANNEL=canaryfor PR builds andrelease/*branches. - Each scan produces a
ScanReportrecorded in the scanner's history ring. - Promotion requires:
- Critical vulnerability rate = 0,
- High vulnerability rate <= 5%,
- Minimum 3 samples collected.
- If
promote === false, halt expansion, fix vulnerabilities, and re-sample. - On success, promote canary -> green -> stable.
- Point traffic to the previous blue/green slot.
- Re-run scan on the serving slot; confirm no critical findings.
- File an incident note with the vulnerability report from the failed canary.
- No plaintext package names from private registries in telemetry (expect
[REDACTED]). - All findings redacted before telemetry POST (
redactReport()). - npm audit and OSV API calls are read-only; no credentials transmitted.
- SBOM generation is scoped to production dependencies only.
- Advisory sources are pinned to specific versions in CI.
- New package sources register a
PackageSourcein the scanner.
- Critical path:
scanSource()/scanAll()(sync parse + advisory fetch). - Budget:
PERFORMANCE_BUDGET_MS = 100. - Each report includes
metrics.durationMsandmetrics.withinBudget. - Advisory fetches are async and may exceed budget on first scan; subsequent scans use cached results to stay within budget.
# Core library tests
npx tsx src/lib/vulnerability/__tests__/dependencyScan.test.ts
# Service layer tests
npx tsx src/services/__tests__/dependencyScan.test.ts