Skip to main content

GitLab SSH keys and selecting which key to use

This guide explains how to use more than one SSH key with GitLab on Windows (OpenSSH and optional Pageant), and how to choose a specific key per repository or per git push—including when an automation agent runs git in your shell.

Related:

Canonical remote for this repository

Always use the gitlab-ai SSH host alias for esysdox-ops (automation key ai_id_ed25519_gitlab, GitLab account @ESysRoot):

git@gitlab-ai:libesys/esysdox-ops.git

Local git remote name: gitlab (already configured after the initial push):

git remote add gitlab git@gitlab-ai:libesys/esysdox-ops.git
git push -u gitlab master

Do not use git@gitlab.com:libesys/esysdox-ops.git for this repo unless Host gitlab.com in ~/.ssh/config is updated to a valid IdentityFile. The gitlab.com alias may point at a missing id_ed25519_mg_libesys private key.

Agents and operators should run all GitLab git fetch / git push against gitlabgit@gitlab-ai:libesys/esysdox-ops.git.

Concepts

PieceRole
Key pairPrivate file on your PC + public file added to GitLab
~/.ssh/config Host blocksMap a short name (e.g. gitlab-ai) to gitlab.com + one private key
Git remote URLgit@HOST_ALIAS:group/project.git selects which Host block SSH uses
GitLab accountCan have many public SSH keys under Preferences → SSH Keys

SSH does not use “the AI’s key” as a separate identity. Commands run on your machine and use keys from your .ssh folder (or Pageant). You control the key by remote URL and IdentityFile in config.

Generate a new key (OpenSSH)

Example: dedicated key for automation or a single machine:

ssh-keygen -t ed25519 -C "ai@libesys.org" -f $env:USERPROFILE\.ssh\ai_id_ed25519_gitlab
  • Use a passphrase for interactive-only keys, or -N '""' only if you accept non-interactive push without a passphrase (automation trade-off).
  • Outputs:
    • ai_id_ed25519_gitlabprivate (never commit, never paste in chat)
    • ai_id_ed25519_gitlab.pubpublic (safe to add to GitLab)

Show the public key for copy/paste:

Get-Content $env:USERPROFILE\.ssh\ai_id_ed25519_gitlab.pub

Add the public key to GitLab

Account key (typical):

  1. GitLab → PreferencesSSH Keys
  2. Paste the .pub line → Add key

Repeat for each key you use (personal, work, automation). GitLab accepts multiple keys on one account.

Project deploy key (optional):

  • Project → SettingsRepositoryDeploy keys
  • One writable deploy key per project if you need repo-scoped access only

Configure ~/.ssh/config to select a key

On Windows the file is C:\Users\<you>\.ssh\config.

If you use Pageant (PuTTY), keep an existing line such as:

Include pageant.conf

Add separate Host blocks per key. Use IdentitiesOnly yes so SSH does not offer every loaded Pageant key until GitLab accepts one at random.

Example: personal key on gitlab.com, automation key on alias gitlab-ai:

Include pageant.conf

# Personal / default LibESys key (OpenSSH file or via Pageant for other tools)
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_mg_libesys
IdentitiesOnly yes

# Automation / agent pushes — dedicated key file
Host gitlab-ai
HostName gitlab.com
User git
IdentityFile ~/.ssh/ai_id_ed25519_gitlab
IdentitiesOnly yes

Notes:

  • HostName is always the real server (gitlab.com).
  • Host is only the alias you use in git URLs.
  • Paths use ~/.ssh/...; OpenSSH on Windows expands them correctly.
  • If the personal key is only in Pageant as a .ppk, load it in Pageant or export an OpenSSH private key (PuTTYgen) and point IdentityFile at that file.

Self-managed GitLab: replace gitlab.com with your hostname in both HostName and URLs (e.g. git@gitlab-ai:group/repo.git still works if HostName is your server).

Choose the key in git remotes

Remote URLSSH uses
git@gitlab.com:libesys/esysdox-ops.gitHost gitlab.comid_ed25519_mg_libesys (not used for this repo)
git@gitlab-ai:libesys/esysdox-ops.gitHost gitlab-aiai_id_ed25519_gitlab (canonical for esysdox-ops)

Add a remote (name gitlab is arbitrary):

git remote add gitlab git@gitlab-ai:libesys/esysdox-ops.git

Push:

git push -u gitlab master

To switch an existing remote to the other key:

git remote set-url gitlab git@gitlab-ai:libesys/esysdox-ops.git

Test before pushing

ssh -T git@gitlab.com
ssh -T git@gitlab-ai

Success looks like:

Welcome to GitLab, @YourUsername!

GitLab may exit with code 0 or 1 for this test command; the welcome line matters.

Ask an agent to use a specific key

When using Cursor or another agent that runs git in your environment, instruct it explicitly:

  • “Use remote gitlab with host alias gitlab-ai, or
  • “Push to git@gitlab-ai:group/esysdox-ops.git

The agent should not receive your private key in chat. It relies on your local ~/.ssh/config and the remote URL you specify.

One-off key without editing remotes

For a single command:

$env:GIT_SSH_COMMAND = "ssh -i $env:USERPROFILE\.ssh\ai_id_ed25519_gitlab -o IdentitiesOnly=yes"
git push gitlab master

Prefer Host aliases in config for anything repeated.

Pageant and multiple keys

If Include pageant.conf is set, Pageant may still load legacy .ppk keys. Use IdentitiesOnly yes on each Host gitlab* block so OpenSSH uses only the IdentityFile you named for that alias.

Typical workflow:

  • Daily PuTTY/Pageant workflows → load .ppk in Pageant.
  • Git from terminal with a dedicated alias → Host gitlab-ai + OpenSSH IdentityFile.

Security practices

DoDon't
Add only .pub files to GitLabPaste private keys in issues, chat, or email
Use separate keys per machine or purpose when usefulCommit *_gitlab private keys to git
Revoke keys in GitLab when a machine is retiredShare one private key across people
Use deploy keys for single-repo automationReuse production personal keys for experiments

Troubleshooting

Permission denied (publickey)

  • Public key not added to GitLab (or wrong account).
  • Wrong Host in URL (gitlab.com vs gitlab-ai).
  • Private file path wrong in IdentityFile.
  • Pageant offering other keys — set IdentitiesOnly yes.

Agent push works in terminal but not from IDE

  • IDE may use a different user or miss ~/.ssh/config; run ssh -T git@gitlab-ai in the same environment the agent uses.
  • Approve network/shell permissions when the agent runs git push.

Host key / known_hosts

First connect may ask to trust GitLab’s host key; accept once or add gitlab.com to known_hosts via a manual ssh -T.

Quick checklist

  • Key pair created (ssh-keygen)
  • .pub added to GitLab SSH Keys (or deploy key)
  • ~/.ssh/config has one Host block per key with IdentitiesOnly yes
  • ssh -T git@gitlab-ai (or your alias) shows welcome message
  • git remote URL uses the intended alias (git@gitlab-ai:...)
  • Agent instructions name the alias when you want the non-default key