Allow CI_JOB_TOKEN to push to its own repository
Problem
CI_JOB_TOKEN allows to clone private repo, but doesn't allow to push back to the same repo.
Users can push with a personal access token or project access token but we want to give them a shorter lived token like CI_JOB_TOKEN to be able to do this with.
Proposal
Add Repository Write permissions matching the users role to the scope for the CI_JOB_TOKEN.
Alternative
An alternative is to share SSH key or a Personal Access Token for free tier.
This widens attack surface to include all user projects. Makes it possible to attack asynchronously at a later time rather than from the auditable pipeline run.
Additional details
Testing in CI/CD
$ git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git /tmp
Cloning into '/tmp'...
$ git push -o ci.skip https://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git HEAD:data
remote: You are not allowed to upload code.
fatal: unable to access 'https://gitlab.com/abitrolly/data-dockerhub-top.git/': The requested URL returned error: 403
Implementation Guide
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 06bdb2c1ddce..61e6ced9022e 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -326,6 +326,7 @@ def build_authentication_abilities
[
:read_project,
:build_download_code,
+ :build_push_code,
:build_read_container_image,
:build_create_container_image,
:build_destroy_container_image
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index 35b330fa0894..d33ffb145fb8 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -230,7 +230,7 @@ def check_authentication_abilities!
raise ForbiddenError, error_message(:auth_download)
end
when *PUSH_COMMANDS
- unless authentication_abilities.include?(:push_code)
+ unless authentication_abilities.include?(:push_code) || authentication_abilities.include?(:build_push_code)
raise ForbiddenError, error_message(:auth_upload)
end
end
@@ -340,7 +340,8 @@ def check_change_access!
if changes == ANY
can_push = deploy_key? ||
user_can_push? ||
- project&.any_branch_allows_collaboration?(user_access.user)
+ project&.any_branch_allows_collaboration?(user_access.user) ||
+ authentication_abilities.include?(:build_push_code) && user_can_push?
unless can_push
raise ForbiddenError, error_message(:push_code)
but I'd have to confirm the code and that the inheriting classes work well with it. Other resources git http code like wikis with their own privacy settings inherit from this class.
We may not want to add this feature at this time. There is an internal discussion about it.
This page may contain information related to upcoming products, features and functionality. It is important to note that the information presented is for informational purposes only, so please do not rely on the information for purchasing or planning purposes. Just like with all projects, the items mentioned on the page are subject to change or delay, and the development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab Inc.