Developer Tools

How to Generate an SSH Key on Mac and Add It to GitHub

Published Nov 2, 2026
Tested on a real Mac. ssh-keygen, ssh -G and ssh-keyscan were run with keys and configs in a scratch folder (OpenSSH_10.3p1); ssh-add, pbcopy, ssh -T to GitHub and any change to ~/.ssh were not run. Test machine: MacBook Air (M3, 16 GB), macOS Tahoe 26.6.2, zsh 5.9.
On this page
  1. Check what you already have
  2. Step 1: Generate an ed25519 key
  3. Step 2: Store the passphrase in the macOS Keychain
  4. Step 3: Copy the public key and add it to GitHub
  5. Step 4: Test the connection
  6. Troubleshooting
  7. Common questions

To create an SSH key on a Mac for GitHub, open Terminal and run:

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

Press Return to accept the default location (~/.ssh/id_ed25519), type a passphrase, then copy the public key with pbcopy < ~/.ssh/id_ed25519.pub and paste it into GitHub under Settings > SSH and GPG keys. The rest of this guide covers the Keychain setup so you only type the passphrase once, and how to check that it works.

Check what you already have

macOS ships with OpenSSH, so there’s nothing to install. On my test Mac (macOS Tahoe 26.6.2):

ssh -V
OpenSSH_10.3p1, LibreSSL 3.3.6

ssh, ssh-keygen, ssh-add and pbcopy all live in /usr/bin. If you might already have a key, list the folder first with ls -al ~/.ssh. Files named id_ed25519 and id_ed25519.pub mean you have one. If you run ssh-keygen again with the same file name, it stops and asks first. In my test it printed ./id_ed25519 already exists. and Overwrite (y/n)?. Answer n unless you really want to replace the key, because the old one stops working everywhere it was added. The .ssh folder is hidden in Finder, so see how to show hidden files on Mac if you want to look at it there.

Step 1: Generate an ed25519 key

ed25519 is the key type GitHub recommends. It’s short, fast and secure. For this article I didn’t touch my real ~/.ssh folder. I saved the test keys in a scratch folder instead, using -f for the file and -N "" for an empty passphrase (only for the demo):

ssh-keygen -t ed25519 -C "you@example.com" -f ./id_ed25519 -N ""
Generating public/private ed25519 key pair.
Your identification has been saved in ./id_ed25519
Your public key has been saved in ./id_ed25519.pub
The key fingerprint is:
SHA256:zTcB9dnitctHxipeWAR6cV1j+pX80a2Nbg7tM8/wGZ8 you@example.com
The key's randomart image is:
+--[ED25519 256]--+
|          ..+ .+o|
|           o =+o*|
|          . o.=+*|
|         o . +.B=|
|        S o o =o*|
|           . *.+.|
|            + B+.|
|           . Bo+*|
|            . oE=|
+----[SHA256]-----+

That makes two files. Check their permissions:

-rw-------@ 1 you  wheel  411 Nov  2 17:32 id_ed25519
-rw-r--r--@ 1 you  wheel   97 Nov  2 17:32 id_ed25519.pub

id_ed25519 is the private key. Never share it or paste it anywhere. id_ed25519.pub is the public key, the one you give to GitHub.

The prompts you’ll actually see

When you run the command normally, without -f and -N, ssh-keygen asks three questions. I captured a real run. The default path is shown with your username, and I typed a scratch path (shortened here to <scratch>):

Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/you/.ssh/id_ed25519):
Enter passphrase for "<scratch>/pp_key" (empty for no passphrase):
Enter same passphrase again:

Note the passphrase prompt. In OpenSSH 10 it names the file you’re protecting. Older tutorials show Enter passphrase (empty for no passphrase):, so don’t worry if yours looks different. Nothing appears on screen while you type the passphrase. That’s normal.

Use a passphrase. With the Keychain setup below you won’t have to type it again.

Step 2: Store the passphrase in the macOS Keychain

Create or edit ~/.ssh/config and add:

Host github.com
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519
  • AddKeysToAgent yes loads the key into ssh-agent the first time you use it.
  • UseKeychain yes is an Apple-only option. It reads the passphrase from your login Keychain, and saves it there after you type it once.
  • IdentityFile points to the key, which matters if you have more than one.

Then add the key to the agent and Keychain once:

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

I did not run ssh-add or edit my real ~/.ssh/config for this article. I checked the flag in man ssh-add on this Mac. --apple-use-keychain is the new name for the old -K flag, and --apple-load-keychain replaces -A. Old guides still use ssh-add -K. It still works on macOS for now, but the man page says it prints a warning, so use the long flag.

Gotcha: check your config without connecting

You can test a config file without touching your real one, and without contacting GitHub. ssh -G prints the settings ssh would use for a host, then exits:

ssh -F ./config -G github.com | grep -Ei '^(user|hostname|port|addkeystoagent|identityfile) '
user you
hostname github.com
port 22
identityfile ~/.ssh/id_ed25519
addkeystoagent true

Two things I learned from this:

  1. user is your Mac username, not git. That’s why you must connect as git@github.com. When I ran ssh -G git@github.com, it showed user git. You can also add User git to the config block.
  2. UseKeychain never shows up in ssh -G output, even though it’s set. It is parsed, though. A bad value like UseKeychain maybe failed with unsupported option "maybe". So don’t panic if it’s missing from the list.

Typos are caught too. With IdentitiyFile (extra “i”) in the file, ssh refused to run at all:

./config-typo: line 4: Bad configuration option: identitiyfile
./config-typo: terminating, 1 bad configuration options

A typo in ~/.ssh/config breaks every ssh and git-over-ssh command, not just GitHub. Run ssh -G github.com after editing it.

Step 3: Copy the public key and add it to GitHub

pbcopy < ~/.ssh/id_ed25519.pub

This puts the key on your clipboard without printing it. I didn’t run it on the test Mac, to avoid replacing the clipboard. The key is a single line that starts with ssh-ed25519 AAAAC3NzaC1lZDI1NTE5 and ends with your comment (you@example.com).

On GitHub, go to Settings > SSH and GPG keys > New SSH key. Give it a title like “MacBook Air”, leave the type as Authentication Key, paste, and save.

Make sure you copied the .pub file. If what you paste starts with -----BEGIN OPENSSH PRIVATE KEY-----, stop. That’s the private key.

Step 4: Test the connection

ssh -T git@github.com

I did not run this against GitHub. The first time you connect, ssh asks you to trust GitHub’s host key. It shows a fingerprint and asks yes/no. Compare the fingerprint before typing yes. I fetched GitHub’s public host key without logging in, which needs no key of your own:

ssh-keyscan -t ed25519 github.com 2>/dev/null | ssh-keygen -lf -
256 SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU github.com (ED25519)

This matches the ED25519 fingerprint GitHub publishes in its docs. If the prompt shows something else, don’t connect.

When the key works, GitHub replies with a message like Hi your-username! You've successfully authenticated, but GitHub does not provide shell access. Don’t be alarmed if the command reports a non-zero exit code. GitHub closes the session right away because there’s no shell.

Finally, switch existing repos from HTTPS to SSH:

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

Troubleshooting

Permissions 0644 for 'id_ed25519' are too open. I reproduced this by running chmod 644 on a test private key:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for 'pp_key' are too open.
It is required that your private key files are NOT accessible by others.

ssh refuses to use the key. Fix it with chmod 600 ~/.ssh/id_ed25519. This happens most often after copying keys from a backup or another Mac.

Forgot your passphrase? There’s no way to recover it. Running ssh-keygen -y -f with the wrong one gave incorrect passphrase supplied to decrypt private key. If Keychain saved it, you can find it in the Keychain Access app (not tested here). Otherwise make a new key and add it to GitHub.

Permission denied (publickey). Usually the key isn’t on GitHub, you connected without git@, or ssh offered a different key. Run ssh -vT git@github.com and look for the Offering public key lines.

Common questions

Should I use RSA or ed25519?

Use ed25519. Only use RSA (-t rsa -b 4096) for an old server that doesn’t support ed25519.

Can I use the same key on two Macs?

You can copy it, but a separate key per Mac is better. If one Mac is lost, you delete just that key on GitHub.

Do I need ssh-agent running?

No. macOS runs it on demand through launchd. On my Mac, launchctl print gui/$(id -u)/com.openssh.ssh-agent listed program = /usr/bin/ssh-agent with state = not running, and SSH_AUTH_SOCK was already set. The agent starts when ssh first needs it. Don’t add eval "$(ssh-agent -s)" to your shell config on a Mac, as Linux guides suggest. It starts a separate agent and points SSH_AUTH_SOCK away from the one launchd manages, which you don’t need.

Where should I put SSH_AUTH_SOCK or other variables?

You normally don’t need to set any. If a tool asks you to, see how to set an environment variable permanently on Mac.

Does this work for GitLab or Bitbucket?

Yes. Add the same .pub key in their settings and add a matching Host block for their hostname.