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
endThe || 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-namespacevulnerability_archivalfeature 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
- Start GDK with an Ultimate license.
- Navigate to Admin Area > Settings > Security and compliance.
- Expand Vulnerability archival.
- Set the retention period (12–84 months) and save.
- 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.