Specifying which SSH key to use has three layers: -i on the command line for one-offs, IdentityFile in ~/.ssh/config for regular hosts, and IdentitiesOnly yes to force a specific key when the agent has multiple. The team that uses the config file for regular hosts and -i for one-offs has the right default. The team that relies on the agent to guess is debugging later.
Table of contents
- The -i command-line flag
- The IdentityFile ssh-config option
- Multiple keys and the agent
- The default key search
- Forcing a key from the agent
- Wildcard subdomains
- FAQ
The -i command-line flag
For one-off connections, the -i flag names the key file:
ssh -i ~/.ssh/id_ed25519_github [email protected]
ssh -i /tmp/keyfile.pem [email protected]
The -i flag is the right answer for:
- EC2 instances with downloaded
.pemfiles. - Throwaway environments with a specific key.
- Debugging (when the default key is wrong and the team wants to confirm).
The team that uses -i for every connection is typing too much. The team that never uses it is stuck when the default does not work.
The IdentityFile ssh-config option
For regular hosts, the right answer is ~/.ssh/config:
Host github.com
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
Host gitlab.com
IdentityFile ~/.ssh/id_ed25519_gitlab
IdentitiesOnly yes
Host myserver
HostName 203.0.113.42
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519_server
IdentitiesOnly yes
After this config, ssh github.com automatically uses the GitHub key, ssh gitlab.com uses the GitLab key, etc. The team that uses a config file does not type -i ever.
IdentitiesOnly yes is the important addition. Without it, the SSH agent sends every key it has loaded, and the server picks the first one that matches. With it, the client sends only the listed key, which is what the team wants when each host has its own key.
Multiple keys and the agent
When the SSH agent has multiple keys loaded (ssh-add -l lists them), the agent sends them in order to the server until one is accepted. That works for servers that accept any of the agent’s keys. It does not work when the server accepts only a specific key, or when the wrong key is being sent first.
The fix is IdentitiesOnly yes - the client skips the agent’s other keys and sends only the IdentityFile. This is the right default for any host with a dedicated key.
The team that uses one agent with many keys and no IdentitiesOnly config gets intermittent auth failures - the order changes when keys are added or removed.
The default key search
Without -i and without IdentityFile, the SSH client looks for these files in ~/.ssh/:
id_rsa, id_ecdsa, id_ecdsa_sk, id_ed25519, id_ed25519_sk, id_dsa
The first one that exists and is 600 is used. The team that has multiple keys with non-default names (no id_* prefix) is fine - SSH only looks at the standard names. The team that has both id_rsa and id_ed25519 has the SSH client send id_rsa first, which is the wrong behavior in 2026 - the team should be using ed25519.
Forcing a key from the agent
If the key is loaded into the agent (via ssh-add), the client uses it without reading the file. To force a specific agent key without naming the file:
# List keys in the agent
ssh-add -l
# Output: 256 SHA256:abc... id_ed25519_github (ED25519)
# Use it
ssh -o IdentitiesOnly=yes -o IdentityFile=~/.ssh/id_ed25519_github github.com
Or in config:
Host github.com
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
The team that uses the agent for storage but config for selection has the right setup - the agent holds the decrypted key in memory, the config picks which one to use per host.
Wildcard subdomains
The Host directive supports wildcards:
Host *.internal.example.com
User admin
IdentityFile ~/.ssh/id_ed25519_internal
IdentitiesOnly yes
Host *.github.com
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
The first match wins. The team that organizes their config by subdomain pattern keeps the file short even with hundreds of hosts.
FAQ
What is the difference between -i and IdentityFile?
Both name a key file. -i is the command-line flag for one connection. IdentityFile is the ~/.ssh/config option for hosts the team uses regularly. The team that has a config file uses -i only for one-offs.
Why does SSH still send the wrong key?
The agent is offering other keys. Add IdentitiesOnly yes to the host config to force the client to send only the listed key. The team that has multiple keys in the agent needs this for any host with a dedicated key.
Where does SSH look for keys by default?
~/.ssh/id_rsa, id_ecdsa, id_ecdsa_sk, id_ed25519, id_ed25519_sk, id_dsa. The first one that exists and is 600 is used. The team that wants explicit control uses IdentityFile per host.
Can I have different keys for different GitHub accounts?
Yes. Two SSH keys, two Host entries in ~/.ssh/config, one for each account. The team that uses ~/.ssh/config with Host github.com-work and Host github.com-personal and the right IdentityFile per entry can have both accounts on the same machine.
Does scp use the same -i flag?
Yes. scp -i ~/.ssh/key.pem file user@host:. Note the capital -P for port in scp (lowercase -p is for preserving timestamps in scp).
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: