Draft: Add logical operator to policy_scope to support OR and AND
What does this MR do and why?
This MR adds support for logical operators (AND and OR) in security policy scopes to address a bug where policy scope conditions were always combined using AND logic, preventing flexible policy application.
Problem
Previously, when a security policy had both projects and groups specified in the policy_scope, the system would only apply the policy if BOTH conditions were met (implicit AND logic):
- The project was explicitly listed in the
projects.includingarray, AND - The project belonged to a group listed in the
groups.includingarray
This caused policies to not be applied to projects that were explicitly included in the projects list but whose parent groups weren't listed in the groups scope, which was counterintuitive and didn't match user expectations.
Solution
This MR introduces an optional operator field in the policy_scope configuration that allows users to specify how multiple scope conditions should be combined:
-
AND(default): All specified conditions must be met (maintains backward compatibility) -
OR: At least one condition must be met (new functionality)
Changes Made
-
JSON Schema Update: Added
operatorfield to the security orchestration policy JSON schema with enum values["AND", "OR"] -
Policy Scope Checker Logic:
- Refactored
scope_applicable?method to use Ruby'sinjectwith dynamic operators (:&for AND,:|for OR) - Added
or_operator?helper method to check if OR logic should be used - Added
default_value_for_operatormethod to return appropriate default values when scope conditions are empty - Updated individual scope check methods to return operator-appropriate defaults when no conditions are specified
- Refactored
-
Comprehensive Test Coverage: Added extensive test cases covering:
- AND operator behavior (existing and new scenarios)
- OR operator behavior with various combinations
- Edge cases with mixed conditions
- Default behavior when operator is not specified
Example Usage
policy_scope:
operator: "OR" # Apply policy if ANY condition matches
projects:
including:
- id: 1507906 # gitlab-org/ruby/gems/gitlab-exporter
groups:
including:
- id: 9970 # gitlab-org
With OR operator, the policy will apply to:
- Any project explicitly listed in
projects.including, OR - Any project belonging to groups listed in
groups.including
Backward Compatibility
- When no
operatoris specified, the system defaults toANDbehavior - All existing policies continue to work without modification
- The change is fully backward compatible
References
Closes #569793
Screenshots or screen recordings
| Before | After |
|---|---|
Policies with both projects and groups scope required ALL conditions to match (AND logic only) |
Policies can now use operator: "OR" to apply when ANY condition matches, or operator: "AND" for the original behavior |
How to set up and validate locally
-
Create a security policy with both project and group scopes:
policy_scope: operator: "OR" projects: including: - id: <project_id> groups: including: - id: <different_group_id> # Group that doesn't contain the project -
Verify the policy applies to the specified project even though it's not in the specified group
-
Test with
operator: "AND"to ensure backward compatibility -
Test without specifying
operatorto confirm default AND behavior
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.
Related to #569793