Expose triage and remediation profile configuration input types
What does this MR do and why?
Adds the GraphQL input types for create and update a triage_and_remediation scan profile with a configuration per trigger.
SecurityScanProfileConfigurationInput is a one_of keyed by scan type, but triage_and_remediation selects its JSON schema by trigger type, so its new member is itself a one_of: SecurityScanProfileTriageAndRemediationConfigurationInput, with one argument per trigger type. Mutations::Security::ScanProfiles::TriggerArguments unwraps both levels and rejects a configuration whose member does not name the trigger it is attached to.
| Argument | Input type | Arguments |
|---|---|---|
sastFalsePositive |
SecurityScanProfileSastFalsePositiveInput |
severityLevel, cweClasses, runMode |
sastVulnerabilityResolution |
SecurityScanProfileSastVulnerabilityResolutionInput |
severityLevel, cweClasses, runMode, openMergeRequestsLimit, falsePositiveConfidence |
secretDetectionFalsePositive |
SecurityScanProfileSecretDetectionFalsePositiveInput |
runMode |
vulnerabilityEnrichment |
SecurityScanProfileVulnerabilityEnrichmentInput |
severityLevel, runMode |
sbomIngested |
existing SecurityScanProfileDependencyScanningPostProcessingConfigurationInput |
reused as-is |
Validations:
SecurityScanProfileRunModeandSecurityScanProfileFalsePositiveConfidenceare enums- New input-only
CweIdentifierscalar enforcing^CWE-\d{1,5}$, and a 50-item cap oncweClasses.
Mutations::Security::ScanProfiles::Update also gained the triage_and_remediation_profile check that Create already had - without it, a profile created while the flag was on stayed editable after the flag was turned off.
All new arguments and enum values are tagged experiment: { milestone: '19.4' }.
Changelog: added
EE: true
Related issue
[Backend] Add input types for new configurations (#627239 - closed) • Gal Katz
How to set up and validate locally
-
Enable the flags in the Rails console:
Feature.enable(:triage_and_remediation_profile) -
Create a profile with a configuration per trigger for root group
g:mutation { securityScanProfileCreate( input: { namespaceId: "gid://gitlab/Group/<g.id>" scanType: TRIAGE_AND_REMEDIATION name: "Triage via GraphQL" description: "Created through the mutation" triggers: [ { triggerType: SAST_VULNERABILITY_RESOLUTION configuration: { triageAndRemediation: { sastVulnerabilityResolution: { severityLevel: CRITICAL runMode: MANUAL cweClasses: ["CWE-89"] openMergeRequestsLimit: 3 falsePositiveConfidence: LIKELY_NOT_FALSE_POSITIVE } } } } { triggerType: VULNERABILITY_ENRICHMENT configuration: { triageAndRemediation: { vulnerabilityEnrichment: { severityLevel: INFO } } } } { triggerType: SBOM_INGESTED configuration: { triageAndRemediation: { sbomIngested: { autoRemediation: { cooldown: 3, upgradePolicy: MAJOR } } } } } ] } ) { errors scanProfile { id name triggers } } } -
Confirm
errorsis empty and each trigger member landed on its own trigger, with values equal to the Standard defaults stripped out:profile = Security::ScanProfile.find_by(name: 'Triage via GraphQL') profile.scan_profile_triggers.each do |trigger| puts "#{trigger.trigger_type}: #{trigger.configuration&.configuration.inspect}" endsast_vulnerability_resolution: {"severity_level"=>"critical", "run_mode"=>"manual", "cwe_classes"=>["CWE-89"], "open_merge_requests_limit"=>3, "false_positive_confidence"=>"likely_not_false_positive"} vulnerability_enrichment: {"severity_level"=>"info"} sbom_ingested: {"auto_remediation"=>{"cooldown"=>3, "upgrade_policy"=>"major"}} -
Update the profile: Replacing a trigger's configuration overwrites it; sending a trigger with no configuration removes its stored configuration; omitting a trigger removes the trigger:
mutation { securityScanProfileUpdate( input: { id: "gid://gitlab/Security::ScanProfile/<ID>" triggers: [ { triggerType: SAST_VULNERABILITY_RESOLUTION configuration: { triageAndRemediation: { sastVulnerabilityResolution: { severityLevel: LOW falsePositiveConfidence: LIKELY_FALSE_POSITIVE } } } } { triggerType: VULNERABILITY_ENRICHMENT } ] } ) { errors scanProfile { triggers } } }Re-run the console snippet from the previous step.
sast_vulnerability_resolutionis now{"severity_level"=>"low", "false_positive_confidence"=>"likely_false_positive"},vulnerability_enrichmentisnil, andsbom_ingestedis gone. -
Confirm the rejections, each by changing the create mutation:
Change Expected error Pair triggerType: SBOM_INGESTEDwith asastFalsePositivememberConfiguration 'sast_false_positive' does not match trigger type 'sbom_ingested'Use a secretDetectionmember instead oftriageAndRemediationConfiguration 'secret_detection' does not match scan type 'triage_and_remediation'cweClasses: ["sql-injection"]"sql-injection" is not a valid CWE identifier51 entries in cweClassescweClasses is too long (maximum is 50) -
With
Feature.disable(:triage_and_remediation_profile), re-running the update mutation returns a top-level resource-not-available error instead of applying the change.
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.