Back to blog

SSH Host Key Verification: What TOFU Actually Protects You From

July 22, 2026 5 min read Kubexer Team
SSHSecurityTerminalHost Keys

Connect to a new server over SSH and you are asked a question almost nobody reads:

The authenticity of host 'web-01.example.com' can't be established.
ED25519 key fingerprint is SHA256:l8Kq...7Yc.
Are you sure you want to continue connecting (yes/no)?

The near-universal response is to type yes and move on. That is understandable — the prompt appears at the least convenient moment, offers no way to check the answer, and is worded as an obstacle rather than a question. But it is the only point at which SSH asks you to establish who you are actually talking to, and it is worth understanding what you are agreeing to.

The problem host keys solve

SSH encrypts your session, which protects the contents from anyone watching the wire. Encryption alone does not tell you who you are encrypting to. An attacker positioned between you and the server — on a shared network, through a compromised router, via DNS or BGP manipulation — can accept your connection, present their own encryption, and relay traffic to the real server. You get a perfectly encrypted session with the attacker in the middle, reading everything, including the password you type.

Every SSH server therefore has a host key: a long-lived keypair identifying the machine itself, distinct from any user key. During the handshake the server proves it holds the corresponding private key. The fingerprint is a hash of the public half, short enough to compare by eye.

The remaining problem is bootstrapping: on your first connection you have nothing to compare against.

Trust on first use

SSH's answer is TOFU — trust on first use. On the first connection the client shows you the fingerprint and asks you to accept it. Once accepted it is recorded, and on every subsequent connection the presented key is checked against the stored one. If it matches, you connect silently. If it does not, you get a loud warning.

It is worth being clear about what this model does and does not give you:

  • It does not verify the first connection. If an attacker is in position the very first time you connect, you will happily record their key as legitimate and never be warned again. TOFU cannot detect this.
  • It reliably detects change after that. Every subsequent connection is verified against what you recorded. An attacker who arrives later is caught.

TOFU converts an ongoing risk into a single moment of exposure. That is a genuine improvement, and it is why the first-connection prompt deserves more than a reflexive yes.

Verifying properly

The correct way to answer the prompt is to obtain the fingerprint through a channel that is not the connection you are trying to establish:

  • Read it from your provisioning output — cloud-init and most providers print host key fingerprints to the console log at first boot.
  • Read it from the cloud console's serial output.
  • Run ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub on the machine through an out-of-band channel and compare.
  • Take it from your configuration management, which provisioned the key in the first place.

If none of these is available, accepting is a considered risk rather than a verification — worth knowing which one you are doing.

When the key changes

The warning on a changed key is deliberately alarming. In practice there are three explanations, and they are not equally likely:

  1. The server was rebuilt or reinstalled. A fresh OS generates fresh host keys. This is by far the most common cause, and in ephemeral infrastructure it is routine.
  2. The address was reassigned. A recycled cloud IP or a reused hostname now points at a different machine, which legitimately has a different key.
  3. Someone is intercepting the connection. Rare, and the entire reason the check exists.

Because the first two are common and benign, the habit of clearing the stored key without thinking is easy to acquire — and it dissolves the protection entirely. The right response is to establish why the key changed. If you rebuilt the host an hour ago, you have your answer. If nothing changed and the key did, treat it as an incident.

How Kubexer Terminal handles it

Kubexer Terminal implements TOFU with the trust decision surfaced rather than buried:

  • The fingerprint is shown at connect time, in the staged connection overlay, alongside the other phases of establishing the session. You see what you are trusting as part of connecting, not as a modal interruption.
  • New and changed keys prompt explicitly, and the two cases are distinguished. A first-time key is a decision; a changed key is a warning.
  • Accepted keys are stored on the host record inside the connection vault — not in a separate global file. This has a useful consequence: because vaults sync between machines, the fingerprints you verified once travel with you. Setting up a new laptop does not mean re-approving every host from scratch, which is exactly the situation that trains people to click through the prompt.

The vault encryption model behind that is covered in encrypted SSH connection vaults.

The short version

The fingerprint prompt is asking whether you have any reason to believe the machine answering is the machine you meant to reach. Usually you do. Occasionally you do not, and that is the case the whole mechanism exists for. Verify the first one out of band where you can, and treat an unexplained change as what the warning says it might be.

Kubexer Terminal is available for macOS, Windows, and Linux.