Introduce `ci_pipeline_variables_minimum_override_role` to refine user-defined variable restrictions based on project's minimum role.
Related to issue: #440338 (closed)
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.
- Introduce new options settings on
ProjectCiCdSettings
table in a new columnci_pipeline_variables_minimum_override_role
enumno_one_allowed|developer|maintainer|owner
with default value maintainer - Handle on the projects API (https://docs.gitlab.com/ee/api/projects.html#edit-project) a new attribute -
ci_pipeline_variables_minimum_override_role
- Consider
restrict_user_defined_variables
as a determinant forpipeline_variables_minimum_override_role
. If restrict_user_defined_variables is false, we disregard the value ofpipeline_variables_minimum_override_role
and permit variable overrides for any role. Conversely, if it is ON, we adhere topipeline_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
- Create a project for example
restrict_user_defined_variables
- Add a
.gitlab-ci.yml
variables:
USER_DEFINED_VAR1: 'USER DEFINED VAR1'
job1:
script:
echo $USER_DEFINED_VAR1
- Create a PAT
Project access token
. - Add a bunch of users to the project with different roles:
owner
,maintaianer
,developer
- Enable a feature flag -
::Feature.enable(:allow_user_variables_by_minimum_role)
- 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"
- 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"
- 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:
When not allowed users try to override defined variables they get a permission error: