This question is about how to manage access for private gitlab python packages with nested dependencies on other private gitlab packages. This assumes all the access is via direct git repository patterns and not a private package repository.
package-a
is in a private gitlab repository and it depends on package-b
, which depends on package-c
and they are also in a private gitlab repository.
package-a
has a pyproject.toml
like this:
[tool.poetry]
name = "package-a"
repository = "https://gitlab.com/org/package_a.git"
[tool.poetry.dependencies]
python = "^3.6"
package-b = {git = "ssh://[email protected]/org/package_b.git", tag = "0.1.0"}
package-b
has a pyproject.toml
like this:
[tool.poetry]
name = "package-b"
repository = "https://gitlab.com/org/package_b.git"
[tool.poetry.dependencies]
python = "^3.6"
package-c = {git = "ssh://[email protected]/org/package_c.git", tag = "0.1.0"}
Any user with the right org
membership on gitlab and an ssh-key can use poetry
to install package-a
and it's dependency on package-b
and then it's dependency on package-c
, all into a python venv on a development laptop. The ssh
protocol access also works for docker builds (with experimental features for ssh mounts).
However, the same projects with private dependencies are not installed in gitlab-CI runners, because they lack ssh access. (Is there any secure way to enable that?)
Assuming the gitlab-CI runners must use an access token to clone the private gitlab repositories, a sed
script is applied to the pyproject.toml
file for project-a
, so the gitlab-CI runner can clone package-b
to discover that it depends on package-c
; the sed
script changes the ssh to https access for project-b
by editing the project-a
dependency spec in pyproject.toml
, i.e.
sed -i -e 's#ssh://[email protected]/org#https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/org#g' pyproject.toml
The CI_JOB_TOKEN is an environment variable provided by the gitlab-CI runner. It is securely managed by the gitlab-CI runner. So, gitlab-CI runner can now clone the project-b
repository somewhere. The same sed trick might work if it could be applied to this project-b
repository somewhere, but this is now in the hands of poetry
and it cannot be touched. So project-b
has a git+ssh dependency on project-c
and the gitlab-CI runner fails to install project-c
because it has no git+ssh credentials to clone it.
Thus, the private package dependency chain works for development and docker build on a laptop with git+ssh access, but it's all broken on gitlab-CI. What's the better practice to manage this private package access across all these build environments?
GitLab Container Registry is a secure and private registry for Docker images. It is integrated with GitLab CI/CD pipelines and provides a convenient way to push and pull images. Container Registry is a standalone product and is not part of GitLab Core.
These snippets are based on:
ssh-keygen -o -t rsa -b 4096 -C "[email protected]"
# output to something like ~/.ssh/gitlab_ci_rsa
# do not add any passphrase
# once created, copy the private key to the clipboard, e.g.
cat ~/.ssh/gitlab_ci_rsa | base64 -w0 > tmp.txt
xclip -sel clip < tmp.txt
The public key is used as a private deploy key, which is enabled from a project settings page, e.g.
The private key is pasted into the gitlab-CI variable SSH_PRIVATE_KEY
and gitlab should be able to mask it (when it is base64
encoded). Then the .gitlab-ci.yml
file can add this private key to the ssh-agent using:
before_script:
- apt-get update -y -qq && apt-get install -y -qq git make openssh-client
- eval $(ssh-agent -s)
## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
- ssh-add <(echo "$SSH_PRIVATE_KEY" | base64 --decode)
## Create the SSH directory and give it the right permissions
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
The gitlab documentation does not use base64
encoding, but it's essential to copying all of the private key into the variable and that avoids a prompt for a passphrase from ssh-add.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With