Add an SSH Key to GitHub (Mac, Windows, Linux)

Suman SharmaSuman Sharma

SSH lets you push and pull without typing a token every time. It takes about five minutes.

On Windows, run these commands in Git Bash (installed with Git for Windows) or PowerShell. The commands are the same unless noted.

Step 1: Check for an existing key

ls -al ~/.ssh

If you see id_ed25519 and id_ed25519.pub, you already have a key. Skip to Step 3.

Step 2: Generate a new key

ssh-keygen -t ed25519 -C "you@example.com"
  • Press Enter to accept the default location (~/.ssh/id_ed25519).
  • Set a passphrase. It protects the key if your laptop is stolen, and the agent means you only type it once.

This creates two files:

FileWhat it isShare it?
~/.ssh/id_ed25519private keyNever
~/.ssh/id_ed25519.pubpublic keyYes, this goes to GitHub

Step 3: Add the key to the SSH agent

macOS:

eval "$(ssh-agent -s)"

Create or edit ~/.ssh/config:

Host github.com AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/id_ed25519

Then:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Keychain now remembers the passphrase across restarts.

Linux:

eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519

Windows (PowerShell as admin, once):

Get-Service ssh-agent | Set-Service -StartupType Automatic Start-Service ssh-agent ssh-add $env:USERPROFILE\.ssh\id_ed25519

Step 4: Copy the public key

pbcopy < ~/.ssh/id_ed25519.pub # macOS cat ~/.ssh/id_ed25519.pub # Linux: copy the output Get-Content ~/.ssh/id_ed25519.pub | Set-Clipboard # Windows PowerShell

It's one line starting with ssh-ed25519.

Step 5: Add it to GitHub

  1. GitHub → your avatar → Settings → SSH and GPG keys.
  2. New SSH key.
  3. Title: something that names the machine ("MacBook 2026").
  4. Key type: Authentication Key.
  5. Paste, save.

Step 6: Test

ssh -T git@github.com

The first time, type yes to trust GitHub's host key. You should see:

Hi your-username! You've successfully authenticated, but GitHub does not provide shell access.

Step 7: Use SSH remotes

Clone with the SSH URL (git@github.com:user/repo.git), or switch an existing repo from HTTPS:

git remote -v git remote set-url origin git@github.com:your-username/your-repo.git

Fixing "Permission denied (publickey)"

Run the test verbosely to see which keys are being offered:

ssh -vT git@github.com

Then check these in order:

  1. Is the key loaded? ssh-add -l. If it says "no identities", run ssh-add again.
  2. Did you paste the .pub file into GitHub, and into the right account?
  3. Is the remote SSH? git remote -v should show git@github.com:..., not https://.
  4. Permissions. SSH ignores keys other users can read:
chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub

See chmod 755 vs 644 for what those numbers mean.

  1. Port 22 blocked on office or campus Wi-Fi? GitHub accepts SSH on port 443:
Host github.com Hostname ssh.github.com Port 443 User git

Two GitHub accounts on one machine

Make a second key and give each account a host alias in ~/.ssh/config:

Host github-work HostName github.com User git IdentityFile ~/.ssh/id_ed25519_work IdentitiesOnly yes

Then clone work repos with the alias:

git clone git@github-work:company/repo.git

Bonus: sign commits with the same key

git config --global gpg.format ssh git config --global user.signingkey ~/.ssh/id_ed25519.pub git config --global commit.gpgsign true

Add the same public key in GitHub again, this time as a Signing Key, and your commits show as "Verified."

Frequently asked questions

Which SSH key type should I use for GitHub?

Ed25519. It's short, fast and secure, and GitHub recommends it. Use RSA with 4096 bits only for very old systems that don't support Ed25519.

Why do I get 'Permission denied (publickey)'?

GitHub didn't receive a key it recognises. Usually the key isn't loaded in the SSH agent, the public key wasn't added to your GitHub account, or the repo remote is using a different account.

Is it safe to share my public key?

Yes. The .pub file is meant to be shared. Never share the file without .pub, which is your private key.

Contact

Get in Touch

Want to call me? book a call and I'll respond in the available time slot. I will ignore all soliciting.