Register skillguard as a platform analyzer type

What does this MR do and why?

Registers skillguard as a platform analyzer type for SkillGuard, the AI agent skill security scanner.

  • Stacked on !263374 (merged), which adds the security_inventory_filters.skillguard column this type requires. Review and merge that one first; this MR targets its branch.
  • No scan runs because of this MR. It only makes the type known to the platform. There is no foundational flow and no allowed trigger types yet, so creating a scan profile still fails validation.
  • Customer-visible parts are behind a new flag, skillguard_analyzer (wip, off by default). The actor is the top-level group everywhere.
  • Second MR of a four-part Phase 1 stack. Part 3 enables SkillGuard through a scan profile, part 4 adds the UI.

What changes for users

Surface Flag off Flag on
Security Configuration page No SkillGuard card SkillGuard card shown
securityScanProfileCreate with SKILLGUARD Rejected Passes the flag check, then fails validation: no trigger types are allowed yet
Six GraphQL enums SKILLGUARD present Same

The ungated enum values follow the business_logic precedent: the frontend uses hard-coded analyzer lists, so nothing renders them.

Review focus

  • Security / platform: the flag gates and the Ultimate entry in GitlabSubscriptions::Features.
  • No database changes here. Security::InventoryFilter declares an enum per analyzer type, so adding skillguard to ANALYZER_TYPES raises at boot without its column. That column ships ahead of this MR in !263374 (merged), which is why this one targets that branch rather than master.

Design decisions

  • Flag type is wip, not experiment. experiment is for A/B/n tests driven through the experiment() API, and lib/feature/shared.rb marks it can_be_default_enabled: false. This flag is a plain Feature.enabled? kill-switch hiding unfinished multi-MR work, which is what wip is for. This diverges from bl_security_analyzer, which is experiment; thanks to @gkatz1 for catching it.

  • ANALYZER_TYPES uses 16 and SCAN_PROFILES_TYPES uses 6, the next free integers (10..14 are reserved, 15 is business_logic).

  • skillguard joins FLOW_BACKED_SCAN_TYPES because it runs as a Duo flow rather than an injected CI job. That keeps it out of ScanProfile.not_flow_backed, so no CI job is ever injected for it.

References

Screenshots or screen recordings

No UI changes. The SkillGuard security configuration card only renders with the flag on, and the card UI arrives with part 3.

Before After

How to set up and validate locally

  1. Enable the flag for a top-level group:
    Feature.enable(:skillguard_analyzer, Group.find_by_full_path('your-group'))
  2. Visit a project's Secure > Security configuration page in that group and confirm the SkillGuard card appears. Disable the flag and confirm it disappears.
  3. In GraphQL, run securityScanProfileCreate with scanType: SKILLGUARD. With the flag on it should fail trigger validation; with the flag off it should return a top-level access error.

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.

Edited by rossfuhrman

Merge request reports

Loading
Loading