Repository navigation
podssh v1.0.0-beta.2
Pre-releasepodssh 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's 443, then makes TLS… (fb712a2)
- The tests of config_import remove their scratch directories (T-292): the gate's steps ssh, ts and iroh failed on 1891f43 (run 41069857511) with "the tests left in the temporary directory", the four di… (d27c6ba)
- The workflow release targets tries each new target of T-218 (partial) before release.yml takes it: aarch64-apple-darwin on macos-15 and x86_64-apple-darwin on macos-15-intel, after the default tests, … (4457f9c)
- The edge of Cloudflare's quick tunnels, measured from GitHub's runners (T-299, done; Q43): docs/design.md, "The edge, measured", and a table in docs/STATUS.md. Run 41071742798: the SRV record names re… (d998246)
- pull-image.sh pulls the platform that PULL_PLATFORM names, and the trial of T-218 pulls the image of armv7 and of riscv64 for its target: in run 41074530703 both jobs stopped at docker run --platform … (711f18f)
- The unit and crontab writers of node --install allow dead code on Windows (T-121): the release build for Windows on ARM of T-218's trial (run 41074530703) warned that the unit's mark, systemd_word, un… (6e2986f)
- The trial of T-218 builds each host triple with --target, and each binary runs the short form of the release check: armv7 and riscv64 stopped at "cannot produce proc-macro for clap_derive" (runs 41074… (3151a82)
- podssh agent puts its socket under /tmp when its path would not fit (T-034), and the test of cp --sparse checks holes only where the file system keeps them (T-146): on both Macs of T-218's trial (run … (4307e94)
- The citation of the agent's confirm in T-034's record moves with serve.rs (cargo todo remap --base HEAD
1): the commit before moved the lines by ten, and cargo todo check --base HEAD1 named the citat… (8e6fd52) - The agent's socket falls back to /tmp by sun_path's own size, and the sparse test syncs each file before it counts its blocks (T-034, T-146): the bound of 100 bytes, taken from doctor's probe, moved a… (3444978)
- The desktop harness waits for the meter's lines before it reads them (T-179): desktop.vnc.rate failed once in CI's step release at 711f18f (run 41075369339) and passed at the commits around it; the me… (ae8447f)
- The release builds and runs the Macs, Windows on ARM and armv7 (T-218): each passed T-218's trial on its own platform, so release.yml now builds aarch64-apple-darwin on macos-15 and x86_64-apple-darwi… (224ccd2)
- The operator's rulings of 2026-10-30 go into the record: Q44, the split HTTP road may open a second connection where a probe found the upgrade refused (the third exception of AGENTS.md's rule 2; T-319… (4f9f3e0)
- podssh --version names the commit of a release build (T-210, item 3): the release gives the commit to the compiler as PODSSH_BUILD_COMMIT, read with option_env! (no build script, no git call), and --v… (cdf9308)
- The release's own run on a tag attests each binary and signs SHA256SUMS, and each build names its commit (T-210, T-211): a run by hand with the input publish now only makes the tag (the job tag) and s… (1841c33)
- The trial builds riscv64 with cargo-zigbuild, by the operator's call, and runs it under QEMU (T-218): the build under QEMU in the gate's image passed in 5287 s (run 41076578398), and its binary passed… (758c691)
- The trial's install of cargo-zigbuild clears RUSTFLAGS (T-218): in run 41091523632 it stopped at "cannot produce proc-macro for clap_derive", as +crt-static with no --target reached the proc-macros of… (2599ae1)
- The trial lists cargo-zigbuild's version with cargo install --list (T-218): in run 41093257619 cargo-zigbuild 0.23.4 installed in 54 s, and its subcommand took no --version; actionlint clean. (4fb1728)
- Dependabot's group of 11 updates reaches main with iroh-relay's patch carried to 1.4.1 (T-329, Azathothas/podssh#53): the pull request failed the gate's step iroh (run 41075421658), as iroh 1.4.1 asks… (67cfa53)
- TruffleHog 3.99.7 scans the history (Azathothas/podssh#58): the steps of the job secrets, run here with the pull request's scanner (mirror.gcr.io served the pinned digest when Docker Hub answered 429)… (d54b9e7)
- The citations of docs/STATUS.md move with its new row (cargo todo remap --base HEAD~1): the commit before added the row of TruffleHog 3.99.7 and left 24 citations of the record one line short, which c… (ea5b046)
- The release cross-compiles riscv64 with cargo-zigbuild, and checks the provenance before it publishes (T-218, T-210): the trial's third run (41093657124) built riscv64gc-unknown-linux-musl in 305 s in… (3992dc3)
- T-218 is done: the dry run of release.yml at 3992dc3 (run 41095138291) built and checked the eight binaries, each on its own platform with the short form of the release check, and publish passed: Linu… (27dc07b)
- podssh job start, list, log and stop: jobs on a far host that go on after the connection ends, each in the host's tmux (T-193, the draft of 2026-10-13 merged): each call sends a POSIX sh script (job/f… (60b0b74)
- A queue of detached jobs on the far host: podssh job submit (to the least busy host of a list), --slots, wait with the job's status, fetch of its output and of --files, and list --json (T-197, the dra… (28306d6)
- A resume deadline that the user sets (T-306, the draft of 2026-10-13 merged): podssh node --resume-deadline TIME, 1 minute to 72 h, keeps a lost session TIME in place of 10 minutes on each road and na… (d0dbb59)
- A notice in the terminal while the far end is silent (T-302, the draft of 2026-10-13 merged), and T-307, its counterpart on the forward road, as a new entry: the resumable layer keeps the far end's la… (bbaecf4)
- Roam at once: a spare link beside a silent one (T-305, the draft of 2026-10-13 merged): when a question of the client (DATA that the far end acknowledges, a PING) waited 3 s with nothing from the far … (b6bcafb)
- The interop check job.queue.choose of T-197, which failed in the gate's step release at d0dbb59 (run 41103062568): the harness runs OpenSSH and Dropbear as one user, podtest, so both servers read one … (3b4cd4e)
- T-330, a new entry: Dependabot's four updates of a major version (Azathothas/podssh#44 to #47: sha1 0.11, vt100 0.16, x25519-dalek 3, aes-gcm 0.11), one at a time with its tests and its vectors, sha1 … (77f8779)
- The second beta made ready, v1.0.0-beta.2 (the steps of T-309): the version 1.0.0-beta.2 in Cargo.toml and both lock files (fuzz/Cargo.lock also gains podssh-terminal and vt100 with their crates, whic… (f7f97a5)