GitLab Deploy Keys instead of Access Tokens, and Deploy Tokens

Deploy Keys

I manage a large number of Git repositories across many nested Linux user environments running in rootless namespaces and container-like setups. Access to these environments is done via (e.g.)sudo machinectl shell codimd@ under restricted user contexts, which makes standard SSH workflows such as SSH agent forwarding unreliable or not possible at all.

As a result, maintaining access to Git remotes for frequent pushes becomes quite cumbersome. So far, I relied on personal access tokens hardcoded in HTTPS git origin URLs. I had to replace these tokens regularly, because they would expire after (e.g.) a year. Conversely, propagating the SSH authentication socket through isolated sessions proved difficult.

The solution for these contexts: Gitlab Deploy Keys. Don’t confuse this with Gitlab Deploy Tokens. Unlike tokens, deploy Keys are only available in projects, not groups. You can find project deploy keys under Project → Settings → Repository → Deploy Keys.

1. Generate SSH key

ssh-keygen -t ed25519 -f ~/.ssh/gitlab-deploy -N ""

2. Show public key

cat ~/.ssh/gitlab-deploy.pub

3. Add key in GitLab

Project → Settings → Repository → Deploy Keys

  • Paste public key
  • Enable: “Write access allowed”
  • Add key

4. Configure git to use SSH key

This directly hooks your repo to the pecific deploy key:

git config core.sshCommand "ssh -i ~/.ssh/gitlab-deploy -o IdentitiesOnly=yes"

5. Switch repo remote to SSH

git remote set-url origin git@gitlab...:<group>/<repo>.git

6. Push test

git push

Reusing an Existing Deploy Key in a New Repository

If the key already exists on your server but is not yet enabled in your new GitLab project, or if it lacks push permissions:

1. Find the Fingerprint of the Active Key via Bash

If git config core.sshCommand is empty, your system uses default SSH keys. Find the exact SHA256 fingerprint:

# Test the SSH connection and list the keys being offered
ssh -vT git@gitlab.example.com 2>&1 | grep -E "Offering|accepts"

Alternatively, read the fingerprint directly from your known .pub file:

ssh-keygen -lf ~/.ssh/gitlab-deploy.pub

2. Enable the Key in the GitLab Web Interface

  1. Go to your new project: Settings -> Repository -> Deploy keys.
  2. Use your browser search (Ctrl + F or Cmd + F) to find the SHA256 value you discovered in step 1.
  3. Locate the key in the lists:
    • Under Privately accessible deploy keys: Click Enable on the right.
    • Already under Enabled deploy keys: Move directly to the next step.

3. Grant Write Access

By default, reused keys are restricted to read-only. To allow pushing code:

  1. Scroll to the top section: Enabled deploy keys.
  2. Find your key and click the Pencil icon (Edit) on the right.
  3. Check the box: Grant write permissions to this key.
  4. Click Save changes.

Deploy Tokens

A Git Deploy Key (SSH) only works for Git operations. For the Docker Registry, HTTP-based authentication is needed.

The easiest, most secure, and standard way to do this for a server is to create a GitLab Deploy Token.

1. Create a Deploy Token in GitLab

  1. Go to your GitLab project: Settings -> Repository.
  2. Expand the Deploy tokens section.
  3. Click Add token:
    • Name: Server-Pull-Token (or similar).
    • Username: (Leave blank, it will generate one).
    • Scopes: Check read_registry only.
  4. Click Create deploy token.
  5. Copy the username and password immediately (you won’t see the password again).

2. Log in on your VM and use it

Perform the docker login (use your gitlab registry!):

docker login gcr.hrz.tu-chemnitz.de
  • Username: (The generated username from GitLab, e.g., gitlab+deploy-token-123)
  • Password: (The generated password)

3. Pull the Image

Now that the credentials are stored in ~/.docker/config.json, your docker compose commands will work seamlessly, e.g.:

docker compose pull
docker compose up -d

Note: A one-liner:

echo "TOKEN" | docker login gcr.hrz.tu-chemnitz.de -u "USERNAME" --password-stdin