Add configurable vulnerability archive retention period

What does this MR do and why?

Allows administrators to configure how long archived vulnerabilities are retained before they are deleted. The retention period can be set between 12 and 84 months (1 to 7 years) via Admin Area > Settings > Security and compliance > Vulnerability archival.

Previously the retention period was hardcoded at 36 months (3 years). It now defaults to 36 months and is configurable, so customers with longer audit requirements (for example, a 5-year retention obligation) can extend it.

Closes #589550 (closed)

Implementation notes

This follows the pattern established in !222998 (merged) (configurable security scan retention), with one key difference worth reviewer attention:

  • Security scan retention is read in runtime query scopes (Security::Scan.stale_after).
  • Vulnerability archive retention is consumed by the partitioning strategy (partitioned_by ... retain_for:), which the partition manager evaluates at boot-time partition sync.

To make a value read at class-load time configurable, retain_for now accepts a lazily-evaluated callable. Gitlab::Database::Partitioning::Time::BaseStrategy#retain_for resolves the callable on each call, so existing static retain_for: declarations are unaffected. The archive models pass a lambda that reads the setting with a default fallback:

partitioned_by :date, strategy: :monthly, retain_for: -> { retention_period }

def self.retention_period
  months = Gitlab::CurrentSettings.vulnerability_archive_retention_months || DEFAULT_RETENTION_MONTHS
  months.months
end

The || DEFAULT_RETENTION_MONTHS fallback is deliberate: during rake tasks or pending migrations, Gitlab::CurrentSettings returns FakeApplicationSettings which resolves the jsonb sub-attribute to nil. Without the guard, partition sync would silently fail for these tables.

Settings

The setting reuses the existing security_and_compliance_settings jsonb column, so no database migration is required.

Setting Default Range
vulnerability_archive_retention_months 36 (3 years) 12–84 months

For reviewer attention

  • Gating: The admin UI block is gated on License.feature_available?(:security_dashboard) (Ultimate). Vulnerability archival itself is additionally gated by the per-namespace vulnerability_archival feature flag, so the control is visible even on instances where archival is not yet active (the value is simply stored). I chose the instance-level license gate as a reasonable proxy, but happy to change this if reviewers prefer.
  • Minimum value: The 12-month minimum is the retention period for the archive record (measured from its creation month), independent of the 12-month archival trigger (based on a vulnerability's last update). A 12-month retention does not delete freshly created archives.

How to set up and validate locally

  1. Start GDK with an Ultimate license.
  2. Navigate to Admin Area > Settings > Security and compliance.
  3. Expand Vulnerability archival.
  4. Set the retention period (12–84 months) and save.
  5. Verify the value persists after reload, and that values outside the range are rejected with "must be between 12 and 84 months".

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist.

Merge request reports

Loading
Loading