Reconnect to GitHub with SSH
Set up SSH key authentication to push and pull from GitHub without credentials.
Introduction
30 Second Summary
Imagine having to type your password every single time you open your front door. That is what pushing code to GitHub feels like without proper authentication set up.
In this project, you will generate an SSH key, link it to your GitHub account, and configure Windows to remember your passphrase automatically. By the end, you will push code to GitHub without ever being asked for credentials.
What You'll Build
A fully configured SSH authentication setup that replaces the old password-based Git workflow with seamless, secure key-based authentication.
By the end of this project, you'll have:
- An Ed25519 SSH key pair generated on your local machine.
- Your public key registered in your GitHub account settings.
- A Windows ssh-agent that auto-starts and remembers your passphrase so you only type it once per session.
- A test repository pushed to GitHub over SSH, proving the full workflow end-to-end.
- Secret Mission: Set up a Personal Access Token as an HTTPS fallback for environments where SSH is blocked.
Are there any prerequisites?
You need Git installed on Windows and a GitHub account. This project walks you through everything else from scratch.
Generate Your SSH Key
To push and pull from GitHub without entering credentials, you need an SSH key pair. A key pair consists of a private key that stays on your machine and a public key that goes to GitHub.
When you push code, GitHub checks that your private key matches the public key on file. In this step, you will generate a fresh Ed25519 key pair. Ed25519 is the algorithm GitHub recommends for new keys because it is fast and secure.
In this step, get ready to:
- Check for existing SSH keys on your machine.
- Generate a new Ed25519 SSH key pair.
- Verify that both key files were created.
Check for existing SSH keys
Your machine might already have SSH keys from a previous setup. Let's check before generating new ones.
- Press the Windows key to open your search bar.
- Type Git Bash and press Enter to open it.
- Check for existing SSH keys by running this command:
ls ~/.ssh
What might you see?
If you see files like id_rsa.pub or id_ed25519.pub, you already have keys from a previous setup.
If you see an error saying No such file or directory, that means you have no SSH keys yet. Either way, we will generate a fresh Ed25519 key in the next substep.
Generate a new Ed25519 key
The ssh-keygen command creates both your private key and public key files in one step. You will need the email address associated with your GitHub account.
- Generate your SSH key pair by running this command in Git Bash, replacing the email with the email on your GitHub account:
ssh-keygen -t ed25519 -C "[[GITHUB_EMAIL="your_email@example.com"]]"
What does this command do?
- -t ed25519 tells ssh-keygen to use the Ed25519 algorithm, which is GitHub's recommended key type.
- -C "your_email@example.com" attaches your email as a label on the key so you can identify it later.
The command asks for three inputs. Here is how to respond to each one:
- When you see "Enter file in which to save the key", press Enter to accept the default location (/c/Users/YOU/.ssh/id_ed25519).
- When you see "Enter passphrase", type a secure passphrase. You will only need to enter this once per session after we configure the ssh-agent in the next step.
- When you see "Enter same passphrase again", re-type the same passphrase to confirm.
You should see output confirming "Your identification has been saved" and "Your public key has been saved."
Seeing a "permission denied" error?
Make sure you are running the command in Git Bash, not in PowerShell or Command Prompt. Git Bash creates the ~/.ssh folder automatically if it does not exist.
If you accidentally typed the wrong file path, delete the files and run the command again. Help me troubleshoot my ssh-keygen error.
Verify the key files were created
- Confirm that both key files exist by running:
ls ~/.ssh/id_ed25519*
You should see two files listed: id_ed25519 and id_ed25519.pub.
What are these two files?
- id_ed25519 is your private key. Never share this file with anyone. It stays on your machine.
- id_ed25519.pub is your public key. This is the file you will upload to GitHub in a later step.
Don't see both files?
If ls returns No such file or directory, the key generation did not complete successfully. Go back and run the ssh-keygen command again.
Double check that you pressed Enter to accept the default file location when prompted. Help me figure out why my SSH key files are missing.
Your SSH key pair is ready. Next up, you will configure the Windows ssh-agent so it remembers your passphrase and you only need to type it once.
Configure the Windows SSH Agent
Your SSH key pair is ready. You have a private key and a public key sitting in your ~/.ssh folder. But right now, you would need to type your passphrase every single time you push or pull from GitHub.
The ssh-agent is a background service that caches your passphrase after you enter it once. Once it is running and your key is loaded, every Git operation happens without a credential prompt.
In this step, get ready to:
- Start the Windows ssh-agent service.
- Add your private key to the agent.
- Configure Git to use the correct SSH client.
Start the ssh-agent service
The ssh-agent service is disabled by default on Windows. You need administrator privileges to enable and start it.
- Press the Windows key to open the Start menu.
- Type PowerShell in the search bar.
- Right-click Windows PowerShell in the search results.
- Select Run as administrator.
- If a User Account Control prompt appears, click Yes to allow it.
How do I know it's running as Administrator?
The window title bar shows "Administrator: Windows PowerShell" when elevated. If it just says "Windows PowerShell" without the Administrator prefix, close it and try the steps above again.
- Enable and start the ssh-agent service by running these commands in your Administrator PowerShell window:
Get-Service -Name ssh-agent | Set-Service -StartupType Manual
Start-Service ssh-agent
What do these commands do?
The first command tells Windows to allow the ssh-agent service to start on demand (it is disabled by default). The second command starts the service immediately so it is ready to hold your keys.
- Confirm the service is running by running:
Get-Service ssh-agent
You should see a status of Running in the output.
Seeing 'Access is denied'?
This means your PowerShell window is not elevated. Close it and reopen PowerShell using the right-click method above, making sure to select Run as administrator.
help me fix the ssh-agent access denied error on Windows
Add your key to the agent
Now that the service is running, you can load your private key into it. This step only requires a regular (non-admin) terminal.
- Switch back to your Git Bash window from earlier.
- Add your private key to the ssh-agent by running this command:
ssh-add ~/.ssh/id_ed25519
What happens when you run this?
The agent asks for your passphrase one time. After you enter it, the agent caches the passphrase in memory. You will not need to type it again for the rest of your session.
- Enter your passphrase when prompted.
You should see a confirmation message that says "Identity added" along with the path to your key file.
Seeing 'Could not open a connection to your authentication agent'?
This usually means Git Bash is using its own bundled SSH client instead of the Windows system one. The next substep fixes this exact issue. Continue to the next heading and come back to retry ssh-add after applying the fix.
help me fix the ssh-agent connection error in Git Bash on Windows
Fix potential SSH agent conflicts
Git for Windows bundles its own SSH client that cannot communicate with the Windows native ssh-agent service. You need to tell Git to use the Windows system SSH instead.
- In Git Bash, configure Git to use the Windows system SSH client by running this command:
git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"
Why is this necessary?
Git for Windows ships with an MSYS2-based ssh.exe that runs in its own environment. This bundled client cannot talk to the Windows ssh-agent service where your key is cached. Pointing Git at the system's C:/Windows/System32/OpenSSH/ssh.exe ensures every Git operation uses the same agent that holds your passphrase.
- Verify your key is loaded by running:
ssh-add -l
You should see your key's fingerprint listed (a line starting with a number like 256 followed by SHA256: and a hash string).
Seeing 'The agent has no identities'?
This means the key was not successfully added in the previous substep. Now that the SSH client conflict is fixed, retry adding your key:
ssh-add ~/.ssh/id_ed25519
Enter your passphrase when prompted, then run ssh-add -l again to confirm.
help me get ssh-add working with the Windows ssh-agent
Your ssh-agent is running and your key is loaded. Next up, you will add your public key to GitHub so it recognizes your machine.
Link Your Key to GitHub
Your SSH key exists on your machine and the agent is caching your passphrase. The missing piece is telling GitHub which public key belongs to you.
In this step, you will copy your public key, paste it into your GitHub account settings, and test the connection. Once GitHub recognizes your key, every push and pull will authenticate silently.
In this step, get ready to:
- Copy your public key to the clipboard.
- Add the key to your GitHub account.
- Test the SSH connection to confirm GitHub recognizes you.
Copy your public key
Your public key is the safe half of the pair. It goes to GitHub so the service can verify that pushes come from the matching private key on your machine.
- In Git Bash, copy your public key to the clipboard by running this command:
cat ~/.ssh/id_ed25519.pub | clip
- To confirm it worked, open Notepad and press Ctrl+V. You should see a single line starting with ssh-ed25519 followed by a long string and your email.
Getting a ParseError?
If you run this command in PowerShell instead of Git Bash, you may see an error about the < operator being reserved. Switch to Git Bash for this command, or use Get-Content in PowerShell instead:
Get-Content ~/.ssh/id_ed25519.pub | Set-Clipboard
Help me copy my SSH public key to the clipboard on Windows.
Add the key to GitHub
Now you will paste this public key into your GitHub account so it knows which key to trust for your pushes.
- Go to github.com in your browser.
- Click your profile picture in the upper-right corner.
- Click Settings.
- In the Access section of the left sidebar, click SSH and GPG keys.
- Click New SSH key.
- In the Title field, type My Windows Laptop.
- Leave the Key type set to Authentication.
- Click inside the Key field and press Ctrl+V to paste your public key.
- Click Add SSH key.
- Confirm access to your account if prompted (GitHub may ask for your password).
Why does GitHub need only the public key?
SSH authentication works like a lock-and-key system. Your public key is the lock. You give it to GitHub. Your private key is the key that opens it. It never leaves your machine.
When you push code, GitHub challenges your machine with a puzzle only your private key can solve. If the answer checks out, you are in.
Test the connection
With your key registered, you can verify that GitHub accepts it. This test does not create any repositories. It simply confirms that the authentication handshake works.
- In Git Bash, test the SSH connection by running:
ssh -T git@github.com
What happens the first time you connect?
SSH will display a warning asking if you trust this host. It shows a fingerprint for github.com. Verify it matches GitHub's published ED25519 fingerprint:
SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU
If it matches, type yes and press Enter. This saves the fingerprint to your ~/.ssh/known_hosts file so you will not be asked again.
- Type yes when prompted about the host's authenticity.
- You should see a message that says: Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access. (where USERNAME is your GitHub username).
Not seeing the success message?
If you see Permission denied (publickey), your key is not reaching GitHub. Check that:
- Your key is loaded in the agent. Run ssh-add -l and confirm your fingerprint appears.
- You pasted the full .pub file contents into GitHub. Go back to SSH and GPG keys in Settings and verify the key is listed.
- Git is using the Windows SSH client. Run git config --global core.sshCommand and confirm it shows the C:/Windows/System32/OpenSSH/ssh.exe path.
Help me troubleshoot my SSH connection to GitHub.
GitHub now trusts your machine. Next up, you will put this to the test by creating a repository and pushing code over SSH with zero credential prompts.
Push a Repository Over SSH
In the previous step, you linked your public key to GitHub and confirmed the connection works. Your machine and GitHub can now recognize each other.
Now it is time to put that SSH connection to real use. In this step, you will create a repository and push it to GitHub without ever being prompted for credentials.
In this step, get ready to:
- Create a test repository on GitHub.
- Push a local project to GitHub over SSH with zero credential prompts.
- Learn how to switch existing repos from HTTPS to SSH URLs.
Create a test repository on GitHub
You need an empty repository on GitHub to push to. Creating it without a README means GitHub will not initialize any commits, so your local project becomes the single source of truth.
- On GitHub.com, click the + icon in the top-right corner.
- Select New repository.
- In the Repository name field, type ssh-test.
- Leave the repository set to Public.
- Do NOT check the Add a README file box. Leave it unchecked.
- Click Create repository.
GitHub shows a Quick Setup page with instructions for pushing an existing or new repository. You will use these SSH URLs in the next substep.
Why no README?
Initializing a README on GitHub creates a first commit on the remote. If you also create a first commit locally, the two histories will conflict and the push will be rejected. Starting empty avoids that problem entirely.
Create and push a local repository
With the empty GitHub repository waiting, you can now create a local project, make a commit, and push it over SSH.
- In Git Bash, create a new project folder and initialize a Git repository by running these commands:
mkdir ~/ssh-test
cd ~/ssh-test
git init
echo "# SSH Test" > README.md
git add .
git commit -m "Initial commit - SSH auth works!"
What do these commands do?
- mkdir ~/ssh-test creates a new folder called ssh-test in your home directory.
- git init turns that folder into a Git repository by adding a hidden .git folder.
- echo "# SSH Test" > README.md creates a simple README file with a heading.
- git add . stages all files, and git commit saves them as your first snapshot.
- Now connect your local repo to GitHub and push by running these commands:
git branch -M main
git remote add origin git@github.com:[[YOUR_USERNAME="your GitHub username"]]/ssh-test.git
git push -u origin main
What do these commands do?
- git branch -M main renames your default branch to main (GitHub's expected default name).
- git remote add origin tells Git where your GitHub repository lives. Notice the URL starts with git@github.com: instead of https://github.com/. That is the SSH format.
- git push -u origin main uploads your commit to GitHub. The -u flag sets origin/main as the default upstream so future pushes just need git push.
- The push should complete without any username or password prompt. Refresh your repository page on GitHub.com.
- You should see your README.md file with the heading "# SSH Test" displayed on the repository page.
Still being asked for credentials?
- Check your remote URL by running git remote -v. If it shows https:// instead of git@github.com:, you accidentally used the HTTPS URL.
- Verify your key is loaded by running ssh-add -l. If it says "The agent has no identities," re-add your key with ssh-add.
- Make sure you are using the Windows system SSH (git config --global core.sshCommand should show C:/Windows/System32/OpenSSH/ssh.exe).
Why is my SSH push still asking for credentials?
Switch an existing repo from HTTPS to SSH
If you have older repositories on your machine that still use HTTPS URLs, you can switch them to SSH so they also benefit from credential-free pushes.
- Navigate to any existing local repository and check its current remote URLs by running:
cd [[REPO_PATH="path/to/your/existing/repo"]]
git remote -v
If the output shows URLs starting with https://github.com/, this repo is using HTTPS.
- Switch the remote URL to SSH format by running:
git remote set-url origin git@github.com:[[YOUR_USERNAME="your GitHub username"]]/[[REPOSITORY="your repository name"]].git
- Confirm the change took effect by running git remote -v again. Both fetch and push URLs should now show git@github.com:.
What does git remote set-url do?
This command changes the URL that Git uses when communicating with the remote server. It does not move or copy any code. All your commits, branches, and history stay exactly the same. Only the transport protocol changes from HTTPS to SSH.
Repeat for all old repos
You can run this command in every local repository that still uses HTTPS. Once switched, they will all push and pull without credential prompts.
Secret mission
Set Up a Personal Access Token (HTTPS Fallback)
Some corporate networks block SSH traffic on port 22. When that happens, you need a backup plan. In this mission, you'll set up a Personal Access Token for HTTPS authentication as a reliable fallback.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally and on free GitHub features, so there are no ongoing costs.
Resources you used:
- Ed25519 SSH key pair at ~/.ssh/id_ed25519 and ~/.ssh/id_ed25519.pub.
- SSH key registered on your GitHub account (titled "My Windows Laptop").
- GitHub repository ssh-test.
- Local repository at ~/ssh-test.
- Fine-grained Personal Access Token on GitHub (named "HTTPS fallback").
- Git global config change (core.sshCommand setting).
- GitHub host fingerprint in ~/.ssh/known_hosts.
Keep everything running
No action needed. Choose this if you plan to keep using SSH authentication with GitHub going forward.
- Your SSH key pair stays in ~/.ssh/ and authenticates every push and pull automatically.
- The Windows ssh-agent continues caching your passphrase each session.
- Your Personal Access Token remains available as an HTTPS fallback if you ever hit a network that blocks port 22.
- The ssh-test repository stays on GitHub as proof your setup works.
Pause - I'll come back to this later
Keep the SSH authentication setup (it is useful for all future Git work) but remove the test artifacts you created just for learning.
- Delete the ssh-test repository on GitHub. Go to the repository page, click Settings, scroll to the bottom, and click Delete this repository.
- Remove the local test folder by running this in Git Bash:
rm -rf ~/ssh-test
- Optionally revoke your Personal Access Token if you do not need the HTTPS fallback right now. Go to Settings > Developer settings > Personal access tokens > Fine-grained tokens, find "HTTPS fallback," and click Delete.
- Leave your SSH key pair and GitHub SSH key entry in place. These continue working for all your repositories.
Delete - I don't want to use this again
Remove all project resources completely. After this, you will need to generate a new SSH key if you want SSH authentication again in the future.
Remove the local SSH key files and known_hosts entry by running these commands in Git Bash:
rm -f ~/.ssh/id_ed25519
rm -f ~/.ssh/id_ed25519.pub
rm -f ~/.ssh/known_hosts
Remove the local test repository:
rm -rf ~/ssh-test
Unset the global Git SSH config:
git config --global --unset core.sshCommand
- Remove the key from the ssh-agent by running ssh-add -d c:/Users/YOU/.ssh/id_ed25519 in PowerShell (replace YOU with your Windows username). If the key file is already deleted, the agent drops it automatically on next restart.
- Delete the SSH key from GitHub. Go to your profile picture > Settings > SSH and GPG keys. Find the key titled "My Windows Laptop" and click Delete.
- Delete the ssh-test repository on GitHub. Go to the repository page, click Settings, scroll to the bottom, and click Delete this repository.
- Delete the Personal Access Token. Go to Settings > Developer settings > Personal access tokens > Fine-grained tokens, find "HTTPS fallback," and click Delete.
Nice Work!
Nice Work!
You just set up SSH authentication for GitHub from scratch. No more credential prompts, no more expired passwords, just seamless pushes and pulls every time you work with your code.
You've learned how to:
- Generated an Ed25519 SSH key pair and configured the Windows ssh-agent to cache your passphrase automatically.
- Linked your public key to GitHub and verified the SSH connection end-to-end.
- Pushed a repository to GitHub over SSH with zero credential prompts and learned how to switch existing repos from HTTPS to SSH URLs.
- Secret Mission: Created a fine-grained Personal Access Token as an HTTPS fallback for restricted networks that block SSH.
Ready to quiz yourself?