Add skillguard column to security_inventory_filters
What does this MR do and why?
Registers skillguard as a platform analyzer type for SkillGuard, the AI agent skill security scanner, and adds the database column that registration requires.
This MR originally carried only the migration. !263331 (merged) was reviewed separately and merged into this branch, so the two now ship together.
- 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. - First MR of a Phase 1 stack. !263332 (merged) enables SkillGuard through a scan profile and now targets this branch; !263334 (merged) adds the UI on top of that.
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
- Database: one column,
security_inventory_filters.skillguard,smallint DEFAULT 0 NOT NULL.Security::InventoryFilterdeclares anenumand avalidates ... presenceper key ofEnums::Security.extended_analyzer_types, so the column has to exist before the enum entry does, or the model raises at boot and every project factory fails. Same shape as thebusiness_logiccolumn indb/migrate/20260923170038_add_business_logic_to_security_inventory_filters.rb. The table istable_size: small, soadd_columnwith a constant default is metadata-only. - Security / platform: the flag gates and the Ultimate entry in
GitlabSubscriptions::Features.
Design decisions
- Flag type is
wip, notexperiment.experimentis for A/B/n tests driven through theexperiment()API, andlib/feature/shared.rbmarks itcan_be_default_enabled: false. This flag is a plainFeature.enabled?kill-switch hiding unfinished multi-MR work, which is whatwipis for. This diverges frombl_security_analyzer, which isexperiment; thanks to @gkatz1 for catching it. ANALYZER_TYPESuses 16 andSCAN_PROFILES_TYPESuses 6, the next free integers (10..14 are reserved, 15 isbusiness_logic).skillguardjoinsFLOW_BACKED_SCAN_TYPESbecause it runs as a Duo flow rather than an injected CI job. That keeps it out ofScanProfile.not_flow_backed, so no CI job is ever injected for it.- The security configuration card's
help_pathpoints at the generic application security overview for now. !263332 (merged) repoints it at the SkillGuard section of the profiles page. A dedicated SkillGuard documentation page is tracked under Documentation follow-up in https://gitlab.com/gitlab-org/gitlab/-/work_items/634364.
References
- Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/634364
- Epic: https://gitlab.com/groups/gitlab-org/-/epics/22680
- Merged into this branch: !263331 (merged)
- Mirrors the BLSA equivalents: !257091 (merged) (analyzer type) and its
business_logiccolumn migration
Screenshots or screen recordings
No UI changes. The SkillGuard security configuration card only renders with the flag on, and the card UI arrives later in the stack.
| Before | After |
|---|---|
Database review
Migration output
main: == 20261019142349 AddSkillguardToSecurityInventoryFilters: migrating ==========
main: -- add_column(:security_inventory_filters, :skillguard, :smallint, {default: 0, null: false})
main: -> 0.0376s
main: == 20261019142349 AddSkillguardToSecurityInventoryFilters: migrated (0.0433s) =Reversible: add_column inside change, so down is generated and drops the column.
How to set up and validate locally
bundle exec rails db:migrate, then confirm the column exists:Security::InventoryFilter.column_names.include?('skillguard') # => true- Enable the flag for a top-level group:
Feature.enable(:skillguard_analyzer, Group.find_by_full_path('your-group')) - Visit a project's Secure > Security configuration page in that group and confirm the SkillGuard card appears. Disable the flag and confirm it disappears.
- In GraphQL, run
securityScanProfileCreatewithscanType: 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.