OpenSSH ships post-quantum key agreement today, with no extra library and no patch. The hybrid method mlkem768x25519-sha256 was added in OpenSSH 9.9 (2024-09-19) and became the default key agreement in OpenSSH 10.0 (2025-04-09). This guide shows how to read which method a session actually negotiated, how to prefer the hybrid method on builds that support it without defaulting to it, what the OpenSSH 10.1 warning about non post-quantum key agreement means, and why SSH host keys are still classical.
What mlkem768x25519-sha256 actually does
The name describes the construction. ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism, a KEM or key encapsulation mechanism) at parameter set 768, X25519 (elliptic curve Diffie-Hellman on Curve25519), and SHA-256 as the hash. NIST published ML-KEM as FIPS 203 on 2024-08-13 (FIPS 203), and the ML-KEM reference page lists its parameter sets and status.
The method is hybrid: the session key is derived from both the ML-KEM shared secret and the X25519 shared secret. A client and a server that negotiate it are protected as long as at least one of the two components holds. That is the conservative choice while post-quantum implementations are young, and it is what European guidance points to: hybrid key agreement rather than a pure post-quantum exchange.
Key agreement is the first priority in SSH for the same reason as in TLS. An attacker who records an encrypted session today can store it and attack it later. This is harvest now, decrypt later (HNDL), described in our article on harvest now, decrypt later. If the exchange was purely classical, a large enough quantum computer would let recorded traffic be decrypted retroactively. Authentication is different: an attacker able to forge a host signature has to use it during a live connection, so signature migration can follow later without exposing yesterday's sessions.
Step 1: check your versions and what your sessions negotiate
Which methods does the binary support
ssh -V
ssh -Q kex
ssh -Q kex | grep mlkem
ssh -Q kex lists the key exchange methods compiled into the binary, independently of configuration. If mlkem768x25519-sha256 appears, the build supports it. Both ends must support it, so run the same check on the server: a modern client talking to an old server falls back to whatever the two have in common.
Which method did this session use
ssh -v user@server 2>&1 | grep -i 'kex: algorithm'
Verbose output goes to standard error, hence the redirection. A session using the hybrid method prints a line of the form debug1: kex: algorithm: mlkem768x25519-sha256. This is the single most useful check, because it reports what was negotiated rather than what you believe is configured.
What is the effective configuration
ssh -G server | grep -i kexalgorithms
sudo sshd -T | grep -i kexalgorithms
ssh -G prints the client configuration that would apply to that destination, after all Host blocks and includes are resolved. sshd -T prints the effective server configuration and requires root. Run both before changing anything, and keep the output: it is inventory evidence.
The version timeline
| OpenSSH version | Release date | Change to key agreement |
|---|---|---|
| 9.0 | 2022-04-08 | The hybrid sntrup761x25519-sha512@openssh.com became the default key exchange (post-quantum, but not based on a NIST standard) |
| 9.9 | 2024-09-19 | mlkem768x25519-sha256 added (ML-KEM-768 with X25519), available by default |
| 10.0 | 2025-04-09 | mlkem768x25519-sha256 became the default key agreement |
| 10.1 | 2025-10-06 | Warns when a connection negotiates a non post-quantum key agreement (WarnWeakCrypto option, enabled by default) |
Source: the OpenSSH release notes. Practical reading: from 9.9 you already have the method available, from 10.0 it is preferred for you, and between 9.0 and 9.9 you still have post-quantum key agreement through sntrup761x25519-sha512@openssh.com.
Step 2: prefer mlkem768x25519-sha256 without breaking older peers
The directive is KexAlgorithms, used in ssh_config on the client side and in sshd_config on the server side. It accepts three prefixes: ^ prepends the listed methods to the built-in default list, + appends them, and - removes them. Prepending is the safe move, because the rest of the default list remains as a fallback.
Client, in ~/.ssh/config or a drop-in file under /etc/ssh/ssh_config.d/:
Host *
KexAlgorithms ^mlkem768x25519-sha256
Server, in /etc/ssh/sshd_config or a drop-in under /etc/ssh/sshd_config.d/:
KexAlgorithms ^mlkem768x25519-sha256
If you prefer an explicit ordered list, keep classical methods at the end so that peers which are not upgraded yet can still connect:
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org
Validate the configuration before reloading, and reload rather than restart:
sudo sshd -t
# the service name varies by distribution: ssh on Debian and Ubuntu, sshd on many others
sudo systemctl reload sshd
An order of operations that avoids lockouts: test in staging first, keep one privileged session open while you reload, then open a second session and re-run the ssh -v check before closing the first. Do not remove classical methods from a server list until every client that connects has been inventoried: jump hosts, automation runners, backup agents, monitoring probes, network appliances and embedded SSH libraries are the usual cause of an outage here.
Step 3: read the OpenSSH 10.1 warning correctly
OpenSSH 10.1 (2025-10-06) warns when a connection negotiates a non post-quantum key agreement. The option is WarnWeakCrypto and it is enabled by default. Two points matter for operations.
First, it is a warning, not an enforcement: the connection still completes. It tells you that the other end of the connection is the part that needs attention. Second, sntrup761x25519-sha512@openssh.com is itself a post-quantum hybrid, so a session negotiating it is not the case this warning targets. It is simply not built on a NIST standard, which is why ML-KEM is the direction of travel for interoperability and for procurement requirements.
Treat each warning as one line of inventory: which peer, which version, which team owns it. If you later want to refuse classical-only exchanges instead of warning about them, set an explicit KexAlgorithms list containing only post-quantum methods, and do that only once your checks show that every peer supports them.
Step 4: host keys stay classical for now
Key agreement and authentication are negotiated separately in SSH. Host keys and user keys are signature algorithms: ssh-ed25519, rsa-sha2-256, rsa-sha2-512 and ECDSA variants. The releases above changed key agreement, not host key types, so the realistic state today is a hybrid exchange protecting a session that is still authenticated with a classical host key. You can see which one was used on the same verbose output:
ssh -v user@server 2>&1 | grep -i 'host key'
That intermediate state is acceptable for the reason given earlier: signature forgery requires an attack during the connection, and it does not expose sessions recorded in the past. NIST standardized ML-DSA as FIPS 204 on 2024-08-13 (see the ML-DSA page), and SSH signature migration depends on further protocol and implementation work. Until then, record the gap instead of hiding it, prefer ed25519 host keys, and where RSA is used follow the key size guidance that applies to your organisation.
What to record for audits and inventories
SSH is often missing from cryptographic inventories that already cover TLS properly. PCI DSS v4.0.1 requirement 12.3.3 requires cipher suites and protocols in use to be documented and reviewed at least every 12 months, and it has been mandatory since 2025-03-31 (see PCI DSS v4.0.1). Under DORA, Commission Delegated Regulation (EU) 2024/1774 Art. 6 requires an encryption and cryptographic controls policy including provisions for updating or changing cryptographic technology based on developments in cryptanalysis, and Art. 7 requires key management across the whole lifecycle (see the DORA RTS page). What those texts literally require is the policy and the inventory. The mapping below is our interpretation of how to evidence it for SSH, not a quotation of any requirement. This is information, not legal advice.
| Evidence to keep | How to produce it |
|---|---|
| OpenSSH version of every client and server | ssh -V, collected by your configuration management tool |
| Effective key agreement list per server | sudo sshd -T filtered on kexalgorithms |
| Method negotiated on critical paths | the kex algorithm line from ssh -v, captured per flow |
| Host key algorithms in use | the host key line from ssh -v, or an inventory of host key files |
| Peers still negotiating classical-only exchanges | WarnWeakCrypto warnings collected from client logs |
| Date of last review and named owner | your inventory register, reviewed at least every 12 months |
Next step: check the rest of your surface
SSH is one protocol among several, and the same hybrid construction exists in TLS as X25519MLKEM768. The quickest way to see where your public services stand is to scan your domain with PQC Status, which reports the negotiated key exchange groups, the TLS versions and the certificate chain. Pair that result with the SSH checks above, one line per host, and you have the beginning of a real cryptographic inventory instead of an assumption.