Skip expired SBOM scans when reusing cached scan results
What does this MR do and why?
Security::VulnerabilityScanning::SbomScanResultCachingService#find_cached_scan picked the newest finished scan for a digest without applying SbomScan.not_expired, so the EXPIRED_AGE (2 days) bound on cache reuse was only enforced by DestroyExpiredSbomScansWorker, which runs once a day. A scan therefore stayed reusable for up to a day past the limit, and longer whenever the reaper fell behind or stopped early on an empty batch.
This MR applies the existing, previously unused not_expired scope in the read path so an expired scan is treated as a cache miss regardless of when the cleanup last ran. The advisory-freshness check is unchanged.
References
- Resolves #616888 (closed)
Differences
Before: A finished scan created more than EXPIRED_AGE ago is still returned by find_cached_scan until the daily worker deletes it, and its result is copied to the new build.
After: The lookup excludes scans older than EXPIRED_AGE, so the service returns status: :not_found and the build runs a fresh scan.
Query plan
Before/after SQL and query plans for the added created_at predicate: !255112 (comment 3837222883)
The query uses the same index as before, index_sbom_vulnerability_scans_on_project_id_and_sbom_digest, and the new predicate lands as an additional in-node filter on the rows that index already returns, rather than changing the access path. No index change needed.
How to set up and validate locally
-
Run the service spec:
bundle exec rspec ee/spec/services/security/vulnerability_scanning/sbom_scan_result_caching_service_spec.rb -
The new context "when the only matching sbom_scan is older than EXPIRED_AGE" fails on
master(a copy is created) and passes with this MR.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.