---
title: "Git SSH Keys for GitHub, GitLab, and Bitbucket on Linux"
description: "Git connects to remotes by default via HTTPS, which requires you to enter your login and password every time you run a command like Git pull or git push, using the SSH protocol. You may connect to servers and authenticate to access their services. The three services listed allow Git to connect through SSH rather than HTTPS. Using public-key encryption eliminates the need to type a login and password for each Git command."
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/blog/post/git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux
---

# Git SSH Keys for GitHub, GitLab, and Bitbucket on Linux

## Introduction

By default, Git talks to remotes over HTTPS, so it asks for your username and password on every `git pull` or `git push`. SSH fixes that. GitHub, GitLab, and Bitbucket all let Git authenticate over SSH with public-key encryption instead set it up once and you stop typing credentials for every Git command.

  An SSH key is a pair of files: a **private key** that never leaves your
  machine, and a **public key** you upload to each service. Authentication
  happens by proving you hold the private key no password sent over the wire.

## Make sure a Git and SSH client is installed

A Git and SSH client must be installed on your system to connect via the SSH protocol. It should be installed by default if you use Arch Linux-based distributions like Manjaro or Garuda Linux.

```shell title="Check if Git and SSH are installed"
git --version
ssh -V
```

That command should return the Git version and SSH client's version number:

```shell title="Output"
git version 2.34.1
OpenSSH_8.8p1, OpenSSL 1.1.1l  24 Aug 2021
```

If the system tells you that the `ssh` or `git` commands are missing, install them with the command set for your distribution:

```shell title="Arch-based (Manjaro, Garuda)"
sudo pacman -Syu
sudo pacman -Syyu
sudo pacman -S git
sudo pacman -S openssh
```

```shell title="Debian-based (Ubuntu, Mint)"
sudo apt update
sudo apt upgrade
sudo apt install git
sudo apt install openssh
```

```shell title="Red Hat-based (RHEL, CentOS)"
sudo yum upgrade
sudo yum install git
sudo yum install openssh
```

```shell title="SUSE-based (openSUSE)"
sudo zypper upgrade
sudo zypper install git
sudo zypper install openssh
```

```shell title="Fedora-based"
sudo dnf upgrade
sudo dnf install git
sudo dnf install openssh
```

Don't forget to specify global Git settings using the following command after installing Git:

```shell title="Set global Git settings"
git config --global user.name 'USERNAME'
git config --global user.email 'YOUR_EMAIL@EXAMPLE.COM'
```

## Look for any SSH keys that have already been created

```shell title="Check for existing SSH keys"
ls -lah ~/.ssh
```

That command lists the contents of the `~/.ssh` folder, where the SSH client stores its configuration files. A typical populated directory looks like this:

- ~/.ssh/
  - **id_ed25519** Ed25519 private key never share this
  - **id_ed25519.pub** Ed25519 public key safe to upload
  - **id_rsa** RSA private key (legacy) never share this
  - **id_rsa.pub** RSA public key (legacy) safe to upload
  - known_hosts
  - config

  Don't worry if you get an error saying there is no `~/.ssh` directory or no
  files in there it just indicates you haven't established an SSH key pair yet.
  Proceed to the next section if this is the case.

  It's worth regenerating your SSH key pair about once a year. If your current
  pair is older than that, generate a new one below; if it's recent and you want
  to keep it, skip the next section.

## Make a fresh set of SSH keys

Generate a new SSH key pair, replacing `YOUR_EMAIL@EXAMPLE.COM` with your email address. **Use Ed25519** it's what GitHub, GitLab, and Bitbucket recommend today. Reach for RSA only on an older system or server that doesn't support Ed25519.

```shell title="Create a new Ed25519 SSH key pair"
ssh-keygen -t ed25519 -C 'YOUR_EMAIL@EXAMPLE.COM'
```

This creates `~/.ssh/id_ed25519` (private) and `~/.ssh/id_ed25519.pub` (public). Ed25519 keys are small and fast, with security on par with a 4096-bit RSA key.

```shell title="Create a new RSA SSH key pair"
ssh-keygen -t rsa -b 4096 -C 'YOUR_EMAIL@EXAMPLE.COM'
```

This creates `~/.ssh/id_rsa` (private) and `~/.ssh/id_rsa.pub` (public). Use the older RSA type only if you need to talk to a legacy system or server that doesn't support Ed25519.

After running the command, complete the prompts:

1. Choose where to save the private key. Press Enter to accept the default location (`~/.ssh/id_ed25519`, or `~/.ssh/id_rsa` for an RSA key):

```shell title="Output"
Generating public/private ed25519 key pair. Enter file in which to save the key (/home/your_user_name/.ssh/id_ed25519):
```

2. If a private key already exists, you'll be asked whether to overwrite it. Type `y` and press Enter:

```shell title="Output"
/home/your_user_name/.ssh/id_ed25519 already exists.
Overwrite (y/n)?
```

3. Enter and re-enter a passphrase (think of it as a password for the key):

```shell title="Output"
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```

  A passphrase encrypts your private key on disk, so a stolen key file is
  useless without it. Combined with the `ssh-agent` (next section), you only
  type it once per session.

The SSH key pair is created in `~/.ssh`, and the whole interaction should look like this:

```shell title="Output"
your_user_name@your_host_name:~> ssh-keygen -t ed25519 -C 'YOUR_EMAIL@EXAMPLE.COM'
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/YOUR_USER_NAME/.ssh/id_ed25519):
/home/YOUR_USER_NAME/.ssh/id_ed25519 already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/YOUR_USER_NAME/.ssh/id_ed25519.
Your public key has been saved in /home/YOUR_USER_NAME/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:Qx3yXenY8FOQmvIsjKVp6oAlITe3k1aMKRdViOFePP6 YOUR_EMAIL@EXAMPLE.COM
The key's randomart image is:
+--[ED25519 256]--+
|        .o+.     |
|       .oo=o     |
|      . o*+.o    |
|     . ..oB.+    |
|      o.S=.* .   |
|     . +o.E o    |
|      o.o+.= .   |
|       =o.++o    |
|      ..o**+.    |
+----[SHA256]-----+
YOUR_USER_NAME@YOUR_HOST_NAME:~>
```

```shell title="Output"
your_user_name@your_host_name:~> ssh-keygen -t rsa -b 4096 -C 'YOUR_EMAIL@EXAMPLE.COM'
Generating public/private rsa key pair.
Enter file in which to save the key (/home/YOUR_USER_NAME/.ssh/id_rsa):
/home/YOUR_USER_NAME/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/YOUR_USER_NAME/.ssh/id_rsa.
Your public key has been saved in /home/YOUR_USER_NAME/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:XenY8FOQmvIsjKVp6oAlITe3k1aMKRdViOFePP6/CuK YOUR_EMAIL@EXAMPLE.COM
The key's randomart image is:
+---[RSA 4096]----+
|o.=@X++.         |
|o*@O++           |
|=Bo+=+           |
|Oo+ oo..         |
|=+ . .. S        |
|...   o          |
| .   o .         |
|    . . o        |
|   E   . o.      |
+----[SHA256]-----+
YOUR_USER_NAME@YOUR_HOST_NAME:~>
```

## To the ssh-agent, add your private SSH key

If you'd rather not retype your passphrase every time you use the key, add it to the `ssh-agent` a background process that keeps your keys in memory while you're logged in.

1. Start the `ssh-agent` in the background:

```shell title="Start the ssh-agent"
eval "$(ssh-agent -s)"
```

The command returns the `ssh-agent` process identification:

```shell title="Output"
Agent pid 2887
```

2. Add your SSH private key to the `ssh-agent` pick the tab for your key type:

```shell title="Add the Ed25519 private key to the ssh-agent"
ssh-add ~/.ssh/id_ed25519
```

```shell title="Add the RSA private key to the ssh-agent"
ssh-add ~/.ssh/id_rsa
```

3. Type your passphrase and press Enter:

```shell title="Output"
Enter passphrase for /home/YOUR_USER_NAME/.ssh/id_ed25519:
```

The `ssh-agent` confirms the private SSH key has been added:

```shell title="Output"
Identity added: /home/YOUR_USER_NAME/.ssh/id_ed25519 (YOUR_EMAIL@EXAMPLE.COM)
```

## To your account, add the public SSH key

You can connect through SSH once you have an SSH key and have added it to the `ssh-agent`. The procedure is the same for all three services: copy your public key to the clipboard, then paste it into the service's SSH-keys settings.

`xclip` is a command-line tool that gives you access to the clipboard from the terminal. If it isn't already installed, install it for your distribution:

```shell title="Arch-based (Manjaro, Garuda)"
sudo pacman -Syu
sudo pacman -Syyu
sudo pacman -S xclip
```

```shell title="Debian-based (Ubuntu, Mint)"
sudo apt update
sudo apt upgrade
sudo apt install xclip
```

```shell title="Red Hat-based (RHEL, CentOS)"
sudo yum upgrade
sudo yum install xclip
```

```shell title="SUSE-based (openSUSE)"
sudo zypper upgrade
sudo zypper install xclip
```

```shell title="Fedora-based"
sudo dnf upgrade
sudo dnf install xclip
```

Using the `xclip` command, copy the contents of your public SSH key to the clipboard pick the tab that matches the key type you created:

```shell title="Copy the Ed25519 public key to the clipboard"
xclip -sel clip < ~/.ssh/id_ed25519.pub
```

```shell title="Copy the RSA public key to the clipboard"
xclip -sel clip < ~/.ssh/id_rsa.pub
```

  Only ever copy and paste the **public** key (the `.pub` file). The private key
  (`id_ed25519` or `id_rsa`, with no extension) must never be uploaded or shared
  with anyone.

Now add that public key to your account. Pick your service below:

Sign in to your GitHub account by going to github.com and entering your username and password. Click your profile photo in the upper-right corner of the page, then **Settings**:

![GitHub Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/github1.png)

Select **SSH and GPG keys** from the user settings sidebar, then select **New SSH key**. Put a descriptive label for the new key in the Title area (for example, your computer's name) and paste your public key into the Key field. Finally, click **Add SSH key**:

![GitHub Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/github2.png)

The key is now visible in the list of SSH keys linked to your account:

![GitHub Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/github3.png)

Sign in to your GitLab account by going to gitlab.com and entering your username and password. Click your profile photo in the upper-right corner of the page, then **Settings**:

![GitLab Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/gitlab1.png)

Click **SSH Keys** in the User Settings sidebar. In the Key area, paste your public key. Fill in the Title field with a descriptive term (for example, the name of your computer). Finally, click **Add key**:

![GitLab Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/gitlab2.png)

The key is now visible in the list of SSH keys linked to your account:

![GitLab Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/gitlab3.png)

Log in to your Bitbucket account by going to bitbucket.org and entering your username and password. Click your profile photo in the lower-left corner of the website, then **Bitbucket settings**:

![Bitbucket Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/bitbucket1.png)

SSH keys may be found in the Settings sidebar's **Security** section. After that, select **Add key**. Fill the Description box with a descriptive label for the new key (such as your computer's name), then paste your public key into the Key field. Finally, choose **Add key**:

![Bitbucket Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/bitbucket2.png)

The key has now been added to your account's list of SSH keys:

![Bitbucket Settings](/assets/blog/0001-git-ssh-keys-for-github-gitlab-and-bitbucket-on-linux/bitbucket3.png)

## Test connecting via SSH

Before you start using SSH with Git, all three services let you check that the connection works.

Once you've added your SSH key to your GitHub account, open the terminal and type:

```shell title="Test connecting via SSH"
ssh -T git@github.com
```

If you're connecting to GitHub over SSH for the first time, the SSH client will ask if you trust the GitHub server's public key:

```shell title="Output"
The authenticity of host 'github.com (140.82.113.4)' can't be established.
RSA key fingerprint is SHA256:a5d6c20b1790b4c144b9d26c9b201bbee3797aa010f2701c09c1b3a6262d2c02.
Are you sure you want to continue connecting (yes/no)?
```

Type `yes` and press Enter. GitHub is added to the list of trustworthy hosts in the SSH client, and you won't be asked about its public key again:

```shell title="Output"
Warning: Permanently added 'github.com,140.82.113.4' (RSA) to the list of known hosts.
```

GitHub only allows this SSH connection for testing, not shell access, so it confirms you're authenticated and then closes the connection:

```shell title="Output"
Hi YOUR_USER_NAME! You've successfully authenticated, but GitHub does not provide shell access.
```

The entire interaction should look something like this:

```shell title="Output"
ssh -T git@github.com

The authenticity of host 'github.com (140.82.113.4)' can't be established.
RSA key fingerprint is SHA256:a5d6c20b1790b4c144b9d26c9b201bbee3797aa010f2701c09c1b3a6262d2c02.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,140.82.113.4' (RSA) to the list of known hosts.
Hi your_user_name! You've successfully authenticated, but GitHub does not provide shell access.
YOUR_USER_NAME@YOUR_HOST_NAME:~>
```

Test passed you're ready to use SSH with GitHub.

Once you've added your SSH key to your GitLab account, the test is pretty similar:

```shell title="Test connecting via SSH"
ssh -T git@gitlab.com

The authenticity of host 'gitlab.com (35.231.145.151)' can't be established.
ECDSA key fingerprint is SHA256:4ac7a7fd4296d5e6267c9188346375ff78f6097a802e83c0feaf25277c9e70cc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitlab.com,35.231.145.151' (ECDSA) to the list of known hosts.
Welcome to GitLab, @YOUR_USER_NAME!
```

Test passed you're ready to use SSH with GitLab.

Once you've added your SSH key to your Bitbucket account, the test is pretty similar:

```shell title="Test connecting via SSH" error-preview
ssh -T git@bitbucket.org

The authenticity of host 'bitbucket.org (104.192.143.1)' can't be established.
RSA key fingerprint is SHA256:fb7d37d5497c43f73325e0a98638cac8dda3b01a8c31f4ee11e2e953c19e0252.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'bitbucket.org,104.192.143.1' (RSA) to the list of known hosts.
logged in as YOUR_USER_NAME.

You can use git or hg to connect to Bitbucket. Shell access is disabled.
```

Test passed you're ready to use SSH with Bitbucket.

## Frequently Asked Questions

> **Should I set a passphrase on my SSH key?**

Yes. A passphrase encrypts the private key on disk, so if the file is ever stolen it's useless without the passphrase. Pair it with the `ssh-agent` so you only type it once per login session rather than on every Git command.

> **RSA or Ed25519 which key type should I use?**

Use `ed25519`. The keys are smaller and faster than RSA with comparable security, and it's what GitHub, GitLab, and Bitbucket recommend. Generate one with `ssh-keygen -t ed25519 -C 'YOUR_EMAIL@EXAMPLE.COM'`. Reach for `rsa -b 4096` only when you need to connect to an older server that doesn't speak Ed25519.

> **Can I use the same key for GitHub, GitLab, and Bitbucket?**

Yes. The same **public** key can be added to as many accounts and services as you like there's no need for a separate key per provider. Just paste `~/.ssh/id_ed25519.pub` (or `id_rsa.pub`) into each service's SSH-keys settings.

> **I get 'Permission denied (publickey)' what's wrong?**

Usually one of: the key wasn't added to the `ssh-agent` (`ssh-add ~/.ssh/id_ed25519`), the public key wasn't added to the service, or the wrong key path is being used. Run `ssh -vT git@github.com` to see which key the client offers, and confirm `~/.ssh` permissions are `700` and the private key is `600`.

> **Why is my passphrase requested every time?**

The `ssh-agent` isn't running or isn't persisting between sessions. Start it with `eval "$(ssh-agent -s)"` and add the key with `ssh-add`. To make it stick automatically, add `AddKeysToAgent yes` (and optionally `UseKeychain yes` on macOS) under your host in `~/.ssh/config`.

---

## References

- [GitHub Docs: Generating a new SSH key and adding it to the ssh-agent](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
- [GitHub Docs: Adding a new SSH key to your GitHub account](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
- [GitHub Docs: Working with SSH key passphrases](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/working-with-ssh-key-passphrases)
- [GitLab Docs: Use SSH keys to communicate with GitLab](https://docs.gitlab.com/ee/user/ssh.html)
- [Bitbucket Docs: Set up an SSH key](https://support.atlassian.com/bitbucket-cloud/docs/set-up-an-ssh-key/)
- [OpenSSH Official Website](https://www.openssh.com/)
- [`ssh-keygen` man page](https://man.openbsd.org/ssh-keygen.1)
- [`ssh-agent` man page](https://man.openbsd.org/ssh-agent.1)
- [`ssh-add` man page](https://man.openbsd.org/ssh-add.1)
- [ArchWiki: SSH keys](https://wiki.archlinux.org/title/SSH_keys)
- [DigitalOcean: How To Set Up SSH Keys](https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-2)
- [Git SCM Book: Git on the Server - Generating Your SSH Public Key](https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key)
- [xclip man page (or alternative like xsel)](https://linux.die.net/man/1/xclip)
- [SSH (Secure Shell) Protocol Overview](https://www.ssh.com/academy/ssh)
