Agents Playbook
Pillars/Security

Vulnerability Management Pattern

How to keep the system patched without bottlenecking on a person watching CVE feeds.

Vulnerability Management Pattern

How to keep the system patched without bottlenecking on a person watching CVE feeds.

TL;DR (human)

Three legs: an SBOM (you know what you ship), automated CVE triage (Dependabot / Renovate / Snyk feeding into your tracker), and signed releases (consumers can verify what you shipped). Patch SLA varies by severity. Supply chain attacks treated as first-class threats — signed deps, lock files committed, install scripts inspected.

For agents

Three legs

LegWhat it answersHow
SBOM (Software Bill of Materials)What did we ship?Generate per release; store + sign
Triage pipelineAre any of those things vulnerable?Automated scanners + watchlists
Signed releasesDid the consumer get what we shipped?Sigstore / cosign / GPG attestation

Without all three, supply-chain attacks become invisible.

SBOM

Generated at build time. Standard formats: CycloneDX, SPDX.

Contents:

  • Every direct and transitive dependency.
  • Version pinned (lock-file derived).
  • Hash / checksum.
  • License.
  • Source repo / package URL.

The SBOM is committed at release tag (or attached as an artifact). Customers / auditors / regulators can request it.

Tooling: npm sbom, cdxgen, syft.

CVE triage

Continuous scan against the SBOM:

  • Dependabot / Renovate: open PRs for patch / minor / major bumps. Per-package config.
  • Snyk / GitHub Advanced Security / OSV-Scanner: scan + alert on CVEs.
  • Trivy / Grype: scan container images.

Triage flow:

  1. Scanner posts to a tracker (issue, slack channel, dashboard).
  2. Severity classified: critical / high / medium / low (CVSS-based, with project-specific adjustments).
  3. Owner assigned (per package, per service).
  4. Patch SLA enforced:
    • Critical (RCE in your trust boundary): 24h.
    • High: 7 days.
    • Medium: 30 days.
    • Low: next release cycle.
  5. Verification: after patch, re-scan; CVE no longer fires.

A CVE past its SLA is a tracked overdue item; escalation path defined.

Severity adjustments

CVSS does not know your context. Adjust based on:

  • Reachability: is the vulnerable code path actually called? An unreachable CVE is lower priority.
  • Exposure: is the vulnerable surface internet-facing or behind auth?
  • Mitigation in place: WAF / firewall / sandbox / input validation that closes the vector.

Document adjustments in the triage record. "CVE-XXX-XXXX downgraded from High to Medium because <reason>" — auditable.

Patch cadence (proactive)

Beyond reactive CVE response, schedule:

  • Weekly: patch + minor bumps via Renovate / Dependabot auto-merge for low-risk packages.
  • Monthly: review pending major bumps; pick low-hanging migrations.
  • Quarterly: review packages with no upstream releases in 12+ months (abandoned dependency risk).

Lagging patches is how known-vulnerable code persists.

Lock files

Commit the lock file (pnpm-lock.yaml, package-lock.json, Cargo.lock, etc.).

  • The lock file IS the deterministic dependency tree.
  • CI runs --frozen-lockfile: install must match the lock; mismatch fails.
  • Lock file updates are diff-visible in PR; reviewers see exactly which transitives moved.

Install-script discipline

NPM packages can run scripts on install. Audit:

  • pnpm config set ignore-scripts true for default-deny; explicit allow per package.
  • Or: review install-script content in CI; flag novel scripts.
  • Be specifically wary of: post-install scripts that touch unexpected paths, fetch external URLs, modify shell config.

Signed releases

Three signatures matter:

  1. Source release signature: the release tag / commit is signed (git tag -s or sigstore gitsign).
  2. Artifact signature: built binaries / packages are signed (cosign sign, npm publish --provenance).
  3. Attestation: the build process itself is attested (which CI built it, which commit, which steps).

Consumers verify:

# Verify the published artefact came from the expected source + build pipeline
cosign verify <artefact>

This converts "we trust the registry" into "we verify the chain".

Supply-chain threats

The big ones:

ThreatDefense
Typosquatting (reqeusts vs requests)Allowlist; explicit dep review on PRs adding new deps
Account hijack of maintainerSigned releases; freeze versions during incident
Malicious update from compromised maintainerPatch-lag-by-days policy (don't auto-update within 24-72h of release); package score tools
Build-system compromiseReproducible builds; verify against attestation
Install-script attackDisable install scripts; explicit allow

Vulnerability disclosure (inbound)

A SECURITY.md at repo root tells reporters:

  • Where to report (security@\<your-domain\> is standard).
  • What to include.
  • Response SLA.
  • Coordinated disclosure terms.
  • (Optional) bug bounty program.

Process:

  1. Acknowledge within 24h.
  2. Triage within 72h.
  3. Per severity:
    • Critical: emergency patch + coordinated disclosure within 7 days.
    • High: patch within 30 days.
    • Medium / low: next release.
  4. Public advisory after fix lands.

Dependency policy

Documented criteria for adding a new dependency:

  • Maturity: > 1 year of releases; recent commits.
  • Maintenance: active issue triage; not single-maintainer in a critical role.
  • Trust: well-known author / org, or a thorough read of the source.
  • Necessity: the functionality cannot be reasonably inlined.
  • License: compatible with the project license.
  • Size: a 2-line problem solved by a 200KB package is overhead.

Each new dep is an attack surface and a maintenance burden. Add deliberately.

Common failure modes

  • No SBOM. Vulnerability scan tells you which CVE exists; you cannot tell if you ship it. → Generate SBOM per release.
  • Dependabot PRs auto-merged with no test guard. Compromised dep gets in. → Tests must pass; signed-by-known-maintainer check.
  • Critical CVE waiting weeks for triage. No SLA; no escalation. → SLAs documented; escalation path.
  • Lock file not committed. Different dev / CI sees different versions; CVE scan is unreliable. → Commit; CI uses frozen install.
  • Install scripts enabled by default. One malicious dep runs arbitrary code on every install. → Disable by default.
  • No signature verification on download. Consumer doesn't verify; spoofed artefact accepted. → Verify in CI / production install.

Tooling stack (typical)

ConcernTool
SBOM generationsyft, cdxgen, npm sbom
CVE scan (deps)osv-scanner, Snyk, Dependabot, Renovate
CVE scan (images)trivy, grype
Signingsigstore (cosign, gitsign), gpg
ProvenanceSLSA framework, GitHub Actions native provenance
Bounty / disclosureHackerOne, Bugcrowd, security@<domain> mailbox

See also