Day 5 — GitHub SSH Login#
Goal: Set up SSH key authentication for GitHub so you can push and pull without entering passwords, and understand how public-key cryptography works in practice.
Why SSH?#
When you push code to GitHub, GitHub needs to verify you are who you say you are. There are two main ways:
| Method | How it works | Pros | Cons |
|---|---|---|---|
| HTTPS + Token | Password/token sent with each request | Easy setup | Must manage tokens |
| SSH Keys | Cryptographic key pair | No password needed, more secure | One-time setup is longer |
We recommend SSH — once set up, it just works. No tokens to manage or expire.
How SSH Keys Work#
SSH uses public-key cryptography. You generate a pair of keys:
┌──────────────────┐ ┌──────────────────┐
│ Private Key │ │ Public Key │
│ (SECRET!) │ │ (shareable) │
│ │ │ │
│ ~/.ssh/id_ed25519 │ ~/.ssh/id_ed25519.pub
│ │ │ │
│ Never share │ │ Upload to │
│ Never upload │ │ GitHub │
│ Keep on YOUR │ │ │
│ machine only │ │ Like a lock │
│ │ │ that only your │
│ Like a key │ │ key can open │
│ that opens the │ │ │
│ lock │ │ │
└──────────────────┘ └──────────────────┘Analogy: Think of it like a padlock:
- Public key = the padlock (you give copies to GitHub, GitLab, servers)
- Private key = the key to the padlock (you keep it secret, only on your machine)
When you push to GitHub:
- GitHub sends a challenge encrypted with your public key
- Your machine decrypts it with your private key
- GitHub verifies you are legit ✓
🧠 Knowledge Check#
Q1: What is the primary difference between a public key and a private key in SSH?
- A) The public key is for reading files, the private key is for writing files
- B) You upload the public key to GitHub, but you keep the private key secret on your local machine
- C) The private key is uploaded to GitHub, and you keep the public key
- D) They are identical; you just rename one of them
Answer
B — The public key acts like a padlock that you can give to anyone (like GitHub). The private key is the actual key that unlocks it, and it must never be shared.
Step-by-Step Setup#
Step 1: Check for Existing Keys#
ls -la ~/.ssh/
# If you see id_ed25519 and id_ed25519.pub, you already have keys!
# If ~/.ssh/ doesn't exist or is empty, proceed to Step 2.Step 2: Generate a New SSH Key#
ssh-keygen -t ed25519 -C "[email protected]"You’ll see:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/you/.ssh/id_ed25519): [press Enter]
Enter passphrase (empty for no passphrase): [press Enter or type a passphrase]
Enter same passphrase again: [press Enter]- File location: Press Enter to accept the default (
~/.ssh/id_ed25519) - Passphrase: Optional. Adds extra security — you’ll type it once per session
ed25519 vs RSA: We use
ed25519because it’s faster, more secure, and generates shorter keys than RSA. All modern systems support it.
Step 3: Verify Your Keys#
ls -la ~/.ssh/
# id_ed25519 ← private key (NEVER share this)
# id_ed25519.pub ← public key (this goes to GitHub)View your public key:
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGx... [email protected]Step 4: Start the SSH Agent#
The SSH agent remembers your key so you don’t have to type the passphrase every time:
eval "$(ssh-agent -s)"
# Agent pid 12345
ssh-add ~/.ssh/id_ed25519
# Identity added: /home/you/.ssh/id_ed25519 ([email protected])Step 5: Add Your Public Key to GitHub#
Copy your public key:
cat ~/.ssh/id_ed25519.pub # Copy the entire output (starts with "ssh-ed25519")Go to GitHub → Settings → SSH and GPG Keys → New SSH Key
- Direct link: github.com/settings/keys
Fill in:
- Title: Something descriptive like “My Ubuntu Laptop” or “WSL2 Desktop”
- Key type: Authentication
- Key: Paste your public key
Click Add SSH Key
Step 6: Test the Connection#
ssh -T [email protected]
# Hi username! You've been successfully authenticated, but GitHub
# does not provide shell access.If you see “Hi username!” — you’re connected! 🎉
Using SSH with Git#
Clone a repo via SSH#
# SSH URL format:
git clone [email protected]:username/repo-name.git
# HTTPS URL format (for comparison):
git clone https://github.com/username/repo-name.gitAlways use the SSH URL (starts with
[email protected]:) when you have SSH set up.
Switch an existing repo from HTTPS to SSH#
# Check current remote:
git remote -v
# origin https://github.com/username/repo.git (fetch)
# Switch to SSH:
git remote set-url origin [email protected]:username/repo.git
# Verify:
git remote -v
# origin [email protected]:username/repo.git (fetch)Push and pull (no password needed!)#
git push origin main # push changes — no password prompt
git pull origin main # pull changes — no password prompt🧠 Knowledge Check#
Q1: If you have an existing repository using HTTPS, what command changes it to use SSH?
- A)
git switch-to-ssh - B)
git remote set-url origin [email protected]:username/repo.git - C)
git clone ssh://github - D)
git config --global use-ssh true
Answer
B — git remote set-url updates the URL of the remote named origin to the new SSH URL.
Creating a GitHub Repo from the Terminal#
If you have the GitHub CLI (gh) installed:
# Install gh:
sudo apt install gh -y
# Or: see https://cli.github.com/
# Authenticate:
gh auth login
# Choose: GitHub.com → SSH → select your key
# Create a repo and push:
cd ~/my-project
gh repo create my-project --public --source=. --remote=origin --pushWithout gh, create the repo on GitHub’s website, then:
git remote add origin [email protected]:username/my-project.git
git branch -M main
git push -u origin mainTroubleshooting#
"Permission denied (publickey)" error
This means GitHub didn’t accept your SSH key. Check:
Is the SSH agent running?
ssh-add -l # Should show your key. If "no identities," run: ssh-add ~/.ssh/id_ed25519Is the correct public key on GitHub?
cat ~/.ssh/id_ed25519.pub # Compare with what's on github.com/settings/keysAre you using the SSH URL?
git remote -v # Should start with [email protected]:, NOT https://
"Could not resolve hostname github.com"
This is a DNS/network issue, not an SSH issue. Check your internet connection:
ping github.com"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED"
This usually means GitHub’s SSH key fingerprint changed (rare) or you connected to a different server. If you trust the connection:
ssh-keygen -R github.com
ssh -T [email protected] # accept the new fingerprint"Enter passphrase for key" keeps appearing
Your key has a passphrase, and the SSH agent isn’t remembering it. Fix:
# Start the agent:
eval "$(ssh-agent -s)"
# Add your key (will ask for passphrase once):
ssh-add ~/.ssh/id_ed25519
# Make it persistent across terminal sessions — add to ~/.bashrc:
echo 'eval "$(ssh-agent -s)" > /dev/null 2>&1' >> ~/.bashrc
echo 'ssh-add ~/.ssh/id_ed25519 2>/dev/null' >> ~/.bashrcHTTPS Alternative (if SSH doesn’t work)#
If you can’t use SSH (corporate firewall, etc.), use HTTPS with a Personal Access Token (PAT):
# 1. Create a PAT at: github.com/settings/tokens
# Select scopes: repo (full access)
# 2. Store it so Git remembers:
git config --global credential.helper store
# 3. Push — enter your token when asked for "password":
git push origin main
# Username: your-github-username
# Password: ghp_your_personal_access_tokenThe token is stored in
~/.git-credentials(plain text). SSH keys are more secure.
Q&A#
Q: What is the difference between SSH and HTTPS for Git?
A:
- SSH: Uses a key pair (public + private). Once set up, no password/token needed. More secure.
- HTTPS: Uses a username + token. Simpler to set up but you need to manage tokens.
Both work fine. SSH is preferred for daily development.
Q: Can I use the same SSH key for multiple GitHub accounts?
A: No — GitHub only allows each SSH key to be added to one account. If you have multiple accounts (personal + work), generate separate keys and configure SSH to use the right one for each:
# ~/.ssh/config
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_workQ: Is my private key ever sent to GitHub?
A: No, never. Your private key stays on your machine. Only the public key is uploaded to GitHub. During authentication, a mathematical challenge-response happens — your private key proves you own the public key without ever being transmitted.
Q: What is known_hosts?
A: ~/.ssh/known_hosts stores the fingerprints of servers you’ve connected to. The first time you connect to GitHub via SSH, you’ll see:
The authenticity of host 'github.com' can't be established.
ED25519 key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no)?Type yes. This saves GitHub’s fingerprint so SSH can verify it’s really GitHub next time (not an impersonator).
Exercises#
Exercise 1: Generate an SSH key
ssh-keygen -t ed25519 -C "[email protected]"
ls -la ~/.ssh/
cat ~/.ssh/id_ed25519.pubWhat should you see?
ls -la ~/.ssh/
# -rw------- 1 you you 411 Jan 15 10:00 id_ed25519 ← private (600 permissions)
# -rw-r--r-- 1 you you 97 Jan 15 10:00 id_ed25519.pub ← public
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGx... [email protected]Note: The private key has 600 permissions (only you can read it). This is required — SSH refuses to use keys with looser permissions.
Exercise 2: Add key to GitHub and test
- Copy your public key (
cat ~/.ssh/id_ed25519.pub) - Go to github.com/settings/keys → New SSH Key
- Paste and save
- Test:
ssh -T [email protected]Expected output
Hi your-username! You've been successfully authenticated, but GitHub
does not provide shell access.If you see this, SSH authentication is working. You can now push/pull without passwords.
Exercise 3: Push a repo via SSH
mkdir -p /tmp/ssh-test
cd /tmp/ssh-test
git init
echo "# SSH Test" > README.md
git add .
git commit -m "test: verify SSH push"
# Create repo on GitHub (requires gh CLI):
gh repo create ssh-test --public --source=. --remote=origin --push
# Or manually:
# 1. Create repo on github.com
# 2. git remote add origin [email protected]:your-username/ssh-test.git
# 3. git push -u origin mainHow to verify
Visit https://github.com/your-username/ssh-test — you should see your README.md. The push happened over SSH with no password prompt.
Clean up:
gh repo delete ssh-test --yes # delete the test repo
rm -rf /tmp/ssh-testExercise 4: Check and switch remote URL
# For any existing repo:
cd ~/your-existing-repo
git remote -vIf it shows https://, switch to SSH:
git remote set-url origin [email protected]:username/repo.git
git remote -v # should now show [email protected]:Why switch?
With HTTPS, you need a token/password for every push. With SSH, authentication is handled by your key pair automatically. One set-url command switches permanently for that repo.
Exercise 5: MCQ
Q1: Which file do you upload to GitHub?
- A)
~/.ssh/id_ed25519(private key) - B)
~/.ssh/id_ed25519.pub(public key) - C)
~/.ssh/known_hosts - D)
~/.ssh/config
Answer
B — You upload the public key (.pub file) to GitHub. The private key stays on your machine and should never be shared with anyone.
Q2: You run ssh -T [email protected] and get “Permission denied (publickey).” What is the most likely cause?
- A) GitHub is down
- B) Your public key isn’t added to GitHub, or the SSH agent doesn’t have your key
- C) You need to install Git
- D) Your internet connection is slow
Answer
B — Either:
- Your public key isn’t on GitHub (add it at github.com/settings/keys)
- The SSH agent doesn’t have your key loaded (run
ssh-add ~/.ssh/id_ed25519)
Q3: What is the SSH URL format for cloning a GitHub repo?
- A)
https://github.com/user/repo.git - B)
ssh://github.com/user/repo - C)
[email protected]:user/repo.git - D)
github.com:user/repo
Answer
C — The SSH URL for GitHub is [email protected]:user/repo.git. Note the colon : between github.com and user, not a slash.