Skip to content

Introduce `ci_pipeline_variables_minimum_override_role` to refine user-defined variable restrictions based on project's minimum role.

Related to issue: #440338

What does this MR do and why?

Users want to be able to restrict user-defined variables from being overridden by Developers and Maintainers. Currently the restrict_user_defined_variables project option only restricts it so that Maintainers and Owners can still override them.

  1. Introduce new options settings on ProjectCiCdSettings table in a new columnci_pipeline_variables_minimum_override_role enum developer|maintainer|owner with default value maintainer
  2. Handle on the projects API (https://docs.gitlab.com/ee/api/projects.html#edit-project) a new attribute - ci_pipeline_variables_minimum_override_role
  3. Consider restrict_user_defined_variables as a determinant for pipeline_variables_minimum_override_role. If restrict_user_defined_variables is false, we disregard the value of pipeline_variables_minimum_override_role and permit variable overrides for any role. Conversely, if it is ON, we adhere to pipeline_variables_minimum_override_role and establish overwrite permissions based on the role.

As a result, we've introduced a more gradual way to limit the overriding of user-defined variables based on the user's role: developer, maintainer, or owner. This change supports the old restrict_user_defined_variables settings for a while, ensuring a smooth transition without breaking anything.

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.

Database

Migration

VERSION=20240411204324 bundle exec rails db:migrate      
main: == [advisory_lock_connection] object_id: 124340, pg_backend_pid: 9432
main: == 20240411204324 AddCiPipelineVariablesMinimumRoleEnum: migrating ============
main: -- add_column(:project_ci_cd_settings, :pipeline_variables_minimum_override_role, :integer, {:default=>40, :null=>false, :limit=>2})
main:    -> 0.0027s
main: == 20240411204324 AddCiPipelineVariablesMinimumRoleEnum: migrated (0.0067s) ===

main: == [advisory_lock_connection] object_id: 124340, pg_backend_pid: 9432

Rollback

VERSION=20240411204324 bundle exec rails db:rollback:main
main: == [advisory_lock_connection] object_id: 124080, pg_backend_pid: 8994
main: == 20240411204324 AddCiPipelineVariablesMinimumRoleEnum: reverting ============
main: -- remove_column(:project_ci_cd_settings, :pipeline_variables_minimum_override_role, :integer, {:default=>40, :null=>false, :limit=>2})
main:    -> 0.0018s
main: == 20240411204324 AddCiPipelineVariablesMinimumRoleEnum: reverted (0.0064s) ===

main: == [advisory_lock_connection] object_id: 124080, pg_backend_pid: 8994

How to set up and validate locally

  1. Create a project for example restrict_user_defined_variables
  2. Add a .gitlab-ci.yml
variables:
  USER_DEFINED_VAR1: 'USER DEFINED VAR1'
job1:
  script:
    echo $USER_DEFINED_VAR1
  1. Create a PAT Project access token.
  2. Add a bunch of users to the project with different roles: owner, maintaianer, developer
  3. Enable a feature flag - ::Feature.enable(:allow_user_variables_by_minimum_role)
  4. Enable restrict_user_defined_variables - set it to true
   curl --request PUT --header "PRIVATE-TOKEN: PAT" "http://gdk.test:3000/api/v4/projects/59"  --form "restrict_user_defined_variables=true"
  1. Set different roles maintainer, owner, developer to ci cd settings of project via API:
   curl --request PUT --header "PRIVATE-TOKEN: PAT" "http://gdk.test:3000/api/v4/projects/59"  --form "ci_pipeline_variables_minimum_override_role=owner"
  1. Run a pipeline manually impersonating different user roles on the project redefining a user-defined variable USER_DEFINED_VAR1

When allowed users try to override defined variables they get a normal output:

Screenshot_2024-04-16_at_19.21.28

When not allowed users try to override defined variables they get a permission error:

Screenshot_2024-04-16_at_19.21.03

Edited by Dmytro Biryukov

Merge request reports