View : 106

05/11/2026 10:00am

A student in a hoodie sits at a laptop, smiling and holding up a brass key that stands for an SSH Key replacing a password on GitHub, with cards showing the year GitHub dropped passwords, the recommended Ed25519 key type and the ssh -T test command

SSH Key for GitHub: Set It Up on Mac and Windows and Fix Permission denied (publickey)

#ssh key github

#add ssh key to github

#permission denied publickey

#ssh-keygen ed25519

#github ssh key setup

Picture this: you have just finished a project, you type git push with confidence, and Terminal asks for a username and password. You enter your GitHub password as usual and get back Password authentication is not supported for Git operations. Or, if you have already tried setting something up, you might see a different message: Permission denied (publickey).

Don't panic. Nothing is broken, and you are not doing anything stranger than anyone else. Today Superdev Academy will walk you through setting up an SSH Key so GitHub recognizes your machine, step by step on both Mac and Windows, and then fix Permission denied in the same article.

Why GitHub no longer accepts your password on git push

Because GitHub really did stop accepting account passwords for Git. GitHub announced on the GitHub Blog that beginning August 13, 2021, it would no longer accept account passwords when authenticating Git operations on GitHub.com. That covers Git on the command line and apps that use Git. GitHub Desktop was not affected.

The same announcement also notes that if your account has two-factor authentication enabled, you were already required to use a token or SSH. So if you turned on 2FA from the start and are only now hitting this problem, that makes sense: your password never worked for Git in the first place.

In short, the password you use to log in to the GitHub website cannot be used with git push. That leaves two main options: an HTTPS URL with a token, or an SSH URL with an SSH Key. This article takes the second route, because you set it up once and it keeps working. We compare the two near the end.

What is an SSH Key? How the public key and private key work

An SSH Key is a pair of files created together, used to prove that this machine really is you, without sending a password. The simplest way to picture it is a padlock and its key, made as a matching set.

  • Public key (the file ending in .pub): the padlock. You can leave it with GitHub, and it does not matter who sees it, because it cannot open anything.

  • Private key (the file with the same name but no .pub): the key. It stays on your machine only. Never send it to anyone, never paste it in a chat, and never commit it to GitHub.

When you push, your machine uses the private key to prove to GitHub that it matches the public key you left there. GitHub never sees your private key at all. The idea of keeping secrets from leaking is the same one we covered in What Is an API Key? How to Store API Keys in .env Safely.

One public key added to your account works for every repository that account can access, so there is no per-repository setup. If you use more than one machine, such as a laptop and a home desktop, the easiest approach is one key pair per machine, with a name in GitHub that says which machine it is. When a machine is lost or retired, you delete just that one key and the others keep working.

Easy rule: the .pub file goes to GitHub. The file without .pub never leaves your machine.

Setting up an SSH Key on Mac

Every command in this section is typed in Terminal. Our team ran them on macOS 14.1 with the bundled OpenSSH_9.4p1. If you are on Windows, skip to the next section.

1. Check whether you already have an SSH Key

ls -al ~/.ssh

The ~ means your home folder, and .ssh is a hidden folder, so Finder will not show it by default. Every SSH file in this article lives in that folder.

If you see a file named id_ed25519.pub, id_ecdsa.pub or id_rsa.pub, you already have a key and can skip to step 3. If the .ssh folder does not exist or none of these files are there, create a new key in the next step.

2. Create an SSH Key with ssh-keygen

Replace the email with the one you use on GitHub.

ssh-keygen -t ed25519 -C "your_email@example.com"

It will ask where to save the file. Press Enter to accept the default. Then it asks for a passphrase, a password for the key itself. We recommend setting one, so that if your machine is lost or the file leaks, nobody can use the key straight away. Here is what our team saw (we created a test key in a separate folder, so the paths below are changed to the defaults and the randomart image at the end is trimmed):

Generating public/private ed25519 key pair.
Your identification has been saved in /Users/YOU/.ssh/id_ed25519
Your public key has been saved in /Users/YOU/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:u6Kz5piO21Hf3VgDoofTPCE70Z/cuWsfipMo7bI8rDo your_email@example.com

If you pressed Enter and skipped the passphrase, there is no need to create a new key. GitHub Docs shows how to add or change the passphrase later with the command below. We tried it on our test key and got Your identification has been saved with the new passphrase., with the same key pair still working.

ssh-keygen -p -f ~/.ssh/id_ed25519

GitHub gives its reason for passphrases plainly: if someone gains access to your computer, they gain access to every system that uses that key. A passphrase adds one more layer, and it does not make daily use harder, because the ssh-agent in the next step remembers it for you.

Look at the permissions on the two files. The private key is readable only by you, while the public key is readable by anyone, which matches exactly what each one is for.

-rw-------  id_ed25519
-rw-r--r--  id_ed25519.pub

On Ed25519 vs RSA, GitHub Docs recommends Ed25519 and says to use ssh-keygen -t rsa -b 4096 only on legacy systems that do not support Ed25519. DSA keys are no longer supported on GitHub as of March 15, 2022.

3. Add the key to the ssh-agent

The ssh-agent is a program that remembers your key and passphrase, so you do not have to type the passphrase on every push. Start the agent first.

eval "$(ssh-agent -s)"

Then open ~/.ssh/config. If it does not exist yet, create it with touch ~/.ssh/config, and add these lines:

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

If you did not set a passphrase, remove the UseKeychain line. Then add the key to the agent and store the passphrase in your Mac's Keychain.

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

GitHub Docs stresses using the ssh-add that ships with macOS, not one installed through Homebrew or MacPorts, because the --apple-use-keychain option exists only in Apple's version. If you installed OpenSSH through Homebrew and get an error saying the option is unknown, suspect this first.

On macOS versions before Monterey (12.0), the option is written -K instead. If you did not set a passphrase, run ssh-add without the option.

4. Copy the public key

pbcopy < ~/.ssh/id_ed25519.pub

If you open the .pub file with cat ~/.ssh/id_ed25519.pub, you will see a single line in three parts separated by spaces. Our test key looks like this (middle trimmed):

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...H20qRvz4I your_email@example.com

The first part is the key type, the middle is the key itself, and the last part is the email you passed with -C, which GitHub Docs describes as a label for the key. When you paste it into GitHub, paste the whole line and do not add any newlines or extra spaces.

The command above copies the contents of the .pub file to your clipboard. Notice that you copy the .pub file only, never the file without an extension.

Setting up an SSH Key on Windows

Our team has not run this section on a Windows machine ourselves. Every step is taken directly from GitHub Docs. If anything you see differs from what is written here, follow GitHub's documentation.

1. Check for existing keys and create a new one

GitHub Docs uses Git Bash (included with Git for Windows) for this step. Open Git Bash and use the same commands as on Mac: ls -al ~/.ssh to check, and ssh-keygen -t ed25519 -C "your_email@example.com" to create. The files are saved in /c/Users/YOU/.ssh/, which Windows shows as C:\Users\YOU\.ssh\.

2. Start the ssh-agent and add the key

Open PowerShell with Run as administrator and start the ssh-agent service.

Get-Service -Name ssh-agent | Set-Service -StartupType Manual
Start-Service ssh-agent

Then open a new, normal PowerShell window (not as administrator) and add the key.

ssh-add c:/Users/YOU/.ssh/id_ed25519

GitHub Docs warns about one more thing. Windows can have two OpenSSH installations side by side: the one built into Windows and the one bundled with Git for Windows. If you stored your passphrase in the agent but git push still asks for it, tell Git to use Windows' own ssh.

git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"

The other option GitHub Docs gives is to reinstall Git for Windows and choose Use external OpenSSH during setup. If you mainly use Git Bash, the Working with SSH key passphrases page in GitHub Docs has a script you can copy into ~/.profile or ~/.bashrc so the ssh-agent starts every time you open Git Bash.

3. Copy the public key

cat ~/.ssh/id_ed25519.pub | clip

On WSL (Windows Subsystem for Linux), use clip.exe instead. If clip does not work at all, open the hidden .ssh folder, open the .pub file in a text editor and copy it by hand. GitHub Docs also shows clip < ~/.ssh/id_ed25519.pub, but if PowerShell gives a ParseError about the < operator, use the | clip version above.

Add the public key to GitHub and test the connection

This step is the same on both systems.

  1. On GitHub, click your profile picture in the top-right corner and choose Settings.

  2. In the Access section of the sidebar, choose SSH and GPG keys, then click New SSH key.

  3. In the Title field, use a name that says which machine this is, such as "Personal MacBook". For Key type, choose Authentication Key.

  4. Paste the public key into the Key field and click Add SSH key.

Then go back to Terminal and test it.

ssh -T git@github.com

The first time, you will get a warning that the host is not yet known, along with a fingerprint. Check that the ED25519 line matches the value GitHub publishes, SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU, and only then type yes. When our team tested this, the fingerprint matched that value exactly.

After typing yes, our test printed this line:

Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.

The word Warning sounds alarming, but it only means your machine has recorded GitHub in ~/.ssh/known_hosts and will not ask again. Checking the fingerprint before you type yes is how you confirm you are talking to the real GitHub and not another machine pretending to be it.

If everything is right, GitHub Docs says you will see a message like this, with your account name in place of USERNAME:

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

"Does not provide shell access" is not an error. It only means GitHub does not give you a shell on its servers. The command exits with code 1, and that is normal.

Switch an existing repository from HTTPS to SSH

At this point many people have everything set up, yet pushing an existing repository still asks for a password. The reason is that the repository is still linked to an HTTPS URL. Go into the project folder and check.

git remote -v

If it starts with https://github.com/..., change it to an SSH URL as GitHub Docs describes, replacing OWNER and REPOSITORY with your account and repository names.

git remote set-url origin git@github.com:OWNER/REPOSITORY.git

For a new project, when you clone, click the Code button on the repository page and choose the SSH tab instead of HTTPS. The URL will start with git@github.com:. If clone, commit and push still feel unfamiliar, read Git for Beginners: Visual Guide to Add, Commit, and Push first.

Still getting Permission denied (publickey)? What to check

Our team tested with a key that was not attached to any GitHub account, and got exactly this error:

git@github.com: Permission denied (publickey).

It means what it says: GitHub could not find a public key matching the private key your machine sent. The list below covers the main things to check, in order, taken from GitHub Docs' troubleshooting page. It is not every possible cause.

  • Is the key loaded in the agent? Run ssh-add -l -E sha256. If it reports no identities, go back and add the key to the ssh-agent again.

  • Does the key on your machine match the one in GitHub? A fingerprint is a short code calculated from the key, starting with SHA256: like the one shown when you created the key in step 2. It lets you compare keys without reading the whole thing. Compare the fingerprint from the command above with the SSH and GPG keys page in your GitHub Settings. If they differ, you copied the wrong file or added the key to a different account.

  • Always use the git user: type git@github.com, not your own username.

  • Do not use sudo with Git: if you created the key as your normal user but run sudo git push, that command will not use the key you created.

  • Keys unused for a year: GitHub Docs says that if you have not used an SSH key for a year, GitHub automatically deletes it as a security precaution. If you come back to an old project after a long break and cannot push, check that the key is still listed on your SSH keys page.

  • Organization repositories with SAML single sign-on: you must authorize the key for that organization before it works with the organization's repositories. If you can push to your own repositories but not to your company's, suspect this first.

  • See where it fails: run ssh -vT git@github.com and look at which key files SSH tries. If your file is not in the list, the problem is in your local setup, not on GitHub.

One more thing not to overlook: an SSH Key is not safe forever. If your laptop is lost, or you suspect the private key has leaked, that key can still reach your repositories. GitHub Docs says to go to the SSH keys page in your account and delete any key you do not recognize or no longer use. The passphrase you set when creating the key is what buys you time to delete it before anyone else can use it.

SSH or HTTPS with a Personal Access Token: which should you use?

Both work with GitHub. The straight answer:

Choose SSH if you mostly work on your own machine and want to set things up once, with no extra token to create and store.

Choose HTTPS with a token if your network cannot connect over SSH's port 22. GitHub Docs says HTTPS URLs work even behind a firewall or proxy. When Git asks for a password, you enter a Personal Access Token instead of your account password.

And if you are not comfortable typing commands yet, there is a third option. GitHub Docs notes that if you have GitHub Desktop installed, you can use it to clone repositories without dealing with SSH keys, and the 2021 password announcement says GitHub Desktop was unaffected. That suits the early days when you would rather not open Terminal, but once you work on a server or use the terminal inside VS Code, you will end up setting up SSH anyway.

If you are still unsure what GitHub does for a team, read What is GitHub?, and if typing commands in Terminal is still new to you, Terminal/Command Line Pro Edition covers the basics.


Summary: setting up an SSH Key for GitHub, step by step

GitHub has not accepted account passwords for Git since August 13, 2021, which makes an SSH Key the most convenient option for your own machine. The whole process is: check for an existing key, create one with ssh-keygen -t ed25519, add it to the ssh-agent, put the .pub file in GitHub, test with ssh -T git@github.com, and switch your existing repositories' remotes to SSH. The one thing to watch the whole time is that the private key never leaves your machine.

Open Terminal and try ssh -T git@github.com now. If you see your account name, the next time you git push you will not need your GitHub account password.

Follow more articles and tips for people starting out as programmers on our channels.

Facebook: Superdev Academy Thailand (https://www.facebook.com/superdev.academy.th)

YouTube: Superdev Academy Channel (https://www.youtube.com/@SuperdevAcademy)

Instagram: @superdevacademy (https://www.instagram.com/superdevacademy/)

TikTok: @superdevacademy (https://www.tiktok.com/@superdevacademy?lang=th-TH)

FAQ: Frequently Asked Questions about This Article

A collection of questions and answers to help you better understand the content of this article.