Repository navigation
Releases
podssh v1.1.0-beta.3
podssh v1.1.0-beta.3
The third beta of milestone M10, and the first one after the study of osewa
(docs/research/osewa.md): what a user feels on a slow or busy link is now
measured, and podssh's SSH client keeps a key's echo near the link's round
trip while a download runs on the same connection, against any sshd and
through each road; a session resumes in about a second after the client
moves; and a cold connect takes two round trips fewer. The relay role
gains the hardening that a tester asked for (GitHub #126 to #148). A beta is
a prerelease. Its tag never moves: a defect found in it goes into the next
beta.
What to test again
What a user feels (the study of osewa, Q99):
podssh ping DEST --under-loadtypes 40 keys beside a download on the
same connection and gives the echo's p50 and p95;--connect-runs N
times N cold connects (T-660).scripts/feel-matrix.pyruns each road
through the four links of osewa's lab on the loopback.- Typing-aware SSH windows: while a key waits for its echo, a bulk
channel's window is held to the path's round trip and 40 ms, and each
socket that podssh dials keeps 16 KiB unsent; where nobody types, a
window grows to the path, up to 16 MiB on--direct(T-661, T-662). The
server's messages are of 8 KiB, and a window is topped up once a quarter
of it is used (T-670). Measured on the loopback, a key's echo beside a
download: about 100 ms on a cellular link where OpenSSH's is 1.6 s, and
0.4 s on a link of 1 Mbit/s where OpenSSH's is 16 s. The download while
typing on a long fast link is slower than before (T-670, partial). - Liveness in round trips: a spare link after three round trips of
silence, 1 s to 3 s, and a check when the host wakes; a session resumed
in 1.0 s after the client's new address, where it took 3 s (T-663). - A faster cold connect: the key that a host took is signed in the first
request, the pty's request and the command's go together, and a relay
host's TLS group is kept (T-664): two round trips fewer, faster than
OpenSSH's own client to the same sshd on the loopback's links. - The resumable layer ends one direction (
END), so a request, its end and
the reply after it cross the relay role's layer road (T-632). - The iroh road:
PODSSH_IROH_QUICchooses QUIC's settings at both ends
(iroh's own by default,tuned,bbr,newreno; T-665, partial: the
default waits for an A/B run), and the SSH connections of one process to
one node share one iroh connection, a copy's stream below a terminal's,
once both ends agree onpodssh/2(T-666, partial). - The record of the keys that hosts took keeps each host's key when
podssh eachlogs in to several at once (T-675).
The relay role, podssh relay serve (GitHub #126 to #148):
- A name that the role does not dial gets one
403that names no address
(T-628, #126). - It keeps no capability after its bind (T-629, #127); a list of private
ranges that it may dial,--routes(T-635, #133); a share of the pairs
for each key that may mint (T-630, #128); a turn for each session on a
node's socket (T-648, #146); a target's bytes after the client's Close,
as the contract says (T-671); a pair that halts without ending,
podssh relay haltandrelay resume(T-647, #145). podssh pipe ws-listen:answers a request that is not an upgrade with a
page from--cover DIR, and an upgrade with no key with--raw-upgrade
(T-639, T-645, #137, #143).- A retired
PODSSH_*variable is refused by name (T-634, #132); a node's
lines keep their priority in the journal (T-640, #138).
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float, static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Check a download
T=v1.1.0-beta.3; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.1.0-beta.3 (the commit of the tag)podssh update --version v1.1.0-beta.3 from v1.1.0-beta.2, v1.1.0-beta.1 or v1.0.1
takes it, checked by its signature; a build of a release follows releases
alone, so without --version it stays on v1.0.1. The provenance and the
signature are checked as for v1.0.0 (its notes),
with T=v1.1.0-beta.3.
How it was checked
By the operator's ruling Q88 (2026-11-03), until podssh is stable: the gate
green at the tag's commit, the release workflow by hand on it, and the short
form of its binary (scripts/release-short.sh BINARY --net); after the tag,
release-proofs.yml and update-live.yml. The whole release check and the
live runs of each road wait until then.
What a beta does not have yet
- The whole check of a release from end to end with no human
(scripts/release-check.sh, T-251): it waits (Q88). - Signatures of the platforms: the Mac binaries are not signed with an
Apple Developer ID, and the Windows binaries carry no Authenticode
signature, so SmartScreen may warn. The proofs above stand in for them.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Other
- Research: osewa against podssh, the reality check (Q99); its gaps filed as T-660 to T-669 (856940b)
- The record: the ninth round of drafts, in progress (the triage of #127 to #148, T-660 to T-663) (0b7f303)
- Triage: GitHub #127 to #148 as T-629 to T-650 (Q100) (6d90d04)
- WARP's tests: a stand-in edge forgets what an earlier test met at its port (7e6b9bc)
- The record: the citations of road.rs and stand_in.rs moved with the repair of WARP's tests (c65cfc4)
- node_cut's test: the stand-in's late close gives the node the 1003 that its frame would get (fb018a7)
- T-660, partial: what a user feels, measured: ping --under-load and --connect-runs, osewa's four links, and the matrix of roads (a940886)
- T-663 done: liveness in round trips: a spare link after three round trips, and a check when the host wakes (b7f78d6)
- T-661 done, T-662 partial: typing-aware SSH windows against any sshd, and windows that grow to the path (1525a6c)
- v1.1.0-beta.2 published (Q98): STATUS marks its 80 rows; the proofs of its published files passed (release-proofs 41892109498, update-live 41892114409) (6971076)
- T-632 done: the resumable layer ends one direction: END, and podssh proxy's stdin on it through the relay role (c3a9b89)
- T-629 and T-635 done: relay serve keeps no capability after its bind, and a list of private ranges that it dials (GitHub #127, #133) (ce411ac)
- The record: GitHub #127 and #133 closed with T-629 and T-635 (ce411ac) (3775c2f)
- T-630 and T-648 done: a key's share of the relay role's pairs, and a turn for each session on a node's socket (GitHub #128, #146) (4ae2284)
- The record: GitHub #128 and #146 closed with T-630 and T-648 (4ae2284) (df92546)
- T-664 done: a faster cold connect: the key a host took signed in the first request, the pty's request and the command's together, the TLS group kept (b9cfebc)
- T-671 and T-647 done: the relay role keeps a target's bytes after the client's Close, and a pair halts without ending (GitHub #145) (8caa6f0)
- The record: GitHub #145 closed with T-647 (8caa6f0) (8f6fa3a)
- T-670, partial: the slow link's echo beside a download, from 2.4 s to 0.4 s by --direct (a6a1de0)
- T-634 and T-640 done: a retired PODSSH_* variable refused by name, and a node's lines keep their priority in the journal (GitHub #132, #138) (91669ae)
- The record: GitHub #132 and #138 closed with T-634 and T-640 (91669ae) (bc22f0f)
- T-639 and T-645 done: pipe ws-listen serves a cover page, and takes a keyless upgrade...
podssh v1.1.0-beta.2
podssh v1.1.0-beta.2
The second beta of milestone M10: the relay as a role of podssh itself
(podssh relay serve) and the net of a user's own nodes grow by many
parts, and the default list of relay hosts takes a rank that this host
measured. A beta is a prerelease. Its tag never moves: a defect found in it
goes into the next beta.
What to test again
The relay role, podssh relay serve:
- A proxy that refuses the WebSocket upgrade: the HTTP road carries the
session in plain requests, where a probe found the upgrade refused
(T-319, its first part; Q44). - HTTP/2: a host's sessions of one process are streams of one TLS
connection, the WebSocket over extended CONNECT (RFC 8441), with
HTTP/1.1's upgrade where the server does not offer it;PODSSH_H2
chooses,doctornames the ALPN (T-321, its first part). - A cleartext road on port 443, tried after the TLS road fails (T-326).
- A standard sshd's session across a drop of the client's link:
podssh proxyandpodssh sshtake the role's road in the resumable layer where
the first host offers it, its offer kept for a day;PODSSH_RELAY_LAYER=yes
reads the offer at each run and says each case,noturns the road off;
--resume-budget,--resume-deadlineand--resume-hostbound and name
it (T-173). On that road, the end ofpodssh proxy's stdin stops sending
and keeps receiving until the target closes, as on the contract's road; a
relay host that the user named, whose offer is not kept, costs the session
one read of 1 s at most, once a day. - A connect token for each leg of a session, and a stop token that the node
rotates (T-615); a pair that its owner renews in the role (T-592). - A planned stop that no session feels (T-255); a bound on what waits for a
slow reader (T-336); the role's dials through the host'sHTTPS_PROXY
(T-457); its mint for the members of the net (T-455); its IPv6 targets,
anddoctor's lineipv6(T-253). - Relay hosts outside the default domain from a list of deployments that a
trusted key signs (T-346). podssh doctor --stream: what the path does to a stream (T-325).- A name that the role does not dial (it does not resolve, or resolves to
an address that is not public, or has none of the family asked for) gets
one403that names no address; the role's line keeps the cause (T-628,
GitHub #126).
The net and its nodes:
podssh net inviteandpodssh net join: a new device joins the net by
a short code (T-616); pairing by a short one-time code given out of band
(T-086); grants that are signed and used once (T-226, GitHub #35).- Routes: a node reaches its private networks for the net,
--exit auto
picks the exit whose routes hold the target, and an exit never dials its
own addresses (T-432). ssh,proxyandpipetake--exitbeside--carrier(T-614,
GitHub #124), the exit over a carrier (T-596), andpodssh doctor --exit NAME(T-458).--no-resume, a session to a node that ends with its link (T-612);
--timeoutandPODSSH_TIMEOUTonoperator,proxyandpipe
(T-613).- A copy to a node races the roads that
podssh sshraces (T-551); the
quick tunnel's node takes its net's members as its door (T-550);
OpenTunnel's road at the node and the client (T-530, T-531). - A client's lost link during a node's bulk costs the node's other sessions
no backoff (T-421).
Relay selection:
podssh relay rankmeasures each relay host from this host and keeps the
rank (T-606); the default list takes it, with the samples of each race
(T-607);RelayRank autoranks in a session's background, at most once a
day for each egress (T-608, Q89);relay infosays that the pool's order
is the relay's (T-610, GitHub #125), namespodssh relay rank, and says
the order that a run from this host takes (T-618).- A relay member of the net names its host, and each end of the net takes
the role's signed list with no--relay-host(T-617);podssh ping NAME
races a node's roads and says each one's time,podssh status --netlists
each member, anddoctorhas the sectionsnetandcarriers(T-435).
Repairs:
- An ECDSA key of P-256 whose scalar OpenSSH writes in 31 bytes is read
(T-609); a roost on a host with no sshd says so, anddoctorhas a line
for a roost (T-590, GitHub #116);doctor's diagnosis of the TLS
handshakes counts the resolvers of DNS over HTTPS and n0's relays
(T-604); on WARP's road, the end of a stream waits for the bytes that the
far side has not acknowledged yet, so a large echo no longer stalls
(T-599). podssh pipe -vsays, for each direction, when its input ended and how
the other side took the shutdown (T-465).
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float, static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Check a download
T=v1.1.0-beta.2; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.1.0-beta.2 (the commit of the tag)podssh update --version v1.1.0-beta.2 from v1.1.0-beta.1 or v1.0.1
takes it, checked by its signature; a build of a release follows releases
alone, so without --version it stays on v1.0.1. The provenance and the
signature are checked as for v1.0.0 (its notes),
with T=v1.1.0-beta.2.
How it was checked
By the operator's ruling Q88 (2026-11-03), until podssh is stable: the gate
green at the tag's commit, the release workflow by hand on it, and the short
form of its binary (scripts/release-short.sh BINARY --net); after the tag,
release-proofs.yml and update-live.yml. The whole release check and the
live runs of each road wait until then.
What a beta does not have yet
- The whole check of a release from end to end with no human
(scripts/release-check.sh, T-251): it waits (Q88). - Signatures of the platforms: the Mac binaries are not signed with an
Apple Developer ID, and the Windows binaries carry no Authenticode
signature, so SmartScreen may warn. The proofs above stand in for them.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Other
- T-561: done, WARP's road tries the record's endpoint, then the API's peers (GitHub #108) (c5299c2)
- GitHub #108 closed: T-561 done (c5299c2); warp-live.yml dispatched for its live step (365dbd1)
- T-562: done, WARP's API by its routes in turn (GitHub #109); T-561's live run read and its step repaired (cde307f)
- T-564: done, podssh raises its soft limit of open files at start, within the hard one (GitHub #111) (5b643b1)
- T-489: done, chat --listen --linger stays for each peer after its stdin ended (GitHub #102) (ea2a70b)
- WARP live at cde307f (run 41597035711): T-561's turn proved, T-562's second API name registers a device; GitHub #102, #109 and #111 closed (36d1f31)
- T-483: done, http-listen: takes ssh:HOPS with no target, and pipe --help shows the proxy of an SSH server (GitHub #93) (7417676)
- GitHub #93 closed: T-483 done (7417676) (5ff6809)
- T-488: done, podssh mcp offers cp, job, health and session as tools, behind the gate of ssh_exec (GitHub #101) (f8eaeb4)
- GitHub #101 closed: T-488 done (f8eaeb4) (9694d0c)
- Drafts: T-561, T-562, T-564, T-489, T-483 and T-488 merged and closed; their worktrees removed (477b47c)
- T-599: the stack's driver polls at once for packets in that smoltcp left while the queue out was full (partial: the loop under load runs) (02ece60)
- T-590: done, a roost that the loopback refuses says whether this host has an sshd, and doctor's line sshd (GitHub #116); the manual's notes repaired; release-proofs reach a beta by --version (279a283)
- GitHub #116 closed: T-590 done (279a283) (0d0c22c)
- T-474: done, cp copies s...
podssh v1.1.0-beta.1
podssh v1.1.0-beta.1
The first beta of milestone M10: v1.0.1 and the repairs of the defects that
its testers filed after it (GitHub #112, #114 and #118). A beta is a
prerelease. Its tag never moves: a defect found in it goes into the next beta.
What to test again
- Short logins through a node, with OpenSSH's
ProxyCommand=podssh operator:
operator,pipewith anode:side andssh node://take SIGHUP and
SIGTERM (and SIGINT, but forssh) as the end of their bytes and close the
node's session, so a run of logins no longer fills the node's budget. The
refusal of a full budget says what holds it (T-586, #112). ssh node://from a Windows client: the question of a new host key no
longer counts against ConnectTimeout and has its bound on the console, and a
handshake that does not finish says what came, the bytes through the layer
and the channel among them; 10 s in, a line says where it is (T-588, #114).- A node or a client run as root with
HOMEof another account: the cache
passes over a place in another user's tree, takes the home of the uid's
entry in the user database, and reads what it kept there before without
moving it;podssh statusgivescache.passed(T-593, #118).
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float, static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Check a download
T=v1.1.0-beta.1; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.1.0-beta.1 (the commit of the tag)podssh update --version v1.1.0-beta.1 from v1.0.1 takes it, checked by
its signature; a build of a release follows releases alone, so without
--version it stays on v1.0.1. The provenance and the signature are checked
as for v1.0.0 (its notes),
with T=v1.1.0-beta.1.
How it was checked
By the operator's ruling Q88 (2026-11-03), until podssh is stable: the gate
green at the tag's commit, the release workflow by hand on it, and the short
form of its binary (scripts/release-short.sh BINARY --net); after the tag,
release-proofs.yml and update-live.yml. The whole release check of
v1.0.1 and the live runs of each road wait until then.
What a beta does not have yet
- The whole check of a release from end to end with no human
(scripts/release-check.sh, T-251): it waits (Q88). - Signatures of the platforms: the Mac binaries are not signed with an
Apple Developer ID, and the Windows binaries carry no Authenticode
signature, so SmartScreen may warn. The proofs above stand in for them.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Other
- T-584: step 2, v1.0.1's release check before the tag passed at 6ece1f9 (43 passed, 6 skipped), each of its 21 runs green (62d26dc)
- Q88: move fast, the expensive checks wait until podssh is stable; T-584: done, v1.0.1 published at 6ece1f9 (bd3b9e0)
- Record: the citations of docs/STATUS.md moved with its intro's lines on v1.0.1 (cargo todo remap) (b5a0709)
- T-586: done, a signal ends operator, pipe node: and ssh node:// with a CLOSE, and a node charges a closing session its unacknowledged bytes (GitHub #112) (84864f2)
- T-588: done, a handshake that does not finish names what came, and the question of a new host key leaves ConnectTimeout and has its bound on Windows (GitHub #114) (ef50f8b)
- T-593: done, the cache passes over a place in another user's tree, takes the passwd home's, and only reads what was kept there (GitHub #118) (2f87d7b)
- Repair CI: the layer's session future on the heap (exit's stack overflow, T-586); roost's SIGHUP test Unix's alone; T-599 filed (bfd8f7d)
- v1.1.0-beta.1 made ready (T-446): the version 1.1.0-beta.1 and the notes (5d95e5f)
podssh v1.0.1
podssh v1.0.1
The repairs of the defects that the testers of v1.0.0 found (GitHub #83 to
#111, and the report of the operator's testing agents of 2026-11-02), with the
work of milestone M10 that main holds since v1.0.0: podssh's own relay
role, the net of an owner's nodes, and more roads. Its tag never moves: a
defect found in it goes into the next release.
The repairs
- SSH to a server of Go's x/crypto/ssh: a reply to a keepalive or to
-R
that carries data no longer ends the connection (T-460, #83, #85). podssh sshexits 255, not the far command's status, when the link ends
after the status and before the output's end (T-461, #84).- A
-Jhop whose channel opens and carries nothing is named, within
ConnectTimeout (T-462, #86). - A connection that ends right after the login is no longer read as a
refused session; a refusal gives OpenSSH's words of its reason (T-464,
#104). sftp'slsgives OpenSSH's long form, and its switches act (T-471, #89).cp --deltasays why it sends a whole file, and makes the temporary file
by one command where the server has nocopy-data(T-470, #87).cp -rsays each failure once, and a device, FIFO or socket is a skip with
exit 0, not 66 (T-476, #105).healthgives a container's CPUs and memory from its cgroup beside the
host's (T-480, #88).- The login name comes from the user database when
USER,LOGNAMEand
USERNAMEare unset (T-500). --suends su's read when its password cannot be given (T-501).-o ProxyCommand=nonegoes past a file'sProxyCommand, and the first
value of a file holds (T-502).- Each host that is dialed,
-J's hops among them, is checked before
anything connects, on each road (T-503). eachrefuses a blank that would part two hosts of the command line (T-504).- The keywords of a restriction (
Ciphers,MACs,KexAlgorithms,
HostKeyAlgorithms,PubkeyAcceptedAlgorithms,CASignatureAlgorithms,
RequiredRSASize) apply (T-505). session listanddetached listsay on stderr that none is there, and
take--json(T-506).updatenames the move of the kept file as the way back, and--rollback
only for a release that has it (T-507).- The fallback to other products' forwarders follows only a failure where no
relay host answered about the target (T-509, #106). - The relay's record keeps a host that opens, rests one cut short twice, and
keeps each road apart (T-563, #110). - WARP's road proves a packet through its tunnel before it is open (T-560,
#107). - A warning before the relay's idle cut, and
--idle-warn SECONDS(T-463,
#98).
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float, static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Check a download
T=v1.0.1; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.0.1 (the commit of the tag)podssh update from v1.0.0 takes it, checked by its signature. The
provenance and the signature are checked as for v1.0.0
(its notes),
with T=v1.0.1.
The sizes
The sizes of the release's dry run of 2026-11-03 (at 3bb42ea, the code of this tag: the commits
after it change tests and the record alone, run 41563962586), beside v1.0.0's published files.
They grew with the work of M10 that main holds: podssh's relay role, the net of nodes, and the
new roads.
| Binary | v1.0.0 | v1.0.1 |
|---|---|---|
| Linux x86-64 | 15.7 MiB | 17.2 MiB |
| Linux aarch64 | 12.1 MiB | 13.2 MiB |
| Linux armv7 | 9.1 MiB | 10.0 MiB |
| Linux riscv64 | 12.1 MiB | 13.3 MiB |
| macOS, Apple silicon | 9.5 MiB | 10.4 MiB |
| macOS, Intel | 12.6 MiB | 13.9 MiB |
| Windows x86-64 | 12.3 MiB | 13.6 MiB |
| Windows ARM64 | 10.8 MiB | 11.9 MiB |
How it was checked
As v1.0.0: the release check of T-251 (scripts/release-check.sh) ran before the tag on the
release's dry run and a build of its own, and runs again on the published files, the checksums,
the signature of SHA256SUMS and the provenance of each binary first; then the README's first
steps, doctor, proxy and ssh through the live relay, the reverse road with two sessions at
once, cp of 200 MiB each way through a node, pipe, the iroh road through n0's relays, the
static binary in a fresh container and in a box like the target sandbox, the Tailscale runs
against headscale, the throughput run, IRC against ngircd, and the planted defect of each check.
GitHub's runners ran the rest: Windows and macOS, the box, WARP's road, Cloudflare's edge, the
public forwarders, DNS over HTTPS, a node as a unit of systemd, podssh update, 200 MiB each way
through a node with its moves, and the servers of the repairs: Go's x/crypto/ssh, wstunnel, the
via forwarders, and containers of cgroup limits for health. docs/STATUS.md, "The release
check", holds the table of each run.
What is not in it
As in v1.0.0: the entries that wait for the relay's operator, the work that
the operator holds (Q32), the imports of T-328, the live runs of T-376, the
outside services that turn the relay's address away, the platforms'
signatures, and Tailscale and the Tor road, which need their features.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Build and CI
- CI: the gate red since 0b6fcdb: the net tests remove their scratch directories; the DERP stand-in registers a client before its answer (a2c418e)
- CI: the gate red at b76548c: the keyed mint's unit tests remove their scratch directories (60b3070)
- CI: allow the draft of T-460's russh test keys; exit-live meets GitHub's key with no global file (94be1bb)
Other
- T-251: done, the whole release check before the tag of v1.0.0 passed at 35a0d19 (80a6407)
- Q63 to Q66: milestone M10, the mesh at parity with Tailscale and the relay as a role of podssh; v1.0.0 tagged (6b6174f)
- M10: the Corrections of the 15 entries that waited for the relay's operator; relay-operator.md and carriers.md for Q63 to Q65 (d8cc0d6)
- T-169: podssh relay serve, the relay's forward road served by podssh itself (partial: the live run on a runner closes it); T-447, T-448 filed (00197d5)
- T-169: the citations of the files that its commit changed, moved against its parent (cargo todo remap --base HEAD~1) (2d847e8)
- T-443, T-444: the layer's window on the pair's road under the relay's bound; one TLS configuration for each trust, so that TLS resumes; T-449 filed; the relay role's Date header (bd4c576)
- T-439 (partial): --via, HTTP CONNECT to a second proxy over TLS, HTTP/1.1 and HTTP/2; the run against Caddy and squid follows in Actions (a253c8a)
- T-169: done, its live run on a runner passed; tls_resume removes its scratch directories (the gate's libs step at bd4c576) (8899450)
- T-436: the magic-wormhole transit relay as a carrier of a pair's road (Q65); T-450 filed (84eb45e)
- T-439 (partial): via-interop's first run failed on its script: Caddy is built as xcaddy builds it, each proxy must answer TLS, banners keep stdin open (5b62f4e)
- T-439: done, via-interop.yml passed against Caddy and squid (12 of 12) (95563f1)
- T-437: the Piping Server road (Q65) for a proxy that refuses the WebSocket upgrade; T-451 filed (b4817cb)
- T-438: Wisp: the protocol's client,
wisp+wss://forwarders, and the demo server as a fallback (Q65) (f22efab) - T-429: the net: an owner's signed list of its nodes, and their names; T-452 and T-453 filed (0b6fcdb)
- record: a citation of AGENTS.md's sentence of exit code 70 follows its two new lines (fd4cbbe)
- T-427: the relay's reverse road in podssh's relay role; the transit relay takes the host's trust; T-454 filed (d5a700b)
- T-448: the relay role mints tokens, and makes pairs, for the keys of a list; T-455 filed (b76548c)
- T-440 (partial): VLESS over a WebSocket and over XHTTP on HTTP/2, in place of the relay; Q67 and T-456 filed (33ccb11)
- T-441 (partial): wstunnel's protocol, --wstunnel URL in place of the relay, its secret in a 0600 file (e077220)
- T-440 (partial): its interop's first run: Xray-core blackholes a private target unless a final rule allows it (28cba8a)
- T-449 (partial): suite-repeat.yml, a suite run after run on a runner, each failure counted by its test's name (aca3a35)
- T-430: the net's policy: who may reach which node, route, exit and range, checked at the node (f85ced1)
- T-440 and T-441: done, each interop passed against its servers' own projects (f8d15b...
podssh v1.0.0
podssh v1.0.0
The first stable release. podssh carries SSH, or another TCP stream, through
a WebSocket relay on port 443, for a host whose only way out is HTTPS, often
through an HTTP CONNECT proxy: one binary for each platform (static on
Linux), which starts no helper program and uses no capability of the host
that it did not probe for first.
It is v1.0.0-beta.4 with this version and one repair: podssh update of a
build of a release, while the list holds prereleases alone, says that there
is nothing to do (exit 0), where it said that it found no list (T-426).
Its tag never moves: a defect found in it goes into v1.0.1.
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float (a Raspberry Pi with a 32-bit system), static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Each binary ran on its own platform before it was published: --version,
the whole manual, keygen and keygen -y, the iroh road's parse of a
ticket, WARP's road asking for Cloudflare's Terms before it dials, and
GitHub's SSH banner through the live relay.
Check a download
T=v1.0.0; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.0.0 (the commit of the tag)
./"$B" doctor # what this host allows, and whether the whole path worksOn macOS, check with shasum -a 256 -c in place of sha256sum -c -. A
binary that curl fetched has no quarantine; after a browser's download,
run xattr -d com.apple.quarantine "$B" first. On Windows, compare
(Get-FileHash podssh-x86_64-pc-windows-msvc.exe).Hash with its line in
SHA256SUMS (the case of the letters differs).
The provenance of a binary names the release workflow and the tag (with the
GitHub CLI):
gh attestation verify "$B" --repo Azathothas/podssh \
--signer-workflow Azathothas/podssh/.github/workflows/release.yml --source-ref "refs/tags/$T"The signature of SHA256SUMS names the workflow at the tag (with cosign; 3.x
and 2.6 both check it):
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS.sigstore.json"
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/Azathothas/podssh/.github/workflows/release.yml@refs/tags/$T" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMSThe two proofs and podssh --version name the same commit.
The sizes
The sizes of the release's dry run of 2026-11-01 (at e3f90ca, the code of
this tag but for the repair of update, run 41350666813), beside beta.3's:
| Binary | beta.3 | v1.0.0 |
|---|---|---|
| Linux x86-64 | 15.2 MiB | 15.7 MiB |
| Linux aarch64 | 11.7 MiB | 12.1 MiB |
| Linux armv7 | 8.8 MiB | 9.1 MiB |
| Linux riscv64 | 11.7 MiB | 12.1 MiB |
| macOS, Apple silicon | 9.2 MiB | 9.5 MiB |
| macOS, Intel | 12.2 MiB | 12.6 MiB |
| Windows x86-64 | 11.9 MiB | 12.3 MiB |
| Windows ARM64 | 10.5 MiB | 10.8 MiB |
What works
podssh ssh, each, run, job, session, containers, proxy, pipe,
cp, mv, scp, sftp and edit, doctor, keygen, agent, man,
status, ping, health, node, operator, relay, chat, play,
config, mcp, update and detached. podssh man is the reference: each command,
flag, -o keyword, variable, file and exit code. The iroh road is in each
binary: podssh node --iroh, a destination iroh:TICKET, and
--iroh-ticket. So is WARP's road, warp://HOST[:PORT], and the DERP road,
podssh node --derp and a destination derp:TICKET. These binaries have no
Tailscale: podssh ts exits with 70 and says so.
How it was checked
The release check of T-251 (scripts/release-check.sh) ran before the tag on
the release's dry run and a build of its own, and runs again on the
published files: the checksums, the signature of SHA256SUMS and the provenance of each
binary first; then the README's first steps, doctor, proxy and ssh
through the live relay, the reverse road with two sessions at once, cp of
200 MiB each way through a node, pipe, the iroh road through n0's relays,
the static binary in a fresh container and in a box like the target sandbox,
the Tailscale runs against headscale, the throughput run, IRC against
ngircd, and the planted defect of each check. GitHub's runners ran the rest:
Windows and macOS, the box, WARP's road, Cloudflare's edge, the public
forwarders, DNS over HTTPS, a node as a unit of systemd, podssh update,
and 200 MiB each way through a node with its moves. docs/STATUS.md, "The
release check", holds the table of each run.
What is not in it
- The entries that wait for the relay's operator, each an item of
docs/relay-operator.md:
a relay that its users host, a signed list of relays and a second
deployment, resumption in the relay for a standard sshd, a local HTTP
service athttps://NAME, and the relay's tolerance of a frame on its way
when a client's link is lost (T-421), among them. - The work that the operator holds (Q32):
podssh servewith a terminal of
its own (vi,lessand Ctrl-C in a box), two sessions from one box to a
node in another, and the work parked behind them. - The import of FinalShell's and Termius's exports (T-328) and the live run
of the roadsiap://andeice://in throwaway cloud accounts (T-376),
which wait for the operator. - Outside services that turn the relay's address away: railway.new's limit
for anonymous visitors, and the IRC networks libera, undernet and, at
times, OFTC (docs/irc.md). - Signatures of the platforms: the Mac binaries are not signed with an
Apple Developer ID, and the Windows binaries carry no Authenticode
signature, so SmartScreen may warn. The proofs above stand in for them. - Tailscale (
podssh ts), the Tor road (tor://) and their features are
not in these binaries: a build with--features tsor--features tor
has them.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Other
- T-425 (partial): irc.live skips when each network turned the relay's address away in its own words; T-251: the runs before beta.4's tag (e3db9db)
- T-425: done, irc.live skips on the networks' own refusal and fails without it (planted: a closed port, FAIL); the work order names 4e79a1f for beta.4 (9c73e32)
- v1.0.0 made ready (the steps of T-250): the version 1.0.0, the README's install lines, and the notes (e3f90ca)
- T-426: podssh update of a build of a release with prereleases alone listed is nothing to do; T-425: a stalled TLS handshake counts as a network's refusal; ts-headscale.sh takes its build from CARGO_TA… (35a0d19)
podssh v1.0.0-beta.4
podssh v1.0.0-beta.4
The fourth beta. It carries the repairs since v1.0.0-beta.3: a run in the
background that podssh starts again and watches, and that leaves a login
session's scope of systemd, a node that goes on past its pair's expiry, a
quick tunnel that races its roads, keeps two connections and rides out the
edge's GOAWAY, and the repairs of a bulk session through a node. A beta is a prerelease. Its tag never moves: a defect found in it
goes into the next beta.
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float (a Raspberry Pi with a 32-bit system), static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Each binary ran on its own platform before it was published: --version,
the whole manual, keygen and keygen -y, the iroh road's parse of a
ticket, WARP's road asking for Cloudflare's Terms before it dials, and
GitHub's SSH banner through the live relay.
Check a download
T=v1.0.0-beta.4; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.0.0-beta.4 (the commit of the tag)
./"$B" doctor # what this host allows, and whether the whole path worksOn macOS, check with shasum -a 256 -c in place of sha256sum -c -. A
binary that curl fetched has no quarantine; after a browser's download,
run xattr -d com.apple.quarantine "$B" first. On Windows, compare
(Get-FileHash podssh-x86_64-pc-windows-msvc.exe).Hash with its line in
SHA256SUMS (the case of the letters differs).
The provenance of a binary names the release workflow and the tag (with the
GitHub CLI):
gh attestation verify "$B" --repo Azathothas/podssh \
--signer-workflow Azathothas/podssh/.github/workflows/release.yml --source-ref "refs/tags/$T"The signature of SHA256SUMS names the workflow at the tag (with cosign; 3.x
and 2.6 both check it):
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS.sigstore.json"
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/Azathothas/podssh/.github/workflows/release.yml@refs/tags/$T" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMSThe two proofs and podssh --version name the same commit.
The sizes
The sizes of the release's dry run of 2026-11-01 (at 1bafa9d, the code of
this tag, run 41337605530), beside beta.3's:
| Binary | beta.3 | beta.4 |
|---|---|---|
| Linux x86-64 | 15.2 MiB | 15.7 MiB |
| Linux aarch64 | 11.7 MiB | 12.1 MiB |
| Linux armv7 | 8.8 MiB | 9.1 MiB |
| Linux riscv64 | 11.7 MiB | 12.1 MiB |
| macOS, Apple silicon | 9.2 MiB | 9.5 MiB |
| macOS, Intel | 12.2 MiB | 12.6 MiB |
| Windows x86-64 | 11.9 MiB | 12.3 MiB |
| Windows ARM64 | 10.5 MiB | 10.8 MiB |
What works
podssh ssh, each, run, job, session, containers, proxy, pipe,
cp, mv, scp, sftp and edit, doctor, keygen, agent, man,
status, ping, health, node, operator, relay, chat, play,
config, mcp, update and detached. podssh man is the reference: each command,
flag, -o keyword, variable, file and exit code. The iroh road is in each
binary: podssh node --iroh, a destination iroh:TICKET, and
--iroh-ticket. So is WARP's road, warp://HOST[:PORT], and the DERP road,
podssh node --derp and a destination derp:TICKET. These binaries have no
Tailscale: podssh ts exits with 70 and says so.
What to test again
New since v1.0.0-beta.3:
--detach(-fforssh): a run that podssh sends into the background
itself, once it is online, with its log in the cache (T-380); with
--restart, a small supervisor starts it again whenever it ends, never
giving up, and starts it again when it hangs: each run beats a file each
10 s, and one silent for 90 s is ended and started again (T-390, T-394).
--detach-name NAMEandpodssh detached list,status NAMEandstop NAME: a second start of a name that runs is refused (T-392). A run with no
/dev/nulluses closed pipes, the log is cut with no line lost, old files
go, and the run leaves the caller's working directory (T-397). A line that
fails to write (a full disk, a closed journal) no longer ends a run (T-389).
On Linux, a run detached from a login session asks the user's systemd for
a scope of its own,podssh-detached-PID.scope, as tmux does, so that a
logout does not end it where logind ends a session's processes; its log
says the outcome, andPODSSH_SYSTEMD=noasks nothing (T-381).podssh ssh --persist-forever: connect again after each loss with no limit
(T-391);podssh ssh --install NAME -N -R ... --persist: a reverse tunnel as
a service of this user (T-393).--installservices restart after each end,
with a cron watchdog, a LaunchAgent on macOS and a task on Windows (T-393).podssh updateruns the new binary once before it takes the old one's
place, keeps the old one aspodssh.prev, and--rollbackputs it back
(T-396).- A node says its pair's expiry 24 h, 6 h and 1 h before it, with the command
that makes the next pair;podssh relay pair NAMEmakes it in the last day
of the old one, and the node takes it at the expiry with no new start;
podssh statusnames each stored pair's expiry (T-395). A node closed by
the relay for a fault connects again (T-409), and a bulk session through a
node moves with no fault (T-410). A node that starts while the relay still
holds the socket of the pair's last node (a restart, a script that starts
the next one at once) connects again for 30 s instead of exiting at the
relay's 409 (T-416). - The quick tunnel (
podssh node --quick-tunnel): its roads (QUIC, HTTP/2,
HTTP/2 inside WARP) race with a stagger of 2 s, QUIC after a probe of UDP of
300 ms (T-400); on the edge's GOAWAY its visitors go on for up to 90 s while
a new connection takes the new ones (T-402); a window of small frames left
unread no longer ends the connection (T-408); a push of configuration is
answered over HTTP/2 and QUIC (T-404, T-411); a refusal of
api.trycloudflare.comfor now is asked again after its Retry-After (T-401).
The node keeps two connections to the edge, the second to its other region,
so that a region in trouble leaves one standing (T-414). - WARP's tunnel under volume (T-398), and a front door's new key read from the
device's record (T-399); a front door that shows another certificate once
is asked once more a second later before the road gives up (T-419). pipeandproxywrite what their source has ready together, up to
32 KiB, so that a source of small reads no longer pays a write for each.
Through Tor (a build with the featuretor) that took the download from
2.9 to 7.8 MiB/s through a private network; the Tor road also runs on two
threads, and it is measured on Tor's public network (T-353).- DNS over HTTPS through a proxy asks each resolver by its name first (T-405),
and over HTTP/2 it ends each connection with GOAWAY (T-418). ssh+tls://, SSH inside TLS as a hop or the destination (#61, T-372); a
Shadowsocks road from a file ofss://lines that a subscription can
refresh (#62, T-373); meek and WebTunnel inside the Tor road's process, in a
build with the featuretor(T-385).cpof many small files: the far digest's command starts beside each
file's sync and close, and a tree of 50 files or more that go one at a
time says once that--parallel 8copies 8 at once (T-417).
What a beta does not have yet
- The whole check of a release from end to end with no human
(scripts/release-check.sh, T-251): its parts ran on this beta's way; the
whole run, before the tag and after it, isv1.0.0's. - Signatures of the platforms: the Mac binaries are not signed with an
Apple Developer ID, and the Windows binaries carry no Authenticode
signature, so SmartScreen may warn. The proofs above stand in for them.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Build and CI
- CI: the Windows test of --restart gives --keep-listening; T-410's live move from GitHub's network (e837c63)
Other
- T-370, partial: the public forwarders of #59 by a word, and a fallback to them (the draft of 2026-10-31 merged) (5fa6f81)
- T-370: done. The public forwarders' live run passed; GitHub #60 and [#72](https://github.com/Azathothas/podssh/iss...
podssh v1.0.0-beta.3
podssh v1.0.0-beta.3
The third beta. It carries the repairs since v1.0.0-beta.2, the iroh road
and WARP's road in each binary, the DERP road, and podssh update, which
replaces the binary with a signed release. A beta is a prerelease. Its tag never moves: a defect found in it
goes into the next beta.
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float (a Raspberry Pi with a 32-bit system), static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Each binary ran on its own platform before it was published: --version,
the whole manual, keygen and keygen -y, the iroh road's parse of a
ticket, WARP's road asking for Cloudflare's Terms before it dials, and
GitHub's SSH banner through the live relay.
Check a download
T=v1.0.0-beta.3; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.0.0-beta.3 (the commit of the tag)
./"$B" doctor # what this host allows, and whether the whole path worksOn macOS, check with shasum -a 256 -c in place of sha256sum -c -. A
binary that curl fetched has no quarantine; after a browser's download,
run xattr -d com.apple.quarantine "$B" first. On Windows, compare
(Get-FileHash podssh-x86_64-pc-windows-msvc.exe).Hash with its line in
SHA256SUMS (the case of the letters differs).
The provenance of a binary names the release workflow and the tag (with the
GitHub CLI):
gh attestation verify "$B" --repo Azathothas/podssh \
--signer-workflow Azathothas/podssh/.github/workflows/release.yml --source-ref "refs/tags/$T"The signature of SHA256SUMS names the workflow at the tag (with cosign; 3.x
and 2.6 both check it):
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS.sigstore.json"
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/Azathothas/podssh/.github/workflows/release.yml@refs/tags/$T" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMSThe two proofs and podssh --version name the same commit.
The sizes
Each binary carries the iroh road (T-348), WARP's road (T-352) and the DERP
road (T-379) now, and podssh update (T-375).
The sizes of the release's dry run of 2026-11-01 (at 5e42bd4), beside
beta.2's:
| Binary | beta.2 | beta.3 |
|---|---|---|
| Linux x86-64 | 9.6 MiB | 15.2 MiB |
| Linux aarch64 | 7.5 MiB | 11.7 MiB |
| Linux armv7 | 5.6 MiB | 8.8 MiB |
| Linux riscv64 | 7.2 MiB | 11.7 MiB |
| macOS, Apple silicon | 6.2 MiB | 9.2 MiB |
| macOS, Intel | 8.1 MiB | 12.2 MiB |
| Windows x86-64 | 7.9 MiB | 11.9 MiB |
| Windows ARM64 | 6.9 MiB | 10.5 MiB |
What works
podssh ssh, each, run, job, session, containers, proxy, pipe,
cp, mv, scp, sftp and edit, doctor, keygen, agent, man,
status, ping, health, node, operator, relay, chat, play,
config, mcp and update. podssh man is the reference: each command,
flag, -o keyword, variable, file and exit code. The iroh road is in each
binary: podssh node --iroh, a destination iroh:TICKET, and
--iroh-ticket. So is WARP's road, warp://HOST[:PORT], and the DERP road,
podssh node --derp and a destination derp:TICKET. These binaries have no
Tailscale: podssh ts exits with 70 and says so.
What to test again
New since v1.0.0-beta.2:
podssh update: the newest release for this binary's own target. Its
SHA256SUMSis checked against Sigstore's signature by this repository's
release workflow at the tag, then the binary's own sum, before the binary
is replaced in place.--checkonly looks;--version TAGtakes a given
release (T-375).- The iroh road in each binary, and a notice when a relay refuses this
binary's iroh, which namespodssh updateand--iroh-relay(T-348). The
road keeps UDP only once a datagram came back, so a host that drops UDP
goes through the relay at once (#70, T-359). warp://HOST[:PORT]withssh,-Jandproxy: a port of any host
inside Cloudflare WARP's tunnel, MASQUE over HTTP/2 on port 443 through
the proxy, with no relay. The first run registers one device, only once
PODSSH_WARP_ACCEPT_TERMS=yesaccepts Cloudflare's Terms, and keeps its
record in the cache. A proxy that allows names alone refuses the
endpoint's address, and podssh says so (#63, T-352).podssh node --quick-tunnelreaches the quick tunnel's edge inside WARP's
tunnel when port 7844 is closed to the host, or first with--warp
(T-374).- The DERP road:
podssh node --derpserves a node through Tailscale's
public DERP servers (or those of--derp-server), andpodssh ssh derp:TICKETreaches it. A node with an allowlist and no pair serves it
unasked;PODSSH_DERP=noturns that off.node://NAME --derp-ticket
adds it to the race of a node's roads, andpodssh doctorhas a section
derp(T-379). - When no relay host opens a session and no relay was named,
podssh ssh
and the commands that reach a server as it does try the direct road once,
through the proxy, and say so;PODSSH_DIRECT=noturns that off (T-363). --forwarder TEMPLATES: other products' WebSocket forwarders in place of
the relay, such as Mudlet's or ssheasy's, forssh,proxyand the
commands ofssh's road;PODSSH_FORWARDERand the settings file's
Forwardergive them too, andpodssh doctor --forwarderchecks them
(#59, T-369).-J USER@HOST:443through a proxy that allows port 443 alone, with the
hop's password fromSSH_ASKPASS, andpodssh doctor --hop, which says
whether a hop answers with SSH there (#61, T-371).- The iroh road keeps a signed record of its node's home relay at n0's
pkarr server, so a client whose ticket names an old relay finds the node;
PODSSH_IROH_PKARR=offturns it off (T-350). podssh pipe http-listen:PORT relay:%h:%p: an HTTP CONNECT proxy for a
program that knows onlyHTTPS_PROXY, with--proxy-auth-filefor an
address off loopback (#75, T-367).podssh pipewithws://,wss://andws-listen:: a WebSocket by its
URL, and a WebSocket server in front of a port (#76, T-368).podssh ssh iap://andeice://: the tunnels of Google Cloud's IAP and of
AWS's EC2 Instance Connect Endpoint. Their tokens and credentials come
from files, never from the command line (T-351). They were built against
stand-ins; a live report is welcome.-Rtakes each form of OpenSSH's: socket paths on either side, and the
remote SOCKS form (#73, T-365).-J cf://HOST: a Cloudflare tunnel as the first hop of a jump chain
(T-347).podssh doctor:- whether the proxy takes an address as well as names (#74, T-366);
- the listeners that this host allows, each listened on once (T-357,
T-358); - this host's clock, when a certificate looks expired or not yet valid,
in each command's TLS failure too (T-345); - the system's stores of roots on Windows and macOS, and what to do about
an issuer that no root signs (T-340).
- DNS over HTTPS in RFC 8484's wire form, with Quad9 after Cloudflare and
Google. The addresses that carried a session are tried when the resolvers
fail (T-344). - The quick tunnel over QUIC, where UDP reaches Cloudflare's edge (T-301).
- russh 0.65.0, with its security fixes (T-356); the keys of the AEAD
ciphers are wiped when a cipher is dropped (T-377).
What a beta does not have yet
- The check of a release from end to end with no human (T-251); it runs
beforev1.0.0. - Signatures of the platforms: the Mac binaries are not signed with an
Apple Developer ID, and the Windows binaries carry no Authenticode
signature, so SmartScreen may warn. The proofs above stand in for them.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Documents
- docs/relay-operator.md, audited on 2026-10-31 for the relay's agent: a brief that stands alone (what podssh is, the contract as the boundary, how an item is handed back), 18 items with their measureme… (804fff4)
Other
- T-300, partial: a quick tunnel that podssh makes itself, over HTTP/2 with no cloudflared, and its client. The node, podssh node NAME TARGET --quick-tunnel (crates/podssh-relay/src/quick/, feature quic… (2258dd6)
- T-331, partial: the layer's CLOSE before the exit of job, run, pipe, health, containers and --upgrade on a podssh node's cf:// name. Each runs on a runtime of one thread, where a spawned task runs onl… (24dda6b)
- T-307:...
podssh v1.0.0-beta.2
podssh v1.0.0-beta.2
The second beta. It carries the repairs since v1.0.0-beta.1 and more
platforms, and it is the first release that proves where each binary comes
from. A beta is a prerelease. Its tag never moves: a defect found in it goes
into the next beta.
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-armv7-unknown-linux-musleabihf |
Linux on 32-bit ARM with hard float (a Raspberry Pi with a 32-bit system), static |
podssh-riscv64gc-unknown-linux-musl |
Linux on 64-bit RISC-V, static |
podssh-aarch64-apple-darwin |
macOS on Apple silicon; it links the system's libraries only |
podssh-x86_64-apple-darwin |
macOS on Intel |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
podssh-aarch64-pc-windows-msvc.exe |
Windows on ARM64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
SHA256SUMS.sigstore.json |
The signature of SHA256SUMS: Sigstore's keyless signing, by the release workflow at this tag |
provenance.sigstore.json |
The provenance of each binary (SLSA), signed the same way: the workflow, the tag and its commit |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Each binary ran on its own platform before it was published: --version,
the whole manual, keygen and keygen -y, and GitHub's SSH banner through
the live relay.
Check a download
T=v1.0.0-beta.2; B=podssh-x86_64-unknown-linux-musl # or another file of the table
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.0.0-beta.2 (the commit of the tag)
./"$B" doctor # what this host allows, and whether the whole path worksOn macOS, check with shasum -a 256 -c in place of sha256sum -c -. A
binary that curl fetched has no quarantine; after a browser's download,
run xattr -d com.apple.quarantine "$B" first. On Windows, compare
(Get-FileHash podssh-x86_64-pc-windows-msvc.exe).Hash with its line in
SHA256SUMS (the case of the letters differs).
The provenance of a binary names the release workflow and the tag (with the
GitHub CLI):
gh attestation verify "$B" --repo Azathothas/podssh \
--signer-workflow Azathothas/podssh/.github/workflows/release.yml --source-ref "refs/tags/$T"The signature of SHA256SUMS names the workflow at the tag (with cosign; 3.x
and 2.6 both check it):
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS.sigstore.json"
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
--certificate-identity "https://github.com/Azathothas/podssh/.github/workflows/release.yml@refs/tags/$T" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMSThe two proofs and podssh --version name the same commit.
What works
podssh ssh, each, run, job, session, containers, proxy, pipe,
cp, mv, scp, sftp and edit, doctor, keygen, agent, man,
status, ping,
health, node, operator, relay, chat, play and config, and
mcp. podssh man is the reference: each command, flag, -o keyword,
variable, file and exit code. These binaries have no Tailscale and no iroh
road: podssh ts, and a destination iroh:TICKET or --iroh-ticket, exit
with 70 and say so.
What to test again
New since v1.0.0-beta.1:
podssh doctortells apart three failures of the WebSocket upgrade, and
measures each TCP probe nine times, with its loss (#54, T-324). It names a
proxy that answers200to CONNECT and then carries no SSH (T-317).- A proxy that answers
407is named with what it asks for; podssh sends
Basic from the user and password of the proxy URL (T-320). - A relay's name pinned to a loopback address goes with no proxy (T-318).
- Each frame of a forward is 32 KiB at most, the relay's own limit (T-323).
podssh each --interactive --stop-key ^X: the stop of a broadcast on a
key that you choose (T-322).podssh node --installand--uninstall: the node as a service of its
user, with no privilege (T-121).podssh config import putty|mobaxterm|remmina FILE: hosts from the
sessions of those programs (T-292).podssh agenton macOS: its socket goes under/tmpwhere the temporary
directory's path is too long for a socket (T-034).podssh session start NAME HOST, thensend,wait,captureand
stop: a session with a pty that a podssh of its own keeps in the
background, for a program that drives a terminal (T-186).podssh job start|list|log|stop HOST: jobs in the far host's tmux that
go on after the connection ends (T-193); and its queue,submitwith
--slots,waitandfetch, and a submit to a list of hosts that goes
to the one with the fewest jobs (T-197).podssh run HOST -- COMMAND: the project goes to the host, only the files
that changed, and the command runs in it with its exit status (T-192).podssh node --resume-deadline TIME: a node keeps a lost session up to
72 h, and names the time to its clients (T-306).- With the resumable layer of a node: a notice in the window's title while
the node is silent, which counts up and leaves the screen as it was
(T-302); and a spare link beside a link that went silent, so that a new
address of this host costs seconds, not 30 s (T-305;
PODSSH_SPARE_LINKS=noturns it off). - The new platforms of the table: macOS, Windows on ARM64, and Linux on
32-bit ARM and on RISC-V.
What a beta does not have yet
- The check of a release from end to end with no human (T-251); it runs
beforev1.0.0. - Signatures of the platforms: the Mac binaries are not signed with an
Apple Developer ID, and the Windows binaries carry no Authenticode
signature, so SmartScreen may warn. The proofs above stand in for them.
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Commands
- podssh session: one SSH session with a pty that outlives each call of an agent (T-186, the draft of 2026-10-13 merged): start runs serve in the background, which binds its socket (mode 0600 in session… (4d17c3e)
- podssh run: copy a project to a host, only the files that changed, then run a command in it with its exit status (T-192, the draft of 2026-10-13 merged): the project goes to ~/.podssh/run/NAME, or hos… (a792d1a)
Other
- A proxy that takes the CONNECT and carries no SSH is named (T-317): podssh doctor reads the first bytes of github.com port 22 for 5 s after the 200, and on the direct road too, and says that plain ssh… (465cadc)
- v1.0.0-beta.1 is published (T-309): a prerelease at 5c8d423, made by the release workflow by hand with publish=v1.0.0-beta.1 (run 41054194363), after the gate, deny, secrets, the dry run (run 41051568… (0becfb9)
- The requests of 2026-10-30 in the record: GitHub #54 is T-324 (doctor tells the three failures of the upgrade apart, and samples each probe with its loss) and T-325 (what the path does to a stream: bu… (c00c9fd)
- Each forward frame of podssh is 32 KiB at most (T-323): FORWARD_SEND_PAYLOAD beside the relay's cap in podssh-ws is the one size of the stream of podssh ssh, which sent 64 KiB, of the relay leg of pod… (0d80320)
- A relay's name pinned to loopback goes with no proxy (T-318): podssh never sends a loopback target to a proxy, as the proxy's loopback is not this host's, and a name that --relay-addr or PODSSH_RELAY_… (472adff)
- A 407 names what the proxy asks for (T-320): podssh sends Basic only, from the user and password of the proxy URL, as Go, wget, requests and reqwest do, and on a 407 read no Proxy-Authenticate, so a u… (95ef7a3)
- The stop of the broadcast has a key that the user chooses (T-322): podssh each --interactive --stop-key ^X makes Ctrl-X the terminal's QUIT character for the run on Unix, with a guard that puts the ol… (9133f0a)
- doctor samples each probe of TCP, and names three failures of the upgrade (T-324): each CONNECT through the proxy and direct TCP is tried nine times, 125 ms apart, and its line gives the best time, th… (c0ed03f)
- podssh node --install makes the node a service of its user, with no privilege (T-121, partial): a probe finds the way, a user unit of systemd when systemctl --user answers (daemon-reload, enable, rest… (9c6a4a0)
- podssh node --install, measured on a host with systemd (T-121): the workflow service live (run 41066805844, a GitHub runner) made a pair on the live relay, and --install made a user unit of systemd, e… (0b760dd)
- The pinned images move out of .github/ to images/ (T-308, partial): Dependabot's docker job finds each update and its create_pull_request gets 400, "The request contains invalid or unauthorized change… (8b53759)
- podssh config import reads the sessions of PuTTY, MobaXterm and Remmina (T-292): a .reg file of PuTTY's Sessions key in UTF-16LE, UTF-8 or the ANSI of REGEDIT4, or its session files of Unix (a file or… (1891f43)
- The workflow quick tunnel edge measures the edge of Cloudflare's quick tunnels in GitHub Actions (T-299, partial; Q43). It is dispatched by hand with confirm=Q43. Its steps: cloudflared 2026.10.6, pin… (687ccf1)
- The workflow quick tunnel edge gets a job relay, step 4 of T-299: podssh built in the job asks the live relay to trace the edge's 7844 (two addresses and the name) and an address'...
podssh v1.0.0-beta.1
podssh v1.0.0-beta.1
The first beta since this repository's history was replaced: it carries
each change since 2026-10-08. A beta is a prerelease. Its tag never moves:
a defect found in it goes into the next beta.
The files
| File | For |
|---|---|
podssh-x86_64-unknown-linux-musl |
Linux on x86-64, static: no library and no loader needed |
podssh-aarch64-unknown-linux-musl |
Linux on aarch64, static |
podssh-x86_64-pc-windows-msvc.exe |
Windows on x86-64, with a static C runtime |
SHA256SUMS |
The SHA-256 of each binary |
THIRD-PARTY-LICENSES.md |
The licenses of the crates in the binaries, with their texts |
Check a download
T=v1.0.0-beta.1; B=podssh-x86_64-unknown-linux-musl # or podssh-aarch64-unknown-linux-musl
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/$B"
curl -fsSLO "https://github.com/Azathothas/podssh/releases/download/$T/SHA256SUMS"
grep " $B\$" SHA256SUMS | sha256sum -c - && chmod +x "$B"
./"$B" --version # podssh 1.0.0-beta.1
./"$B" doctor # what this host allows, and whether the whole path worksOn Windows, compare (Get-FileHash podssh-x86_64-pc-windows-msvc.exe).Hash
with its line in SHA256SUMS (the case of the letters differs).
What works
podssh ssh, each, containers, proxy, pipe, cp, mv, scp,
sftp and edit, doctor, keygen, agent, man, status, ping,
health, node, operator, relay, chat, play and config, and
mcp. podssh man is the reference: each command, flag, -o keyword,
variable, file and exit code. These binaries have no Tailscale and no iroh
road: podssh ts, and a destination iroh:TICKET or --iroh-ticket, exit
with 70 and say so.
What to test again
What the earlier betas asked for, and this beta has:
ssh_config,-F,-GandMatch(#14, #22).- A relay session that drops: the hop that broke is named, and a forward is
tried again when that is safe (#17). - Copies (#21):
podssh cpcontinues after a drop, writes a temporary
name, checks the digest and then renames; pipelined SFTP, parallel chunks,
delta copies,-r,--delete,--dry-run, progress and a bandwidth
limit;scpandsftpwith OpenSSH's command lines;edit; ZMODEM. - Output for machines:
doctor --json,man --json,status,ping,
health, and the exit status of a remote command (#23). - Many hosts:
each, broadcast with an emergency stop, recordings and
play(#24). - Streams that are not SSH:
pipe,-W, AF_UNIX streams, UDP over the
relay (#26). podssh doctorin your sandbox, with and withoutHTTPS_PROXY; a
no_proxywith blocks such as10.0.0.0/8keeps each address inside
them off the proxy now, anddoctornames the entry (T-316).
What a beta does not have yet
- Build provenance and signed checksums (T-210, T-211):
SHA256SUMScomes
from the run that built the binaries, and is not signed. - macOS, Linux armv7 and riscv64, and Windows aarch64 binaries (T-218).
- The check of a release from end to end with no human (T-251); it runs
beforev1.0.0. - Known, for the next beta: a proxy that answers
200to CONNECT and then
carries no SSH is not named as the cause (T-317).
Report a defect
Open an issue at https://github.com/Azathothas/podssh/issues with the
output of podssh --version and podssh doctor --json. Read that output
before you post it: it names this host's proxy and addresses, and never a
token or a password.
The licenses of the crates in the binaries, with their texts: THIRD-PARTY-LICENSES.md.
The commits of this release
Commands
- podssh ssh: the native client, on russh (e34597b)
- podssh doctor: what a host allows and whether the relay path works (7b38e31)
- podssh keygen: SSH keys in OpenSSH's format, for hosts without ssh-keygen (9b806fe)
- podssh man: the whole manual from the binary, as text (d0b16a3)
- podssh ssh: each flag of OpenSSH 10.3p1 answers by name (0c93a7c)
- podssh ssh: a repeated flag follows OpenSSH; -J and -W only once (3ee70dc)
- podssh status: one line of JSON about this host (692b3b0)
- podssh agent: an SSH agent inside podssh, on a socket that only this user can open, with add, list, remove, lock and unlock (T-034) (f7d5640)
Build and CI
- Workflows: artifact actions on Node 24; dumpbin found with vswhere (3937707)
- scripts/sandbox-check.sh: the sandbox measurement as one command (4853e6c)
- scripts/test_in_box.sh: a Podman box built to the target sandbox's profile (4f66d9b)
- gate: the no-C rule also stops C++ (CXX=/nonexistent) (a378863)
- CI runs the console checks on Windows, against MSYS2's sshd (dacbf4a)
- CI runs each step of the gate in a job of its own, at the same time (a04b0c8)
- scripts/dev.sh in two files, each under 500 lines, and the size check reads the scripts (d88de09)
- CI pulls each pinned image through a fallback: when Docker Hub refuses a pull with no account, a mirror serves the same digest (5557c62)
- CI names the systems of its runners, ubuntu-24.04 and windows-2025, before ubuntu-latest moves to Ubuntu 26 on 2026-10-19 (T-278, partial) (0804e38)
- scripts/gate.sh tries each download of rustup and apk three times, 10 s and then 20 s apart, as CI at 0d3d13a failed in its step msrv_ts when one DNS lookup of rustup's channel file failed on the runn… (73f910b)
- scripts/fuzz.sh builds and runs each fuzz target for this host's own target, as the first run of the workflow fuzz found that a release binary of cargo-fuzz, built for musl, built the targets for musl… (6529789)
Documents
- docs: design.md, the answers that decide podssh's future (bcbccf1)
- Docs, pass 1: the routing documents in ASD-STE100, and docs/defects.md (3c7734a)
- Docs, pass 2: STATUS and ROADMAP in ASD-STE100 (5b9805f)
- Docs, pass 3: the topic pages in ASD-STE100, brought up to date (6649623)
- Docs, pass 4: design, milestone pages and release notes in ASD-STE100 (3a88e1d)
Repairs
- Fix -4/-6, the 1001 exit, -W on a lost connection, two messages (72dc8a6)
Other
- podssh: initial public release (9a03102)
- STATUS: the gate re-run is green, interop 62 of 62 (32a2837)
- podssh-ws: never proxy loopback; drop three unused dependencies (f9dda61)
- Roadmap: the operator's decisions on the way to a finished podssh (fd259f8)
- podssh-relay: relay hosts with failover, in a C-free library crate (b45fcb4)
- Liveness: ping the relay, declare a silent link dead in 30 s (a00c7a2)
- No proxy and no DNS: pinned addresses, DNS over HTTPS, RSA in TLS (a89deaf)
- Fault injection in the gate; the dead DNS stack in podssh-transport removed (c078085)
- Interactive use on Windows, measured in a real pseudo console (ca50a68)
- Release notes for v0.1.0-beta.1: doctor, keygen, failover, the fault harness (aa9cfaa)
- Prompts: no wait for ever on a terminal that nobody watches (eacd94e)
- TODO/: the work record, with its checker in Rust and in the gate (22c3b88)
- TODO/: T-249, a cited line that moved still exists (e275d36)
- AGENTS.md: a session runs unattended toward v1.0.0 (b1b111b)
- One release only: v1.0.0, tagged once at the end (4bf0c26)
- The box has the sandbox's dead /dev/tty; T-005 measured there (d272ebb)
- podssh-todo: remap moves the citations of an edited file; a quote must hold (cd12fa3)
- sandbox-check.sh: each step has a verdict, and a failed step fails the run (eaf9822)
- IPv6 addresses as targets: podssh sends the bare literal to the relay (2da855f)
- Relay tokens: one cache entry for each deployment, with the host that minted it (37ace00)
- A command that is not implemented says so before the --timeout gate (3cd368b)
- A flag with no value names the flag and its value (56b466b)
- podssh --help and --version drop no word (4bceef6)
- A host that starts with -: refused also as HostName, and -- is documented (475aea9)
- A refusal names keys only when keys were tried (80f20bf)
- A dropped session names the hop that broke (25ab0e7)
- The -R refusal gives its own cause, not the listener (cd3fea5)
- A bad relay variable is a configuration error (78) (fdbba30)
- The help of a command that does not work says so (02e4e1f)
- podssh man relay-facts selects THE RELAY (9fefff2)
- Each answer of the server while logging in has a time limit (8d668b7)
- A channel that podssh did not ask for is refused (5c7a1ad)
- The % tokens are OpenSSH's (5521cbf)
- -W takes HOST:PORT, as OpenSSH reads it (d87ca8a)
- podssh doctor gives the version and the age of the compiled-in roots (2c39778)
- An interactive session over -tt from the box: vi, less, top and Ctrl-C (bc13eee)
- podssh doctor --json (332ee58)
- podssh man --json (a2eeb7f)
- PODSSH_TIMEOUT gives the default of --timeout (bd626c7)
- podssh doctor --full logs in to GitHub with a key made for the check (d98d77e)
- T-052 measured in the box: login ok (c6f09a8)
- The node leg's control leaves as a text frame (3d4785a)
- A Close from the relay keeps its code and reason (6d7737f)
- The node leg sends data only for a readied session (1a00ba2)
- An HTTP answer to an upgrade keeps its body and follows the contract (4b6e917)
- A host or a pair name cannot change the relay path (3b60753)
- A control frame that RFC 6455 forbids fails the connection (076e3ce)
- cargo todo check finds a citation that a forgotten remap left (4e817d7)
- No crate carries a verifier that accepts each certificate (510d86f)
- No draw of random bytes can panic (c56792f)
- A library can bring its own rustls configuration (723d90b)
- A session's failure has a class (23b5d82)
- A plain ws:// session to the loopback, for tests (3632dcb)
- Pairs of the reverse road, made, asked about and stopped (9811e0d)
- The node of the reverse road (c3a3ca9)
- The operator of the reverse road (0d92eef)
- A blocking facade for podbox (af0a163)
- The node and the pairs on the command line (3cbf215)
- The operator, and ssh to a node (e8bbd4d)
- The codecs of the reverse road in podssh-relay (cd75137)
- The reverse road has no idle cut, and drops at random (0052ac9)
- ...