Hosts, keys, passwords, two-pane SFTP, port forwarding, serial consoles and mosh — in one window, or one binary. Everything it knows about your servers is encrypted on your own machine.
$ tm ls ID NAME ADDRESS USER GROUP TAGS github.com github.com github.com git fra1 ubuntu-fra 164.92.231.103 root production prod $ tm run disk --tag prod ✓ ubuntu-fra 1.9s /dev/vda1 58G 11G 47G 20% / ✓ web-2 2.1s /dev/sda1 40G 22G 17G 57% / ✗ db-1 timeout after 60s $ tm tunnel add pg --local 5433 --to localhost:5432 --host fra1 → 127.0.0.1:5433 → localhost:5432 loopback only
The window is a native macOS app today. Windows and Linux get the command-line tool, which does everything except draw the window — and it is the same vault, the same hosts, the same keys.
The command-line tool. No window yet — see the note below.
tm.exe · x64 · 4.1 MBAlso: ARM64
macOS will refuse to open it the first time. The app is not signed with an Apple Developer certificate yet, so Gatekeeper calls it damaged. It is not. Right-click the app and choose Open, or run:
xattr -d com.apple.quarantine /Applications/Bastion.app
Why no window on Windows and Linux? The window is built on the system web view — WebView2 on Windows, WebKitGTK on Linux — and neither has been compiled or tested yet. Shipping a build nobody has run would waste your time, so it is not offered until it is.
Checksums: SHA256SUMS · verify with
shasum -a 256 -c SHA256SUMS
Nested groups pass down the user, the key, the jump host and the port. Set it once on production, not on forty machines.
Local on the left, remote on the right. Browse, upload, download, rename, make directories, with progress.
Local, remote and dynamic SOCKS5. Forwards bind to loopback by default, so a database port does not land on the café wifi.
Save the command you run everywhere, tick the hosts, run it on all of them at once. Every host reported, failures included.
USB adapters, with the baud rates that matter first. The one thing a terminal app does that SSH cannot — for the switch that has no network yet.
The actual UDP protocol against mosh-server, not SSH wearing its name. Survives a change of network.
A bastion, then the box behind it, then the box behind that. Each hop carries its own credentials, and each host key is checked.
What connected, from where, and when — append-only, and chained so editing it by hand is detectable.
Hosts, addresses, usernames, tags, snippets and your command history — all encrypted on disk under one master passphrase.
A security page that only lists good news is marketing. Here is the whole picture.
| Thing | Where it lives |
|---|---|
| Hosts, addresses, users, tags, snippets | Encrypted on your disk |
| Saved passwords | Encrypted on your disk |
| Command history | Encrypted on your disk |
| Session log | Encrypted, and chained |
| Private keys | Left in ~/.ssh, referenced — never copied |
| Your master passphrase | Never written down. Lose it and the vault is gone. |
Argon2id derives a key-encryption key from your passphrase; that wraps a random data key; XChaCha20-Poly1305 encrypts each file with its purpose bound in. Changing the passphrase rewrites one wrapped key, not your data.
The session log is tamper-evident, not tamper-proof. Editing it by hand is caught — each record carries the digest of the one before, and the head digest is kept in the system keychain. But anyone who controls the machine can recompute the whole chain. Real proof needs a head digest held somewhere they do not control.
There is a sync server, and its design is end-to-end encrypted — the server stores ciphertext it has no key for. It is not for sale and not switched on, because the cryptography has not been audited by anyone outside this project. It will stay off until it has.
Unpack and put it on your path.
tar xzf tm-v0.1.0-<os>-<arch>.tar.gz sudo mv tm /usr/local/bin/ tm --version
Unzip tm.exe anywhere on your PATH.
tm.exe add --id web1 --address 10.0.0.5 --user root tm.exe connect web1
Or build it yourself — Go 1.26 and make app on a Mac,
go build ./cmd/tm anywhere.