Map sast_iac scanner to sast in approval policy rules

What does this MR do and why?

Approval policies that list sast_iac under a scan_finding rule's scanners never get an approval rule. This MR maps sast_iac to sast when the rule is read, so those policies work again.

Why they break today

  1. sast_iac is a scan execution action, not a report type. Infrastructure as Code (IaC) scanning reports its findings as sast.
  2. The policy schema still saves it: the plain-string scanners form accepts any string.
  3. ApprovalProjectRule only accepts security report types in scanners, so the whole list fails validation and no approval rule is created.
  4. ApprovalRules::CreateService logs that failure at debug level only. The policy produces no approval rule, violation or bot comment, and fallback_behavior: fail: closed has nothing to fail closed on.

The change

  • Security::ScanResultPolicies::Rule#build_scanner_config maps sast_iac to sast. Everything that reads the rule's scanners goes through it: ApprovalRuleParamsBuilder (creating and updating approval rules) and Security::ApprovalPolicySource (per-scanner overrides).
  • The mapping is applied to both scanner forms. Only the plain-string form can contain sast_iac today, because the object form's type enum rejects it on save. Mapping both keeps the two branches consistent.
  • ApprovalRuleParamsBuilder removes duplicates, since [sast, sast_iac] becomes [sast, sast].
  • The non-override branch no longer reads type from a hash. Hashes always take the override branch, so that code could not run.

On GitLab.com, 15 enabled approval policies across 13 policy configurations list sast_iac, linked to 770 projects. These are aggregate counts from a read-only production console query over approval_policy_rules whose content->'scanners' contains sast_iac.

No feature flag: the change only matters when approval rules are created (on a new link or a resync), and it creates the rules those policies already declare.

Reviewable LOC: 14 (plus 28 in tests)

References

  • Resolves #637971
  • Related: #557737 (the update-only sync path, which is why already-affected policies need a resync after this deploys)

Screenshots or screen recordings

Not applicable, backend only.

How to set up and validate locally

  1. Create a group-level approval policy with a scan_finding rule whose scanners are [sast, sast_iac] and a require_approval action.
  2. On master, open a merge request to the default branch of a project in scope. The policy's approval rule is missing, and project.approval_rules.where.not(approval_policy_rule_id: nil) is empty in the Rails console.
  3. On this branch, run resyncSecurityPolicies for the group (relationship: DIRECT). The approval rule is created with scanners: ["sast"] and appears on the merge request.

Specs: ee/spec/services/security/scan_result_policies/approval_rules/create_service_spec.rb (fails on master with expected `project.approval_rules.count` to have changed by 1, but was changed by 0) and ee/spec/lib/security/scan_result_policies/rule_spec.rb.

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.

Context for LLM agents
  • Rejected: adding sast_iac to ApprovalProjectRule::SUPPORTED_SCANNERS. That list doubles as the set of security report types used to filter findings and pipeline reports, and no finding has report type sast_iac, so the rule would never match anything.
  • Rejected: adding an enum to the schema's plain-string scanners form. Policies already persisted with sast_iac would become invalid YAML and stop syncing entirely, which is worse than the current state.
  • Rejected: dropping unknown scanners. A rule listing only sast_iac would end up with an empty list, which scanners_with_default_fallback treats as "all scanners" and so would widen the rule.
  • Invariant: scanner types coming out of Rule#scanner_configurations must be security report types, because ApprovalProjectRule validation and FindingsFinder#by_report_types both depend on that.

Owed elsewhere

  • Policies already affected won't recover on deploy. Nothing re-runs the create path, and a later edit takes the update-only path tracked in #557737. Their projects need resyncSecurityPolicies (DIRECT on the policy's group or project).
  • The approval-rule creation failure is logged at debug only, which is why this stayed invisible. Raising it is a separate change. Follow-up: #637972
Edited by Alan (Maciej) Paruszewski

Merge request reports

Loading
Loading