Fix: Apply variables_override to dotenv artifacts in Pipeline Execution Policies
What does this MR do and why?
Fixes #578849
This MR ensures that dotenv artifact variables respect the variables_override policy settings in Pipeline Execution Policies, with a configurable option to maintain backward compatibility.
Problem
Even though the overriding of variables in Pipeline Execution Policies can be forbidden via variables_override.allowed: false, variables from dotenv artifacts can still bypass these restrictions. This creates a security gap where policy-protected variables can be overridden through dotenv artifacts, undermining the security controls that Pipeline Execution Policies are meant to enforce.
Solution
As proposed by @mcavoj in #578849 (comment 2862627304), this MR applies the VariablesOverride logic to dotenv variables by overriding the dependency_variables method in an EE extension of Ci::Processable.
To address the concern raised by @g.hickman about potential breaking changes, a new configurable dotenv option has been added to variables_override to allow customers to opt-in to the new behavior.
Implementation details:
- Creates
ee/app/models/ee/ci/processable.rbto extend the CECi::Processablemodel - Overrides
dependency_variablesto applySecurity::PipelineExecutionPolicy::VariablesOverridefiltering withsource: :dotenv - Adds
respect_dotenv_policy?method toVariablesOverrideclass to check the newdotenvconfiguration option - Respects both
allowed: false(allowlist mode) andallowed: true(denylist mode) configurations - Supports the
exceptionslist for fine-grained control over which variables can/cannot be overridden - Maintains backward compatibility with legacy
execution_policy_jobformat
Configuration:
Customers can now control dotenv behavior via the dotenv option in variables_override:
variables_override:
allowed: false
exceptions: []
dotenv: respect_policy # or 'allow_override' for legacy behavior
-
dotenv: respect_policy(default): Dotenv variables respectvariables_overriderules (new secure behavior) -
dotenv: allow_override: Dotenv variables bypassvariables_overriderules (legacy behavior for backward compatibility)
Test coverage:
- Tests for allowlist mode (
allowed: false) - blocks all dotenv variables except those in exceptions - Tests for denylist mode (
allowed: true) - allows all dotenv variables except those in exceptions - Tests for
dotenv: allow_overrideconfiguration in both allowlist and denylist modes - Tests for legacy policy format
- Tests with multiple dotenv variables
How to set up and validate locally
- Create a pipeline execution policy with
variables_override.allowed: false:
pipeline_execution_policy:
- name: Execute pipeline job with variables
enabled: true
pipeline_config_strategy: inject_policy
content:
include:
- project: your-policy-project
file: policy-pipeline.yml
variables_override:
allowed: false
exceptions: []
dotenv: respect_policy # New option - respects policy by default
policy_scope:
projects:
including:
- id: your-project-id
- In the policy pipeline, define protected variables:
variables:
PROTECTED_VAR: "I should not be overridden"
policy:job:
script:
- echo $PROTECTED_VAR
- In the project pipeline, create a job that generates dotenv artifacts:
prepare:
script:
- echo "PROTECTED_VAR=I am trying to override" >> build.env
artifacts:
reports:
dotenv: build.env
-
Run the pipeline and verify that
PROTECTED_VARmaintains its policy-defined value and is not overridden by the dotenv artifact -
To test backward compatibility, set
dotenv: allow_overridein the policy and verify that dotenv variables can override protected variables
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related issues
Closes #578849