iTranslated by AI
Setting Up SSH Public Key Authentication for GitHub Repository Operations
Many people have already written about this topic, but I've noticed that the following perspectives are often missing, so I'm organizing this for my own reference.
- What should we use for the email comment in ssh-keygen?
- Does everyone enter the passphrase every time?
- Automatically converting HTTPS URLs to Git URLs
- Automatically specifying and using a dedicated key
What we want to do
Enable Git operations on GitHub repositories that require authentication (such as private repositories) without using a PAT (Personal Access Token), by using SSH public/private keys.
The environment is macOS.
Procedure
1. ssh-keygen command
ssh-keygen -t ed25519 -C "your-email@example.com"
-t specifies the encryption algorithm. If not specified, the default is RSA with a key length of 2048 bits. ed25519 is not necessarily stronger than RSA, but the official GitHub documentation recommends using ed25519.
-C sets the comment appended to the end of the public key. If not specified, the default is accountname@hostname, which has little practical harm but you might regret it later. Specify the email address you use on GitHub. Alternatively, on https://github.com/settings/emails, there is a note under Keep my email addresses private that suggests using the xxxxx@users.noreply.github.com email address. That is one option. I use it myself.
We'll remove your public profile email and use xxxxx@users.noreply.github.com when performing web-based Git operations (e.g. edits and merges) and sending email on your behalf. If you want command line Git operations to use your private email you must set your email in Git.
Previously authored commits associated with a public email will remain public.
The comment field of the -C option in ssh-keygen is not limited to writing an email address, but the details are well explained in this article (in Japanese); thank you.
2. Create an SSH key pair
Create a key pair using the ssh-keygen command. You will be asked a few questions interactively.
Enter file in which to save the key
You rarely need to change the save folder, but if you want to change the filename, specify it here. I want to use my GitHub key pair only for GitHub, so I name it something like id_ed25519_github to make it identifiable.
Enter passphrase for ... / Enter same passphrase again:
If you want to set a passphrase (like a password), enter it here. It's generally recommended to set one. Later, we'll configure ssh-agent, which caches the passphrase so you don't have to enter it every time.
$ ssh-keygen -t ed25519 -C "your-email@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/your-home/.ssh/id_ed25519): /Users/your-home/.ssh/id_ed25519_github
Enter passphrase for "/Users/your-home/.ssh/id_ed25519_github" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/your-home/.ssh/id_ed25519_github
Your public key has been saved in /Users/your-home/.ssh/id_ed25519_github.pub
The key fingerprint is:
SHA256:(省略) your-email@example.com
ls -l ~/.ssh/
and verify that the private key and public key have been created.
-
id_ed25519_github: Private key. It should have permissions-rw-------so others cannot read it. -
id_ed25519_github.pub: Public key. It should have wider permissions like-rw-r--r--. I assumepubstands for public.
💡 Note
- On macOS, sometimes the keys are created in
~/(the home directory) instead of~/.ssh/. In that case, either move the keys, or delete them and retry with the path specified:mkdir -p ~/.ssh ssh-keygen -t ed25519 -C "your-email@example.com" -f ~/.ssh/id_ed25519_github
3. Register the public key on GitHub
pbcopy < ~/.ssh/id_ed25519_github.pub
Copy the content using the command above, or open the file directly and copy the contents. Be careful not to copy the private key by mistake.
The format ssh-ed25519 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx your-email@example.com is the public key. The one starting with -----BEGIN OPENSSH PRIVATE KEY----- ... is the private key, so it's different.
Open https://github.com/settings/keys and click the New SSH key button.
- Title: Anything is fine, but if you register keys from multiple devices on GitHub, it's good to name them so you can distinguish the device. Alternatively, you could use the same private key across multiple devices, but it's better to have separate keys so you can revoke them individually if compromised.
- Key: Paste the content you copied earlier.
Click the Add SSH Key button to save.
After registering, it should appear in the list of public keys under Authentication keys at https://github.com/settings/keys.
If you want to use this key for GitHub Organizations as well, authorize the desired Org via Configure SSO.
4. Verify SSH connectivity
Test the SSH connection with ssh -T git@github.com.
$ ssh -T git@github.com
Hi xxxxxxxx! You've successfully authenticated, but GitHub does not provide shell access.
If you get a response with "successfully authenticated", the connection is working.
Note that the direct SSH connection to git@github.com is only used for connectivity verification.
Once this works, try cloning a private repository, etc.
💡 Note
- If you see
Permission denied (publickey)., set up the configuration from the next section "Supplement 1: Automatic private key specification" and try again.
Supplements
In fact, I wrote this article because I wanted to compile and record this information.
Supplement 1: Automatic private key specification
In my case, I use a dedicated key for GitHub only, so I add the following configuration to make SSH automatically use that specific key. Adjust the key name to match your environment.
Host github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
Supplement 2: Add the SSH key to ssh-agent
First, run eval "$(ssh-agent -s)" to start ssh-agent in the background.
$ eval "$(ssh-agent -s)"
> Agent pid xxxxx
Add the following settings to the Host github.com section in ~/.ssh/config.
Host github.com
AddKeysToAgent yes
UseKeychain yes
-
AddKeysToAgent yes: Configuration for the private key. When establishing an SSH connection, the private key used is automatically added to ssh-agent. The key will be reused as long as ssh-agent is running or not restarted. -
UseKeychain yes: Configuration for the private key passphrase. When starting an SSH connection, it will search the keychain for the passphrase and use it if found; otherwise, it will prompt the user to enter it and store it in the keychain.
Remove UseKeychain yes if you don't use a passphrase or don't want to store it in the macOS keychain. This can cause the error Bad configuration option: usekeychain. In that case, add IgnoreUnknown UseKeychain to the Host github.com section.
Here's an example:
Host github.com
AddKeysToAgent yes
IgnoreUnknown UseKeychain
Then, explicitly add the key to ssh-agent.
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_github
The --apple-use-keychain option saves the private key and its passphrase to the macOS keychain. If you don't use the keychain, you can omit this. Typically, if UseKeychain yes is set, the passphrase will be asked on the first SSH connection and then stored in the keychain automatically, so explicitly using ssh-add might not be necessary [1].
For troubleshooting ssh-agent configuration, GitHub's official documentation is the most comprehensive. As always, official sources are the best.
Combining Supplement 1 and Supplement 2, the ssh config would look like:
Host github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
AddKeysToAgent yes
UseKeychain yes
Or alternatively:
Host github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
AddKeysToAgent yes
IgnoreUnknown UseKeychain
Supplement 3: Automatically replace https://github.com/ URLs with git@github.com: when cloning, etc.
Setting this up allows you to copy a repository URL from your browser and clone it directly, which is convenient.
[url "git@github.com:"]
insteadOf = https://github.com/
Supplement 4: Personal Access Token (PAT) and OAuth
GitHub offers a few authentication methods: interactive methods for humans (e.g., simple password + MFA, Passkeys), and for non-interactive cases, besides SSH public keys, there are Personal Access Token (PAT) and OAuth.
PAT (Personal Access Token) is easier to set up and more convenient, but it carries security risks—there are trade-offs.

I have summarized the differences and use cases of these authentication methods.
| Comparison Item | SSH Public Key Authentication | PAT (Personal Access Token) | OAuth App/GitHub App |
|---|---|---|---|
| Security | |||
| Where credentials are stored | Private key locally, public key only on GitHub | Entire token synced with GitHub | Can be refreshed with a refresh token |
| Risk of leakage | Low (double protection: private key + passphrase) | High (token alone can be used for authentication) | Medium (token can be easily revoked) |
| Cryptographic strength | Very high (RSA/Ed25519) | Depends on token string complexity | Complies with OAuth standards |
| Network security | Credentials never transmitted | Token transmitted over HTTPS | Protected by authentication flow |
| Permission management | Full access to repositories | Granular scopes can be set | Most granular permission control possible |
| Expiration | None (must be manually deleted) | Can be set with expiry (auto-revoke) | Can auto-renew |
| Convenience | |||
| Initial setup difficulty | Complex (key generation, registration, SSH config) | Easy (generate and copy-paste) | Somewhat complex (App registration, authentication flow implementation) |
| Daily use | Very convenient (only passphrase needed) | Somewhat cumbersome (token entry/storage settings) | Auto-renewal |
| Multiple devices | Need to generate key on each device | Can reuse the same token | Authentication flow per device |
| Repository URL | SSH format (git@github.com:...) | HTTPS format (https://github.com/...) | HTTPS format |
| Recommended Use Cases | |||
| Personal development | ◎ Recommended | △ Can be used | △ Overkill |
| Team development | ◎ Recommended | △ Supplementary use | ○ Consider for large teams |
| Automation/CI/CD | × Setup is complex | ○ Easy but suboptimal | ◎ Recommended |
| Temporary access | × | ◎ Use with strict scope and expiry | ○ Can be used |
| Third-party integration | × | △ Not recommended for ongoing use | ◎ Optimal |
-
However, explicitly running
ssh-add --apple-use-keychaindoesn't cause any issues, so I do it. I'm not entirely sure about the details here. ↩︎
Discussion