Skip to content

Non-Deployment jobs (e.g. `action: prepare`, `action: verify`) are not executable when the environment is protected

Summary

When a job runs that targets a specific environment, it normally indicates what environment is affected, and, once complete, the job is listed as the most recent "deployment" to an environment.

When Protected Environments are configured for a project, only the selected roles and/or groups & users are allowed to deploy to an environment.

However, jobs such as a Terraform plan job are usually configured with action: prepare as they don't actually modify the environment, but still may need environment specific CI/CD variables to be successful.

Steps to reproduce

  1. Create a project within a Premium/Enterprise Licensed group/instance
  2. Set up a CI/CD pipeline with e.g. Terraform
  3. Configure Protected Environments and try running the pipeline as a e.g. non-Maintainer user
  4. Get the following error message:

    The environment this job is deploying to is protected. Only users with permission may successfully run this job.

What is the current bug behavior?

Jobs with action: prepare are only allowed for users permitted to deploy to the environment.

What is the expected correct behavior?

Prepare jobs should either not be affected by Protected Environments or it should be configurable per action: default (no action specified), stop, prepare.

Relevant logs and/or screenshots

image

Potential Fix

diff --git a/ee/app/policies/ee/ci/build_policy.rb b/ee/app/policies/ee/ci/build_policy.rb
index 4b2674aba12c..30dc1f78342d 100644
--- a/ee/app/policies/ee/ci/build_policy.rb
+++ b/ee/app/policies/ee/ci/build_policy.rb
@@ -7,7 +7,7 @@ module BuildPolicy
       prepended do
         # overriding
         condition(:protected_environment) do
-          @subject.persisted_environment.try(:protected_from?, user)
+          @subject.persisted_environment.try(:protected_from?, user) && @subject.deployment.present?
         end
 
         condition(:reporter_has_access_to_protected_environment) do
diff --git a/ee/app/services/ee/ci/process_build_service.rb b/ee/app/services/ee/ci/process_build_service.rb
index d73c2579706c..f3b7b3ea8f79 100644
--- a/ee/app/services/ee/ci/process_build_service.rb
+++ b/ee/app/services/ee/ci/process_build_service.rb
@@ -19,7 +19,7 @@ def process(build)
 
       override :enqueue
       def enqueue(build)
-        if build.persisted_environment.try(:protected_from?, build.user)
+        if build.persisted_environment.try(:protected_from?, build.user) && build.deployment.present?
           return build.drop!(:protected_environment_failure)
         end

Warning: This is technically loosening the authorization to the protected environment deployment access. We should rollout carefully not to break existing CD workflow.

This change implies that users who are not in Allowed-To-Deploy can execute Non-Deployment jobs. So semantically this makes sense.

Edited by Shinya Maeda