Skip to main content

SSH Keys

SSH keys provide secure, passwordless authentication for git operations (push, pull, clone) over SSH. When you add an SSH public key to your JJHub account, JJHub’s SSH server matches the key fingerprint on every connection, letting you interact with any repository you have access to without entering a password or token.

Why SSH Keys

  • No passwords: Once your key is registered, git operations authenticate automatically. No credentials to type, paste, or rotate.
  • Strong cryptography: SSH keys use public-key cryptography. Your private key never leaves your machine — only the public key is stored on JJHub.
  • Works everywhere: SSH is supported by every major operating system and git client, including jj’s git backend.
  • Multiple keys: You can register multiple SSH keys on your account — one per machine, one per role, or however you prefer to organize access.

Supported Key Types

JJHub accepts the following SSH key types: Recommendation: Use Ed25519 unless you have a specific reason to use another algorithm. Ed25519 keys are shorter, faster to verify, and resistant to several classes of implementation vulnerabilities that affect RSA and ECDSA.

Generating an SSH Key

If you already have an SSH key you want to use, skip to Adding Your SSH Key to JJHub.

macOS and Linux

Open a terminal and run:
When prompted for a file location, press Enter to accept the default (~/.ssh/id_ed25519). When prompted for a passphrase, enter a strong passphrase (recommended) or press Enter for no passphrase. This creates two files:
  • ~/.ssh/id_ed25519 — your private key (never share this)
  • ~/.ssh/id_ed25519.pub — your public key (this is what you add to JJHub)
Start the SSH agent and add your key:
On macOS, you can add the key to your Keychain so the agent loads it automatically on login:
And add the following to your ~/.ssh/config to load keys from Keychain automatically:

Windows

Using Git Bash or WSL: The same commands from the macOS/Linux section work in Git Bash and WSL:
Using PowerShell (OpenSSH): Windows 10+ includes OpenSSH. Open PowerShell as administrator and ensure the SSH agent service is running:
Then generate your key:

Using RSA (if Ed25519 is unavailable)

Some older systems do not support Ed25519. In that case, generate an RSA key with at least 4096 bits:
The resulting files will be ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub.

Adding Your SSH Key to JJHub via CLI

Copy your public key and add it using the jjhub ssh-key add command:
Use a descriptive title so you can identify the key later — for example, the name of the machine it belongs to.

Adding Your SSH Key via API

You can also register SSH keys through the JJHub API directly:
Response (201 Created):
Error cases:
  • 400 — Missing required fields (title, key)
  • 401 — Not authenticated
  • 409 — Key already exists on your account
  • 422 — Invalid SSH public key format or unsupported key type

Listing Your SSH Keys

Via CLI

Example output:

Via API

Response:

Deleting an SSH Key

Via CLI

The positional argument is the key ID, which you can find from jjhub ssh-key list.

Via API

Returns 204 No Content on success.

Testing Your SSH Connection

After adding your key, verify that JJHub recognizes it:
If your key is configured correctly, you will see a message like:
If you get a Permission denied error, see Troubleshooting below.

Using SSH with jj

Once your SSH key is registered, you can clone, push, and pull repositories over SSH.

Cloning a repository

Pushing changes

jj uses the remote URL stored in the repository configuration. If you cloned over SSH, pushes automatically use SSH.

Setting SSH as your default protocol

If you want the CLI to always generate SSH clone URLs:
This is the default. To switch to HTTPS instead:

Multiple SSH Keys

If you use multiple JJHub accounts (for example, a personal account and a work account), or if you want to use different keys for different hosts, configure SSH to select the right key automatically.

SSH Config for Multiple Accounts

Edit ~/.ssh/config to define host aliases:
Then clone using the alias:
The IdentitiesOnly yes directive ensures SSH only offers the specified key, preventing the agent from trying other keys and hitting authentication failures.

Testing a specific key

Troubleshooting

Permission denied (publickey)

This means JJHub’s SSH server did not accept any of the keys your SSH client offered. Check that your key is added to JJHub:
If your key is not listed, add it:
Check that the SSH agent has your key loaded:
If your key is not listed, add it:
Check that you are connecting to the right host:
The verbose output (-v) shows which keys SSH is offering and whether the server accepts them. Look for lines like Offering public key and Server accepts key.

Wrong key being used

If you have multiple keys and SSH is offering the wrong one, use an SSH config file to specify which key to use for JJHub:
The IdentitiesOnly yes directive prevents the SSH agent from offering other keys.

SSH agent not running

If ssh-add -l returns Could not open a connection to your authentication agent, the SSH agent is not running. macOS/Linux:
Windows (PowerShell):

Key format not supported

JJHub accepts Ed25519, ECDSA, and RSA (2048+ bits) keys. If you receive a 422 error when adding a key, check:
  • The key is a public key (not the private key). Public key files end in .pub.
  • The key format is supported. DSA keys and RSA keys smaller than 2048 bits are rejected.
  • The key string is complete and has not been truncated. Public keys are a single line — make sure no line breaks were introduced when copying.

Connection timeout

If ssh -T ssh.jjhub.tech hangs without responding:
  • Check that your firewall or corporate network allows outbound SSH connections (port 22).
  • Try connecting on an alternate network to rule out network-level blocking.
  • Verify DNS resolution: nslookup ssh.jjhub.tech should return an IP address.

SSH Keys vs Other Authentication Methods

Personal SSH keys are the right choice for day-to-day development on your own machine. For automated systems that need access to a single repository, use deploy keys instead.

API Reference