GitSSH Keys for GitHub

SSH Keys for GitHub

An SSH key is a pair of files — a private key on your laptop and a matching public key uploaded to GitHub — that authenticate you to the server. Once it is set up, every clone, fetch, and push happens silently with no password prompts. It is more secure than HTTPS-with-password, faster to use day-to-day, and the standard way professionals work with GitHub.

Why SSH (and not HTTPS)
  • No password retypes — the agent handles auth automatically.

  • No risk of password leaking to phishing sites that imitate GitHub.

  • Better cryptography (Ed25519) than reusable passwords.

  • Tokens (PATs) can be revoked, but they expire and you must rotate them. SSH keys you can keep for years.

  • Works the same against GitHub, GitLab, Bitbucket — one key, many hosts.

Step 1 — Generate the key

Modern Ed25519 keypair

Bash
ssh-keygen -t ed25519 -C "you@example.com"

# Press Enter to accept the default file path (~/.ssh/id_ed25519)
# Type a passphrase (recommended) — you'll only enter it once per
# boot if you use the ssh-agent.

Older systems that don't support Ed25519

Bash
ssh-keygen -t rsa -b 4096 -C "you@example.com"

Use Ed25519 unless you have a hard reason not to — it is shorter, faster, and just as secure as a 4096-bit RSA key.

Where the keys live

Two files in ~/.ssh

Text
~/.ssh/id_ed25519       # PRIVATE key — never share, never copy
~/.ssh/id_ed25519.pub   # PUBLIC key  — paste this into GitHub
Step 2 — Add the public key to GitHub

Copy the public key to your clipboard

Bash
# macOS
pbcopy < ~/.ssh/id_ed25519.pub

# Linux (X11)
xclip -sel clip < ~/.ssh/id_ed25519.pub

# Linux (Wayland)
wl-copy < ~/.ssh/id_ed25519.pub

# Windows (Git Bash)
clip < ~/.ssh/id_ed25519.pub

# Or just print and copy manually:
cat ~/.ssh/id_ed25519.pub
  • Go to github.com → Settings → SSH and GPG keys → New SSH key.

  • Title: something memorable like personal-laptop-2026.

  • Key type: Authentication Key.

  • Paste the public key (the whole line starting with ssh-ed25519).

  • Click Add SSH key. You may be prompted for your password and 2FA code.

Step 3 — Test the connection

A successful test looks like this

Bash
ssh -T git@github.com

# The authenticity of host 'github.com (140.82.121.3)' can't be established.
# ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
# Are you sure you want to continue connecting (yes/no)? yes

# Hi jsmith! You've successfully authenticated, but GitHub does not
# provide shell access.

That "Hi jsmith!" line means you are good. The "no shell access" bit is normal — SSH on GitHub is only for Git, not interactive logins.

Step 4 — Start the ssh-agent

The agent remembers your unlocked private key so you only type the passphrase once per session. Setup varies by OS.

macOS — agent runs automatically; add to keychain

Bash
# In ~/.ssh/config add:
Host github.com
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

# Then add the key once:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Linux — start the agent and add the key

Bash
eval "$(ssh-agent -s)"     # start agent in this shell
ssh-add ~/.ssh/id_ed25519  # type passphrase once

# Make persistent: add 'eval $(ssh-agent -s)' to ~/.bashrc or use
# the keychain package: 'eval $(keychain --eval id_ed25519)'

Windows — Git Bash with OpenSSH

Bash
# In an admin PowerShell, enable the ssh-agent service:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent

# Then in Git Bash:
ssh-add ~/.ssh/id_ed25519
Switching an existing repo from HTTPS to SSH

Change the remote URL

Bash
git remote -v
# origin  https://github.com/you/repo.git (fetch)
# origin  https://github.com/you/repo.git (push)

git remote set-url origin git@github.com:you/repo.git

git remote -v
# origin  git@github.com:you/repo.git (fetch)
# origin  git@github.com:you/repo.git (push)
Multiple GitHub accounts (work + personal)

Need a personal GitHub and a work GitHub on the same laptop? Generate a separate key for each, then teach SSH which key to use via ~/.ssh/config.

Generate a second key

Bash
ssh-keygen -t ed25519 -C "you@work.com" -f ~/.ssh/id_ed25519_work
# Upload the .pub file to your work GitHub account

~/.ssh/config

Text
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes

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

Clone using the alias

Bash
# Personal repos:
git clone git@github.com:you/personal-app.git

# Work repos — note the host alias:
git clone git@github-work:acme/work-app.git
Rotating and listing your keys

Audit and rotate

Bash
# List keys currently loaded in the agent
ssh-add -l

# Remove all keys from the agent
ssh-add -D

# Replace an old key:
ssh-keygen -t ed25519 -C "you@example.com" -f ~/.ssh/id_ed25519_new
# Upload new .pub to GitHub, then delete the old one in Settings.
Common errors
  • Permission denied (publickey) — the server did not accept any of your keys. Check ssh -vT git@github.com to see which keys were offered; verify the matching public key is uploaded.

  • Host key verification failed — the remote host key changed. Either GitHub rotated its host key (rare, announced) or you are being MITM-ed. Update ~/.ssh/known_hosts only after verifying via the official fingerprints page.

  • Bad owner or permissions on ~/.ssh/config — chmod the file: chmod 600 ~/.ssh/config and chmod 700 ~/.ssh.

  • Could not open a connection to your authentication agent — the agent is not running. Run eval "$(ssh-agent -s)" first.

  • Repository not found — wrong account or wrong key being used. Add IdentitiesOnly yes to force a specific key.

Verifying with verbose mode

See exactly which key SSH offers

Bash
ssh -vT git@github.com 2>&1 | grep -i "offering\|identity"
# debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 ...
Warning
Never share your private key. Never paste it into chat, email, a screenshot, or commit it to a repo. If you suspect the private key has leaked, treat it as compromised — generate a fresh keypair, upload the new public key, and delete the old one from every host (GitHub, GitLab, your servers).
One key per device is the right default
Generate a new keypair for every laptop, desktop, and CI runner. That way if one device is lost or stolen you only revoke that key, not your entire identity. Naming the keys after the machine (`id_ed25519_personal-laptop`) makes audits much easier.
Tip
Set `git config --global url."git@github.com:".insteadOf "https://github.com/"` so that even when a tool hands you an HTTPS URL, Git rewrites it to SSH automatically. No more password prompts on weird clones.