Repository navigation
Conversation
A client with no ML-KEM is refused rather than downgraded. ML-KEM is post-quantum and on the bench fleet cost what curve25519 did - a login 40 against 39 ms (boot:ssh-first, lab run 43479854381) - while sntrup761x25519, what OpenSSH 8.5-9.8 picks, took 104. A client needs OpenSSH 9.9 or later, or x/crypto/ssh v0.38.0 or later with Go 1.24; image/README.md says so and who that leaves out. build.sh reads the drop-in back from the finished filesystem. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The runners' OpenSSH is 9.6, which has no ML-KEM, and the image's sshd now refuses it. The probe dials vsock itself and logs in with x/crypto/ssh offering mlkem768x25519-sha256 only - what spin's Go clients negotiate by default - so vsockproxy, its ProxyCommand, goes. A column counts the boots where a login offering only curve25519 got in: none on this image, every one on a release from before it. The rows that answered on the bench fleet are recorded beside the one left. boot:waits takes FLAGS, so TARGET=sshd-vsock.socket can be measured with a vsock device. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aledbf
marked this pull request as ready for review
November 13, 2026 18:30
This was referenced Nov 13, 2026
aledbf
added a commit
to spin-stack/open-remote-ssh
that referenced
this pull request
Nov 13, 2026
A workspace's sshd will accept one key exchange, mlkem768x25519-sha256 (spin-stack/spin-machine#245), and ssh2 has no ML-KEM, so the connection is the system's ssh: - one ControlMaster, carried by `spin tunnel <session>` as its ProxyCommand: the session is carried once, so everything rides on that login - the server's start as an exec through it, and each connection VS Code makes to the server as `ssh -W` through it; - held to the claim's host key as the one line of a known_hosts of its own, StrictHostKeyChecking yes, no global file; logged in with the certificate alone (CertificateFile, IdentitiesOnly, BatchMode); -F /dev/null, so nothing of the person's config changes what it is; and -o KexAlgorithms=mlkem768x25519-sha256; - `ssh -V` is asked first, and an OpenSSH older than 9.9 refused in VS Code before the CLI is run, naming the version found, the one needed and why, as the spin CLI does. An unreadable banner is let through with a line in the log. Windows is refused up front: there is no spin CLI for it, and OpenSSH for Windows has no ControlMaster. LogLevel is INFO, not ERROR: ssh says "no matching key exchange method found" at INFO, and that refusal is the one this change is about. ssh2, its types, its patch and the test of its internals go. The tests run OpenSSH on both ends: a real sshd set up as a workspace's (certificates only, ML-KEM alone), which the connection logs in to, refuses another principal's certificate and another host key, and cannot negotiate with an sshd that has no ML-KEM; the resolve test drives the real ssh through a wrapper that records each run and logs in as the test's user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
sshd in the image accepts one key exchange,
mlkem768x25519-sha256, and refuses a client without ML-KEM (no matching key exchange method found).Why (bench fleet,
boot:ssh-first, 20 boots per row, alternated):ML-KEM is post-quantum and costs the same as curve25519; sntrup761 (what OpenSSH 8.5–9.8 negotiates) costs ~28 ms on the first login and ~60 ms on every later one. Runs: 43463472762, 43479854381.
Client contract (in
image/README.md): OpenSSH ≥ 9.9, orgolang.org/x/crypto/ssh≥ v0.38.0 built with Go ≥ 1.24. Thessh2npm package (≤ 1.17.0) has no ML-KEM.Do not merge before the clients move: open-remote-ssh uses
ssh2and would stop connecting;spin sshuses the user's OpenSSH and needs ≥ 9.9.Also:
boot:ssh-firstnow logs in with x/crypto/ssh over vsock (the runners' OpenSSH 9.6 is refused) and counts whether a curve25519-only login got in: 0 of 5 on this image, locally.boot/vsockproxyis removed;boot:waitstakesFLAGS.🤖 Generated with Claude Code