Files
tech-log-backend/.github/dependency-vulnerability-policy.md
T

5.0 KiB

Dependency Vulnerability Policy

This policy is enforced by dependency-vulnerability.yml, dependency-review-config.yml, ../.trivyignore.yaml, verifyTrivyignore, CODEOWNERS, and ../renovate.json.

Execution and platform boundary

Canonical workflow files live under .github/workflows. The current origin is Gitea and server-side Actions is externally disabled; committing these controls does not enable or prove remote execution. An administrator must enable Actions, provide compatible runners, configure required checks, and require code-owner review separately.

External actions execute only by verified full commit SHA; inline comments retain the immutable release tag for review. GitHub dependency review publishes check output but never writes a PR summary comment, preserving the workflow-wide contents: read permission.

GitHub dependency review and dependency submission depend on GitHub.com APIs. They are guarded by github.server_url == 'https://github.com' and intentionally skip on Gitea. trivy-fs is the platform-neutral release-blocking snapshot and runs for pull requests, main pushes, daily schedule, and manual dispatch.

The later supply-chain slice owns image builds/scans, SBOM, signing, provenance, tag release, and retention. This policy does not claim those absent jobs.

Severity and response

Severity CI posture Target remediation
KEV / Critical block 7 days or the CISA due date, whichever is sooner
High block 30 days
Medium advisory 90 days
Low advisory best effort

High/Critical is the template's release threshold. The exact threshold and remediation targets are team policy rather than an external mandate and should be reviewed when the template is adopted. GitHub dependency review applies the same High threshold to newly introduced runtime dependencies.

The Trivy JSON snapshot is also compared with the CISA Known Exploited Vulnerabilities catalog. Any intersection blocks regardless of Trivy severity. Before intersection, CI requires nonblank catalog metadata, a positive integral declared count, a non-empty vulnerability array whose length matches that count, and unique CVE-pattern cveID values. A missing, empty, malformed, count-inconsistent, duplicate, or unreachable KEV feed fails closed; configure the KEV_FEED_URL repository variable to an approved internal mirror when direct CISA access is unavailable.

Candidate extraction also validates Trivy's JSON first: the top level must be an object with a non-empty Results array; each result is an object whose Vulnerabilities value is null or an array; and every listed vulnerability has a nonblank string VulnerabilityID. Invalid scanner output fails closed instead of becoming an empty candidate set.

Scanner and network requirements

Trivy scans the committed filesystem and Gradle lockfiles. High/Critical findings exit non-zero; Medium/Low findings are reported with exit zero. Scanner database or tool-download failures remain failures rather than silently producing an empty result.

Runners need HTTPS egress to:

  • the configured Trivy binary source (GitHub Releases by default);
  • Trivy vulnerability databases (the scanner defaults, commonly OCI registries);
  • jq releases, unless JQ_DOWNLOAD_BASE_URL points to an internal mirror;
  • the CISA KEV feed, unless KEV_FEED_URL points to an internal mirror;
  • GitHub action sources when the forge does not mirror actions.

Closed networks must mirror the pinned Trivy/jq artifacts and checksums, set TRIVY_DOWNLOAD_BASE_URL and JQ_DOWNLOAD_BASE_URL, configure Trivy's documented database mirror environment, and set KEV_FEED_URL. Mirror availability and freshness are operational dependencies; stale mirrors can delay detection.

Suppression governance

The only suppression source is repository-root .trivyignore.yaml. Every Trivy scan passes it explicitly with --ignorefile .trivyignore.yaml. Each future entry must contain an identifier, a non-empty rationale, and a future expiry no more than 90 days away. verifyTrivyignore validates the shape and expiry; CODEOWNERS plus branch protection controls who may approve the change. Neither control substitutes for the other.

Do not use an ad-hoc ignore file or an inline scanner bypass. An expired suppression is removed or renewed with fresh owner review and current evidence.

Dependency update policy

Renovate is the checked-in security-update bot configuration. Patch/pin/digest security updates may auto-merge only after every configured required check succeeds; minor and major updates require human review. Dependency declarations and all 19 gradle.lockfile files must move together, and verifyDependencyLocks remains release-blocking.

Bot alerts are not a transitive-dependency backstop on every forge. Use a Gradle constraint or resolution rule for a vulnerable transitive dependency, refresh locks deliberately, and retain the full-snapshot Trivy scan.