This SSH key setup guide explains how to generate a key pair, connect it to GitHub or GitLab, use it for remote servers, configure aliases, and troubleshoot the errors that commonly stop authentication. Keep the checklist as a reusable reference whenever you add a device, change accounts, or rotate credentials.
Overview
SSH, or Secure Shell, can authenticate you to Git hosts and remote computers without sending a password for every connection. An SSH key pair contains a private key that stays on your device and a public key that you upload to the service or server. The two keys work together, but the private key should never be uploaded, emailed, committed to a repository, or pasted into a support ticket.
For most new setups, ed25519 is a sensible default because it is widely supported and produces a compact key. Use RSA only when you need compatibility with an older system that does not support ed25519. The exact prompts can vary slightly between Linux, macOS, and Windows, but the overall process is the same.
Before starting, confirm which account and device you are configuring. A useful inventory records the device name, key filename, associated Git or server account, date created, and last date reviewed. Do not record the private key itself.
Checklist by scenario
1. Generate a new SSH key
- Open a terminal. On Windows, use PowerShell, Windows Terminal, or Git Bash.
- Check whether you already have keys before creating another one:
ls -la ~/.ssh
On Windows PowerShell, the equivalent location is usually:
Get-ChildItem $HOME\.ssh
- Generate an ed25519 key, replacing the comment with an address or label that helps identify its purpose:
ssh-keygen -t ed25519 -C "device-or-account-label"
When prompted, accept the default filename if you are setting up your first key. If you already use a key, choose a distinct filename such as id_ed25519_work. Set a passphrase when prompted. It protects the private key if the file is copied from the device.
If ed25519 is unavailable on an older system, an RSA key may be used instead:
ssh-keygen -t rsa -b 4096 -C "device-or-account-label"
2. Start ssh-agent and load the key
The SSH agent keeps an unlocked key available for the current session or user account, so you do not have to enter its passphrase for every operation. Start the agent with:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Use your actual filename if you created a named key. macOS can store the passphrase in its keychain with an appropriate SSH configuration. On Linux, the method depends on the desktop session and distribution. On Windows, Git Bash, PowerShell, and the built-in OpenSSH agent may be configured differently. If ssh-add reports that the agent is unavailable, start or enable the OpenSSH Authentication Agent service rather than repeatedly generating new keys.
3. Add the public key to GitHub or GitLab
Display the public key, which normally ends in .pub:
cat ~/.ssh/id_ed25519.pub
On Windows PowerShell, use:
Get-Content $HOME\.ssh\id_ed25519.pub
Copy the complete single line, including its key type and trailing comment. In your Git hosting account, open the SSH key settings, choose the option to add a key, give it a recognizable title, paste the public key, and save it. Use a separate key entry for each device when practical. This makes it possible to remove one lost or retired device without disrupting every other connection.
Test the connection using the host's documented SSH test command. For GitHub, the usual test is:
ssh -T git@github.com
For GitLab, use:
ssh -T git@gitlab.com
The first connection may ask you to verify the host fingerprint. Confirm it using the provider's current documentation or a trusted administrator before accepting it.
4. Use a key with a remote server
Ask the server administrator to install your public key in the correct account's ~/.ssh/authorized_keys file, or use an approved provisioning process. Then connect with:
ssh username@server.example
If the key has a non-default filename, specify it explicitly:
ssh -i ~/.ssh/id_ed25519_work username@server.example
Do not replace server configuration or disable password authentication solely to solve a client-side error. Confirm access in a second session before changing server settings, so you do not lock yourself out.
5. Create an SSH config alias
An SSH config file avoids long commands and helps select the right key for different accounts:
Host work-git
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
Save this in ~/.ssh/config. You can then use ssh work-git for testing or set a Git remote that uses the alias, such as git@work-git:organization/repository.git. Keep the file private and use the correct path syntax for your operating system.
What to double-check
- Public versus private key: Upload only the file ending in
.pub. The private key usually has the matching name without that extension. - Account identity: Make sure the public key was added to the intended GitHub, GitLab, or server account, not a second browser session.
- Remote URL: Run
git remote -vand confirm the repository uses an SSH URL rather than an unrelated HTTPS URL. - File permissions: On Unix-like systems, restrict the private key and SSH directory:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
- Agent contents: Check loaded keys with
ssh-add -l. Remove an unnecessary key from the agent withssh-add -d path/to/key. - Verbose diagnostics: If authentication fails, run
ssh -vT git@github.comor add more verbosity with-vv. Look for the key being offered, the selected config file, and the server's rejection reason.
For a broader method for isolating software failures, see the software troubleshooting guide. If you are transferring files rather than managing Git repositories, the FileZilla SFTP walkthrough provides a separate client-focused workflow.
Common mistakes and fixes
“Permission denied (publickey)” usually means the server did not accept any offered key. Check the username, public key placement, key filename, agent status, and SSH config alias. Use verbose output to see whether the intended key was offered.
“Could not open a connection to your authentication agent” means the current shell cannot reach an agent. Start the agent in that shell or use the operating system's OpenSSH agent, then run ssh-add again.
“Bad permissions” indicates that the private key or its directory is readable by other users. Apply restrictive permissions and verify that you are using the correct file.
The wrong Git account is selected. Multiple accounts often require separate key files and explicit Host aliases. Avoid loading many unrelated keys at once; some servers stop trying after a limited number of failed offers.
A lost or exposed private key. Treat it as compromised. Remove its public-key entry from every Git host and server where it was authorized, then generate and distribute a replacement. Do not rely on deleting the local file alone.
When to revisit your SSH setup
Review this checklist whenever you receive a new computer, change teams or Git accounts, add a server, or notice an unexpected authentication prompt. Revisit it during access reviews and before major workflow changes, such as moving repositories between hosting platforms or replacing a development environment.
Maintain a simple key inventory with the device, owner, purpose, filename, authorized services, and review date. Remove entries for retired devices and revoke keys that no longer have a clear owner. Periodically confirm that old public keys are not still authorized on servers or hosting accounts. When your tools, operating system, shell, or hosting workflow changes, retest both Git access and server access rather than assuming the previous configuration still applies.
Final action checklist: generate or identify the correct key, protect it with a passphrase, load it into the appropriate agent, upload only the public key, test the intended account, document the configuration, and record where the key is authorized. This gives you a repeatable SSH setup instead of a one-time fix.