Using SSH Keys with Git Services#
This page explains how to use SSH keys with Git services such as Surrey GitLab, GitHub and GitLab.com.
It is aimed at users who:
use Git over SSH rather than HTTPS
use more than one Git service, for example Surrey GitLab and GitHub
see permission errors even though
ssh -Tappears to authenticate successfullywant to understand the difference between SSH authentication and Git commit identity
For most users, the setup is simple: add your public key to the Git service, make sure your repository uses an SSH remote URL, and set your Git name and email address.
SSH authentication and Git identity are separate#
There are two related but different pieces of configuration:
- SSH authentication:
Determines whether you are allowed to fetch from or push to a Git service. This is controlled by your SSH key and
~/.ssh/config.- Git commit identity:
Determines the name and email address recorded in your commits. This is controlled by Git configuration, usually
~/.gitconfigor repository-specific Git config.
For example, SSH might allow you to push to a repository, but your commits could still use the wrong email address if Git itself is not configured correctly.
Configure SSH for Git services#
If you use more than one Git service, it is useful to configure ~/.ssh/config so each service has a clear entry.
Example ~/.ssh/config:
Host surrey-gitlab
HostName gitlab.surrey.ac.uk
User git
IdentityFile ~/.ssh/id_ed25519_surrey_gitlab
IdentitiesOnly yes
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab_com
IdentitiesOnly yes
IdentitiesOnly yes tells SSH to use the key specified by IdentityFile rather than trying several keys from your SSH agent.
Notes for Windows users
On Windows using OpenSSH, SSH keys are usually stored in your Windows user profile, for example:
C:\Users\YourUsername\.ssh\id_ed25519_github
In ~/.ssh/config you can usually refer to this key using the shorter
cross-platform form:
IdentityFile ~/.ssh/id_ed25519_github
If you use a full Windows path in ~/.ssh/config, forward slashes are often
clearer:
IdentityFile C:/Users/ab1234/.ssh/id_ed25519_github
If you use WSL, it has its own separate Linux home directory and SSH keys, for example
/home/ab1234/.ssh/id_ed25519_github
If you use PuTTY, Pageant or WinSCP, those tools may use their own SSH key settings rather than this OpenSSH config file.
Test authentication#
Run the relevant test command:
ssh -T git@surrey-gitlab
ssh -T git@github.com
ssh -T git@gitlab.com
GitHub and GitLab.com may tell you that authentication succeeded but shell access is not provided. That is normal for Git hosting services. They allow Git operations over SSH, but not interactive shell login.
Use SSH remote URLs#
SSH Git remote URLs look like this:
git@surrey-gitlab:group/project.git
git@github.com:organisation/repository.git
git@gitlab.com:group/project.git
HTTPS remote URLs look like this:
https://github.com/organisation/repository.git
If you want to use SSH keys, make sure your repository remote uses an SSH URL.
To check the remote URL for an existing repository, first change into the repository directory, then run:
cd path/to/your/repository
git remote -v
To change the remote URL:
git remote set-url origin git@surrey-gitlab:group/project.git
Set your Git commit identity#
SSH keys determine whether you are allowed to fetch or push. They do not determine the author name and email address in your commits.
Set your identity globally:
git config --global user.name "Your Name"
git config --global user.email "your.name@surrey.ac.uk"
Check your current identity:
git config --get user.name
git config --get user.email
For many users, a single global Git identity is sufficient.
Set identity for one repository only
If a particular repository should use a different name or email address, change into that repository and use --local:
cd path/to/your/repository
git config --local user.name "Your Name"
git config --local user.email "your.name@surrey.ac.uk"
This affects only the current repository.
Advanced: directory-based Git identities
Advanced users may want Git to use different names or email addresses depending on where a repository is stored.
Example directory layout:
~/code/
surrey/
github/
gitlab-com/
Example ~/.gitconfig:
[user]
useConfigOnly = true
[init]
defaultBranch = main
[pull]
ff = only
[fetch]
prune = true
[push]
default = simple
[core]
excludesfile = ~/.gitignore_global
[includeIf "gitdir:~/code/surrey/"]
path = ~/.gitconfig-surrey
[includeIf "gitdir:~/code/github/"]
path = ~/.gitconfig-github
[includeIf "gitdir:~/code/gitlab-com/"]
path = ~/.gitconfig-gitlab-com
Example ~/.gitconfig-surrey:
[user]
name = ab1234
email = your.name@surrey.ac.uk
Example ~/.gitconfig-github:
[user]
name = your-github-username
email = your-github-username@users.noreply.github.com
The line useConfigOnly = true prevents Git from guessing an identity when no matching configuration is found. This makes accidental commits with the wrong email address less likely.
Optional: global ignore file
A global ignore file is useful for local editor and operating system files that you never want Git to offer as untracked files.
In ~/.gitconfig:
[core]
excludesfile = ~/.gitignore_global
Example ~/.gitignore_global:
# macOS
.DS_Store
# JetBrains IDEs
.idea/
*.iml
# VS Code
.vscode/
# Python
__pycache__/
*.py[cod]
.ipynb_checkpoints/
# Temporary files
*.swp
*.swo
*~
Project-specific generated files, data files or build outputs should usually go into the repository’s own .gitignore so that all collaborators benefit from the same ignore rules.
Advanced: one repository with more than one remote
Most repositories only need one remote, usually called origin. Some advanced workflows use more than one remote. For example, you might keep a project on Surrey GitLab but also push a copy to GitHub.
List the remotes for the current repository:
git remote -v
Add a second remote:
git remote add github git@github.com:organisation/project.git
Push to a specific remote:
git push origin main
git push github main
If you are unsure whether you need more than one remote, you probably only need origin.
Troubleshooting
git remote -vdoes not workgit remote -vmust be run from inside a Git repository directory. First change into the repository, for example:cd path/to/your/repository git remote -v
Permission denied (publickey)SSH could not authenticate with an accepted key. Check that the public key has been added to the Git service and that
~/.ssh/configpoints to the right private key.- Permission denied to a repository
If GitHub or GitLab says permission is denied for a repository, SSH may have authenticated correctly but the account may not have access to that project. Check that you have been added to the repository or group with the correct role.
- SSH keeps trying the wrong key
Add
IdentitiesOnly yesto the relevant host block in~/.ssh/config.- Check what SSH is doing
Use verbose output:
ssh -vT git@github.com- Check where Git identity came from
Inside the repository, run:
git config --show-origin --get user.name git config --show-origin --get user.email