Secure Shell keys, commonly called SSH keys, give developers and administrators a safer and more convenient way to authenticate with GitHub, cloud instances, virtual private servers, and internal machines. Instead of typing a password for every connection, a person proves identity by using a private key stored on the local computer and a matching public key installed on the remote service. When configured correctly, SSH keys improve security, simplify workflows, and reduce the risk of password-based attacks.
TLDR: SSH keys work as a secure pair: a private key kept on the local machine and a public key added to GitHub or a server. A developer generates the key pair, protects it with a passphrase, adds the public key to the target account or server, and tests the connection. For best results, each person should use strong modern key types, restrict private key permissions, and rotate or remove old keys when access is no longer needed.
What SSH Keys Are and Why They Matter
An SSH key pair contains two linked files. The private key must remain secret and should never be shared, copied into chat, committed to Git, or uploaded to a public location. The public key can be safely shared with services such as GitHub or placed inside a server’s authorized_keys file.
When a connection begins, the remote system checks whether the public key is allowed. The local machine then proves it has the matching private key without actually sending that private key over the network. This makes SSH authentication more resistant to interception than ordinary password logins.
SSH keys are especially useful for GitHub because they allow a developer to clone, pull, and push repositories without repeatedly entering account credentials. They are also essential for server administration, automated deployments, CI/CD systems, and secure remote maintenance.
Choosing the Right Key Type
Modern systems commonly support several SSH key algorithms. For most current use cases, Ed25519 is a strong and efficient choice. It creates compact keys, performs quickly, and is widely supported by GitHub and many Linux servers.
If compatibility with older systems is required, RSA may still be used, but it should be generated with a larger size, such as 4096 bits. However, when the environment supports it, Ed25519 is usually preferred.
- Recommended for modern systems:
ed25519 - Fallback for older systems:
rsawith4096bits - Not recommended: outdated or weak key types that are no longer accepted by modern platforms
Checking for Existing SSH Keys
Before creating a new key, a developer may check whether an SSH key already exists on the local machine. On macOS, Linux, or Windows with Git Bash, the following command lists common SSH key files:
ls -al ~/.ssh
Common file names include:
id_ed25519andid_ed25519.pubid_rsaandid_rsa.pub- Custom names such as
github_ed25519orproduction_server
The file ending in .pub is the public key. The file without .pub is the private key. If an existing private key is still in use, it should not be overwritten accidentally.
Generating a New SSH Key
To create a new Ed25519 key, the user can run:
ssh-keygen -t ed25519 -C "user@example.com"
The email comment helps identify the key later, especially when it is added to GitHub or reviewed on a server. During generation, the command asks where to save the key. The default location is often acceptable for a primary key:
/home/username/.ssh/id_ed25519
On macOS, the path may look like:
/Users/username/.ssh/id_ed25519
On Windows with Git Bash, it commonly appears as:
/c/Users/username/.ssh/id_ed25519
When prompted for a passphrase, a strong passphrase should be used. A passphrase protects the private key if the device or file is stolen. Although leaving it empty may be convenient for some automated systems, personal keys should normally be protected.
If RSA is required for compatibility, the command can be:
ssh-keygen -t rsa -b 4096 -C "user@example.com"
Starting the SSH Agent and Adding the Key
The SSH agent stores decrypted private keys in memory during a login session. This allows a developer to enter the passphrase once instead of every time a Git or SSH command runs.
On many Linux and macOS systems, the agent can be started with:
eval "$(ssh-agent -s)"
Then the private key can be added:
ssh-add ~/.ssh/id_ed25519
If the key has a different file name, that name should be used instead:
ssh-add ~/.ssh/github_ed25519
On macOS, users may store the passphrase in the system keychain depending on SSH version and configuration. On Windows, Git Bash, OpenSSH for Windows, or a credential manager may handle key loading differently, but the principle remains the same: the private key must be available to the SSH client when authentication occurs.
Adding an SSH Key to GitHub
To use SSH with GitHub, the public key must be copied and added to the GitHub account. The public key can be displayed with:
cat ~/.ssh/id_ed25519.pub
The entire output should be copied. It usually begins with ssh-ed25519 and ends with the identifying comment, such as an email address. The private key file should never be copied into GitHub.
Inside GitHub, the user would typically open account settings, find SSH and GPG keys, choose New SSH key, enter a descriptive title, and paste the public key. A useful title might include the device name, such as Work Laptop or Home Desktop.
After the key is added, the connection can be tested:
ssh -T git@github.com
The first connection may show a host authenticity prompt. If the host fingerprint is correct, it can be accepted. A successful response usually confirms authentication and mentions that shell access is not provided, which is normal for GitHub.
Using SSH URLs for Git Repositories
GitHub repositories can be accessed using either HTTPS or SSH URLs. For SSH authentication, the remote URL should look similar to:
git@github.com:owner/repository.git
To clone a repository with SSH, the developer can run:
git clone git@github.com:owner/repository.git
For an existing repository that still uses HTTPS, the remote can be changed:
git remote set-url origin git@github.com:owner/repository.git
The current remote URL can be checked with:
git remote -v
Once the SSH key and remote URL are configured correctly, Git operations such as pull, fetch, and push should authenticate through SSH.
Adding an SSH Key to a Server
For a Linux server, the public key must be placed in the target user’s ~/.ssh/authorized_keys file. If password login is currently allowed, the easiest method is often:
ssh-copy-id username@server_ip
This command copies the public key to the server and sets up the required file. If ssh-copy-id is unavailable, the key can be added manually. The administrator logs into the server, creates the SSH directory, sets permissions, and appends the public key:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
The public key is pasted as a single line inside authorized_keys. Line breaks inside the key can cause authentication failure, so the full key must remain intact.
After installation, the connection can be tested from the local machine:
ssh username@server_ip
If the key file has a custom name, the -i option can be used:
ssh -i ~/.ssh/production_server username@server_ip
Configuring Multiple SSH Keys
Many professionals use more than one SSH key. For example, one key may be used for GitHub, another for a staging server, and another for production infrastructure. This separation limits damage if one key must be revoked.
The SSH client configuration file, located at ~/.ssh/config, can simplify multiple identities:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/github_ed25519
IdentitiesOnly yes
Host production
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/production_server
IdentitiesOnly yes
With this configuration, GitHub uses the specified GitHub key, while the production server can be reached with:
ssh production
This approach improves clarity and prevents the SSH client from offering too many keys during authentication.
Improving Server Security After Keys Work
Once key-based login has been tested successfully, the server administrator may choose to reduce password-based risks. On many Linux servers, SSH daemon settings are stored in:
/etc/ssh/sshd_config
Common hardening options include disabling root login and disabling password authentication. The exact settings depend on the environment, but they may look like:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Before disabling password authentication, at least one working SSH key login should be confirmed in a separate terminal session. Otherwise, the administrator could lock everyone out of the server.
After changes are made, the SSH service usually needs to be reloaded or restarted:
sudo systemctl reload ssh
On some distributions, the service may be named sshd instead of ssh.
Best Practices for SSH Key Management
- Protect the private key: It should remain only on trusted devices and should never be emailed, pasted into tickets, or stored in repositories.
- Use a passphrase: A passphrase adds protection if the private key file is exposed.
- Create separate keys for separate purposes: GitHub, personal servers, work servers, and automation can each have dedicated keys.
- Remove unused keys: Old laptops, former employees, retired servers, and abandoned automation accounts should have their keys revoked.
- Check permissions: SSH is strict about file permissions. Private keys should usually be readable only by the owner.
- Back up carefully: If a private key is backed up, the backup must be encrypted and protected.
- Review access regularly: Periodic audits help ensure that only authorized keys remain active.
Common Troubleshooting Tips
If SSH authentication fails, the cause is often a small configuration issue. The user can run a verbose connection test to see more detail:
ssh -vT git@github.com
For a server, the command may be:
ssh -v username@server_ip
Common problems include incorrect file permissions, the wrong public key on the remote system, an SSH agent that has not loaded the key, or a repository still using an HTTPS remote. On servers, the authorized_keys file must belong to the correct user and must not be writable by other users.
FAQ
What is the difference between a public key and a private key?
The private key stays on the local machine and must be kept secret. The public key is shared with GitHub or placed on a server to allow authentication.
Can the same SSH key be used for GitHub and servers?
It can be used, but it is usually better to create separate keys for different services. Separate keys make access easier to manage and revoke.
What happens if a private key is lost?
If the private key is lost and no backup exists, it cannot be recovered from the public key. A new key pair must be generated, and the new public key must be added to GitHub or the server.
What should happen if a private key is exposed?
The exposed key should be removed immediately from GitHub, servers, and any other system where it was authorized. A new key pair should then be generated and installed.
Why does GitHub say authentication succeeded but shell access is not provided?
That message is normal. GitHub allows SSH authentication for Git operations, but it does not provide an interactive shell account.
Why is SSH asking for a password even after the key was added?
The SSH client may not be using the correct key, the public key may not be installed correctly, or the remote URL may still use HTTPS. Checking ssh-add -l, git remote -v, and verbose SSH output can help identify the problem.
Is it safe to store an SSH key without a passphrase?
For personal and administrative use, a passphrase is strongly recommended. Passphrase-free keys are sometimes used for automation, but they should be restricted, carefully stored, and limited to the minimum permissions required.