SSH keys: how they work and how to create one

An SSH key is a pair of files: the private key stays with you and the public key goes to the server. To create one, run ssh-keygen -t ed25519 and add the .pub file.

Updated 5 min read

Learning objectives

After reading this article you will be able to:

  • Understand how a public and private key pair authenticates you
  • Generate an Ed25519 key with a passphrase on Linux, macOS or Windows
  • Add the key to GitHub, test the connection and avoid leaks
On this page

SSH (Secure Shell) is the protocol you use to log in to servers and to run git push without typing a username and password every time. Instead of a password, it can authenticate you with a pair of cryptographic keys.

This model is safer than a password for a simple reason: the secret never travels over the network.

Your machineid_ed25519private keyServerid_ed25519.pubpublic keychallengesigns with theprivate keysignaturechecks with thepublic keythe private key never leavesyou're in
The server sends a challenge, the private key signs it and the public key checks it: only the signature crosses the network.

How does an SSH key work?#

You generate two mathematically linked files:

  • Private key (for example id_ed25519): stays only on your machine. It is the secret.
  • Public key (id_ed25519.pub): can be copied anywhere. It lives on the server or in your GitHub account.

When you connect, the server sends a challenge. Your SSH client signs the challenge with the private key, and the server checks the signature with the public key. If it matches, you are in. The private key itself is never sent.

Someone who holds only the public key cannot pretend to be you. Someone who holds the private key can, so treat it with the same care as a bank password.

How do you generate an SSH key?#

The command is the same on Linux, macOS and Windows (PowerShell or Git Bash):

bash
ssh-keygen -t ed25519 -C "you@example.com"
  • -t ed25519 picks the key type.
  • -C adds a comment (use the email of your GitHub account).

The program asks where to save the key: press Enter to accept the default (~/.ssh/id_ed25519). Then it asks for a passphrase. Set one. It encrypts the private key file: if someone copies the file, they still need the phrase.

At the end there are two files in ~/.ssh/: id_ed25519 (private) and id_ed25519.pub (public).

Which key type should you use?#

In most cases, Ed25519. It is the type GitHub's documentation uses by default in its examples.

If the system or an older server does not accept Ed25519, use RSA with 4096 bits:

bash
ssh-keygen -t rsa -b 4096 -C "you@example.com"

How do you use ssh-agent to avoid typing the passphrase every time?#

ssh-agent keeps the unlocked key in memory for the session.

On Linux and macOS:

bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

On macOS, to store the passphrase in the Keychain, run ssh-add --apple-use-keychain ~/.ssh/id_ed25519 and create the file ~/.ssh/config with:

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

On Windows, open PowerShell as administrator and enable the service:

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

Then, in a terminal without administrator rights:

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

How do you add the public key to GitHub?#

  1. Copy the contents of the .pub file, with no extra spaces or line breaks:
    • macOS: pbcopy < ~/.ssh/id_ed25519.pub
    • Windows (PowerShell): cat ~/.ssh/id_ed25519.pub | clip
    • Linux: cat ~/.ssh/id_ed25519.pub and copy the output.
  2. On GitHub, click your profile picture, then Settings.
  3. In the sidebar, under Access, open SSH and GPG keys.
  4. Click New SSH key, give it a title (for example "personal laptop"), choose the Authentication type and paste the key.
  5. Click Add SSH key. GitHub may ask you to confirm your identity.

On your own servers, the equivalent step is to append the public key line to the ~/.ssh/authorized_keys file of the user on the server.

How do you test that it worked?#

bash
ssh -T git@github.com

On the first connection, SSH shows a fingerprint and asks Are you sure you want to continue connecting (yes/no)?. Compare the fingerprint with GitHub's official fingerprints page before typing yes. If everything is right, the reply is:

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

The message mentions "no shell access" because GitHub only accepts Git commands. The command exits with code 1, and that is expected.

To clone over SSH, use a URL in the form git@github.com:user/repository.git.

What are the most common errors?#

Permission denied (publickey): the server did not recognize any key. Check that the public key is added to the right account, that the private key was added to the agent (ssh-add -l lists loaded keys) and that the remote URL uses git@github.com:, not https://.

Windows does not use the key loaded in the agent: Git may be using a different SSH binary, not the system one. Force Git to use the Windows client, where the agent holds the key:

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

Bad configuration option: usekeychain on macOS: add IgnoreUnknown UseKeychain to the same Host block in ~/.ssh/config.

How do you protect your private key?#

  • Never push the private key to a repository, chat or ticket. If that happens, treat it as leaked: remove the matching public key from GitHub and generate a new pair. The guide on an API key exposed on GitHub follows the same revocation logic.
  • Use a passphrase and one key per machine. That way, losing a laptop invalidates only one key.
  • Give each key a clear title on GitHub and delete the ones you no longer use.
  • For automation such as deploying with GitHub Actions, prefer credentials stored as secrets, never your personal key.
  • Go through the security checklist for shipping a bot, site or API.

How to do this on Square Cloud#

On Square Cloud you do not need an SSH key to deploy. The deploy options are a ZIP upload in the dashboard, the CLI, GitHub (a push deploys, through the official GitHub Action or a webhook) and the VS Code extension. The CLI logs in by approving a code in the browser or, in CI, reads the key from the SQUARECLOUD_API_KEY variable.

Outbound connections on port 22 are not allowed, so the application cannot open SSH to another server or clone a repository over git@. To reach a private repository, use HTTPS with a token. Keep that token, and any other secret, in the application's environment variables (set in the dashboard, API, CLI or VS Code), never in the code or the ZIP. A change applies on the next restart, with no rebuild.

See how to set them up in environment variables on Square Cloud.

Infrastructure

L3/L4/L7 DDoS mitigation and a WAF on every plan

Learn more

FAQs

What is the difference between a public key and a private key?

The public key can be shared and lives on the server or on GitHub. The private key never leaves your machine: it proves you own the public one.

Ed25519 or RSA: which should I pick?

Ed25519 is the type GitHub's documentation uses by default in its examples. Use 4096-bit RSA only if the system does not accept Ed25519.

Do I need a passphrase on my key?

It is recommended. It protects the private key file if someone copies it off your computer, and ssh-agent remembers it so you do not type it on every use.

I lost my private key. What now?

There is no way to recover it. Generate a new pair, add the new public key and remove the old one from GitHub or the server.

Next articleWhat is a brute force attack and how to defend against itA brute force attack tests passwords in bulk until one works. Learn the types (spraying, credential stuffing), how they work and the defenses, with code that runs.

More in Security

See all 10 articles