cmux-rd host: systemd socket admission for Cloud desktops, plus a Linux release workflow
cmux-rd host gets the production Cloud admission mode. systemd passes the host a root-only Unix socket, and only the machine's root link receiver may connect, after it has admitted the owner with the owner's one-time link token for service desktop. A new release workflow publishes cmux-rd for x86_64 Linux so Cloud images can install it.
Leo, 2026-11-05: "Also go check in on the state of affairs of screen sharing remotely on these machines, like the cloud machines, because there was so much VNC work. But it's also like, I feel like it wasn't really linked up end to end here, and we have an opportunity quite soon to start doing that. [...] And then it became AI computer use!!" Also, on cmux#36080: "is that really necessary? can't you both do it at the same time?", and his standing order: "don't stick it into dev. Put it into prod".
Changelog
none (host and release plumbing; the Cloud desktop becomes visible with the app slice)
What changes
cmux-rd host --listen-systemd --peer-uid N (Linux) (new src/systemd.rs, src/host.rs)
- The host takes its one listening socket from systemd (
LISTEN_FDS=1,LISTEN_PID= self, fd 3). It refuses to start without those, or when the passed fd is not a listening Unix stream socket. It marks the fd close-on-exec and clearsLISTEN_*. --peer-uidis required. Each accepted connection'sSO_PEERCREDuid must equal it, or the connection is shut down before a byte is read.- No TCP or UDP listener in this mode.
--token-fd,--bind,--port,--single-tenant-overlayand--upstream-recordare refused. - The hello token is not checked, because the link already admitted the owner. The principal is the machine owner, a person at the app (
--owner, defaultowner), and the hello's user/class/interactive claims are ignored. Thestartmode picks view or control. A hello that asks for UDP is refused withStreamCarrierOnly. --xauthority PATHsetsXAUTHORITYfor the X connections.--idle-exit-s(default 120): with no connection for that long the host exits, and socket activation starts it again.- Every other mode works as before.
SocketCarrierandserve_viewerare now generic over the stream (TCP or Unix). The TCP path keeps its token check, peer check and UDP carrier. - README: a new "Security: Cloud machines (production)" section describes this mode. The phase-1 section is now marked development.
.github/workflows/cmux-rd-release.yml (pattern of cmux-browser-host-release.yml)
- Triggers: a tag push
cmux-rd-v*, orworkflow_dispatchwith inputtag. The tag must match the crate version and sit on feat-cmux-next. - Builds
cmux-rdforx86_64-unknown-linux-gnuwith--no-default-features --features openh264,link(nobench, nox264), through cargo-zigbuild at the glibc 2.31 floor. It checks the glibc symbols and fails if the binary defines any x264/OpenH264 codec symbols. It runs the crate tests first. - Publishes
cmux-rd-<version>-x86_64-unknown-linux-gnu.tar.gzandchecksums.txt(sha256) as prereleasecmux-rd-v<version>, with a build-provenance attestation. - The archive holds
bin/cmux-rd,LICENSE(GPL-3.0-or-later) andTHIRD_PARTY_LICENSES.md. The notices come fromscripts/release.py notices, using the build's exactcargo treethroughbuild-support/notices/rust_notices.py. They cover the Rust std, Zig compiler_rt/musl and glibc, and they say that OpenH264 is not in the archive (cmux-rd openh264-installdownloads Cisco's binary on the machine). One review choice is local to this binary:openh264-sys2's BSD-2-Clause text inupstream/LICENSE. - Runners read the Linux pool.
.github/warm-sources.jsongets a cold entry.
What ran
- Fleet Linux (
cmux-ci test --setup rust, run 42008007660, SUCCESS):cargo build --locked --release --no-default-features --features openh264,link --bin cmux-rdpassed.cargo test --locked(default features): 14 passed, 1 ignored.cargo test --no-default-features --features openh264,link systemd: 7 passed.
- New tests:
- Missing
LISTEN_FDS/LISTEN_PIDrefuses. - A wrong pid or a count other than 1 refuses.
- A passed fd that is TCP, unconnected or not a socket refuses.
- A listening Unix socket is taken and set close-on-exec.
- A peer uid mismatch closes with nothing sent back.
- The expected uid is admitted.
- The idle accept times out.
--listen-systemdparses as a value-less flag.
- Missing
release.py noticesgenerated a 65-crate notices file from the releasecargo tree, andrelease.py packagewrote the archive layout above.- Workflow guards
test_ci_linux_single_size,test_ci_overflow_pick_reads_poolandtest_ci_warm_sourcespass,test_ci_upload_artifact_retentionreports nothing for this file, and actionlint is clean.
The systemd units, the receiver's desktop service, the platform capability and the app pane are separate PRs.
Agent session: agent session
🤖 Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Adds the production Cloud admission mode to cmux-rd host: systemd passes a root-only Unix socket, and only the machine's root link receiver may connect, after it admitted the owner with the owner's one-time link token for service desktop. A new release workflow publishes cmux-rd for x86_64 Linux so Cloud images can install it.
Cloud admission (--listen-systemd)
- The host takes its one listening Unix socket from systemd (
LISTEN_FDS/LISTEN_PID, fd 3) and refuses to start without it or when the fd is not a listening Unix stream socket. - Each accepted connection's
SO_PEERCREDuid must equal--peer-uid; anything else is closed before a byte is read. The check keeps out non-root processes only; the link admission is the real boundary. - No TCP or UDP listener:
--token-fd,--bind,--port,--single-tenant-overlay,--upstream-record,--browser, and--browser-cdp-portare refused. - The hello token and its user/class/interactive claims are ignored: the link already admitted the owner, so the principal is the machine owner (
--owner, defaultowner), and view/control come from the start mode. A hello asking for UDP is refused withStreamCarrierOnly. --xauthoritysetsXAUTHORITYfor the X connections;--idle-exit-s(default 120) makes the host exit when idle so socket activation restarts it.SocketCarrierandserve_viewerare now generic over the stream; the TCP path keeps its token check, peer check, and UDP carrier.
Linux release workflow
- Runs on a
cmux-rd-v*tag (or dispatch), builds x86_64-unknown-linux-gnu withopenh264,link(no bench, no x264) at the glibc 2.31 floor, and fails on any x264/OpenH264 codec symbols in the binary or when the symbol table is too empty to check. - Publishes
cmux-rd-<version>-x86_64-unknown-linux-gnu.tar.gzandchecksums.txtas prerelese, with build-provenance attestation; re-runs never replace already-published assets. - The archive holds
bin/cmux-rd,LICENSE, andTHIRD_PARTY_LICENSES.mdgenerated from the build's exactcargo tree; OpenH264 stays a runtime download on the machine, not in the archive.