SSH Keys for GitHub and GitLab: Generate, Add, and Fix Permission Denied
Create an ed25519 key, load it in ssh-agent, add the public key to your host, and debug common auth failures.
Security & secrets Intermediate 6 min read
·
SSH public-key auth exists so servers can verify you possess a private key without sending passwords over the network. You run ssh-keygen to create a key pair, ssh-add so the agent holds decrypted keys in memory, and ssh -T git@github.com to verify the remote accepts your public key—each step fails fast if misconfigured.
This complements Git basics when you use git@github.com:... URLs.
Generate a new key (ed25519)
Why ed25519: Shorter keys than RSA with modern security margins; GitHub and GitLab support it. The -C comment labels the key in the UI (usually your email).
ssh-keygen -t ed25519 -C "you@example.com" -f ~/.ssh/id_ed25519_git
Press Enter for an empty passphrase for convenience on a personal machine, or set a passphrase and use the agent below for fewer prompts.
Check: Two files appear: id_ed25519_git (private, never upload) and .pub (public).
Start ssh-agent and add the key
Why the agent: Passphrase-protected keys would otherwise prompt on every Git operation; the agent decrypts once per login session.
On macOS (recent): keys can be added to the agent automatically via Keychain when you first use them. On Linux:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_git
What eval ssh-agent does: Starts a background agent and prints shell exports; eval applies them to your current shell.
Check: ssh-add -l lists the key fingerprint.
Add the public key to GitHub or GitLab
Why paste only .pub: The public key is safe to share; the private file must never leave your machine.
Copy ~/.ssh/id_ed25519_git.pub into SSH keys in your account settings. Title it by machine (for example “work laptop”).
Test the connection
Why test with ssh -T: Git uses non-interactive SSH; a successful test proves authentication before your first git fetch.
ssh -T git@github.com
ssh -T git@gitlab.com
Check: GitHub greets you by username; GitLab shows a similar success message—not “Permission denied”.
Multiple keys and ~/.ssh/config
Why config matters: Multiple accounts (work vs personal) need different private keys per host alias; without IdentityFile, SSH tries default key names and may pick the wrong one.
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_git
Permission denied (publickey)
- Wrong remote URL (HTTPS instead of SSH, or vice versa).
- Key not loaded: run
ssh-add -land add the key. - Wrong public key pasted (ensure full single-line
ssh-ed25519 AAAA...).
Frequently asked questions
RSA or ed25519?
Prefer ed25519 for new keys; shorter keys, strong security. RSA 4096 remains acceptable where required by policy.
Is it safe to share the .pub file?
Yes—the public key is meant to be uploaded. Never share the private key without encryption.
known_hosts warnings?
First connect fingerprints the server. If a key changes unexpectedly, investigate possible spoofing before accepting.
Can I use SSH with Docker?
Mount keys read-only into build contexts carefully; prefer BuildKit secrets or CI SSH agents instead of baking keys into images.