Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GitLab CI denies access to push using a deploy key with write access

I added a deploy key with write access to my GitLab repository. My .gitlab-ci.yml file contains:

- git clone [email protected]:user/repo.git
- git checkout master
- git add myfile.pdf
- git commit -m "Generated PDF file"
- git push origin master

The deploy key works when cloning the repository. Pushing is not possible, even if the deploy key has write access.

remote: You are not allowed to upload code.
fatal: unable to access 'https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@domain/user/repo.git/': The requested URL returned error: 403
like image 451
jasdefer Avatar asked Mar 18 '19 15:03

jasdefer


People also ask

How do I add deploy keys?

On your profile page, click Repositories, then click the name of your repository. From your repository, click Settings. In the sidebar, click Deploy Keys, then click Add deploy key. Provide a title, paste in your public key.


1 Answers

I just encountered the same problem and saw this question without answer, so there is my solution.

Problem

The problem is caused by the fact that the remote url used by git to push the code is in the form http(s)://gitlab-ci-token:[email protected]/group/project.git. This url is using http(s) protocol so git doesn't use the ssh deploy key that you setup.

Solution

The solution is to change the push url of the remote origin so it matches ssh://[email protected]/group/project.git. The easiest way to do so is to use the predefined variable CI_REPOSITORY_URL.

Here is an example of code doing so by using sed:

# Change url from http(s) to ssh
url_host=$(echo "${CI_REPOSITORY_URL}" | sed -e 's|https\?://gitlab-ci-token:.*@|ssh://git@|g')
echo "${url_host}"
# ssh://[email protected]/group/project.git

# Set the origin push url to the new one
git remote set-url --push origin "${url_host}"

Also, those using docker executor may want to verify the SSH host key as suggested by the gitlab documentation on deploy keys for docker executor.

So I give a more complete example for docker executor. The code is mainly from gitlab documentation on ssh deploy keys. In this example, the private deploy key is stored inside a variable named SSH_PRIVATE_KEY.

create:push:pdf:
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - git config --global user.email "[email protected]"
    - git config --global user.name "User name"
    - gitlab_hostname=$(echo "${CI_REPOSITORY_URL}" | sed -e 's|https\?://gitlab-ci-token:.*@||g' | sed -e 's|/.*||g')
    - ssh-keyscan "${gitlab_hostname}" >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - git checkout master
    - git add myfile.pdf
    - git commit -m "Generated PDF file"
    - url_host=$(echo "${CI_REPOSITORY_URL}" | sed -e 's|https\?://gitlab-ci-token:.*@|ssh://git@|g')
    - git remote set-url --push origin "${url_host}"
    - git push origin master

like image 140
Bichon Avatar answered Oct 12 '22 14:10

Bichon