Demo coming soon.
Toggle, restart and watch all your SSH forwards from a single TUI β running standalone, or attached to a background daemon that keeps them alive.
-L, -R and -D tunnels. A dynamic forward runs a SOCKS5 proxy so you can reach any internal address through the bastion without a forward per port.
Start standalone, then hand off to the daemon without dropping a connection β already-bound local listeners are passed over SCM_RIGHTS, so the port never goes down.
macOS, Linux and Windows from the same release. Named-pipe IPC, ssh-agent over the OpenSSH pipe, and a registry Run-key autostart on Windows.
Native SSH via golang.org/x/crypto/ssh β no system ssh dependency. IPC bearer-token auth, OS-keyring identity storage, and govulncheck scanning in CI.
Auto-detected from NO_COLOR / COLORFGBG; force one with PORTATO_THEME. The light theme paints a real light surface across the whole TUI.
Plain ssh -L is fine for one tunnel in one terminal. Portato is for everything past that.
| What you want | ssh -L / autossh | Portato |
|---|---|---|
| See what's running | nothing β ps and scrollback | one TUI screen, live status for every tunnel |
| Reconnect after sleep / drop | autossh, one process per tunnel | built-in backoff + reconnect, all tunnels |
| Many tunnels | one command and process each | named tunnels from one config.yaml |
| Survive logout | hand-rolled systemd / launchd unit | portato install β launchd / systemd / Windows Run key |
| Toggle without re-running | β | space in the TUI |
| Don't drop the port on hand-off | β | FD-passing β standaloneβdaemon, port stays up |
# macOS / Linuxbrew
brew install --cask portuber/tap/portato
# Windows
# If Scoop reports git is required: scoop install git
scoop bucket add portuber https://github.com/portuber/scoop-bucket
scoop install portuber/portato
# Linux (deb / rpm) β from the latest GitHub Release
sudo dpkg -i portato_<version>_linux_amd64.deb
# or: sudo rpm -i portato_<version>_linux_amd64.rpm
# Alpine (apk) β unsigned, so allow-untrusted is required
sudo apk add --allow-untrusted portato_<version>_linux_amd64.apk
# macOS / Linux β download the archive from the latest Release, then:
tar -xzf portato_<version>_macOS_arm64.tar.gz
install -m 0755 portato ~/.local/bin/portato
# Windows: expand the .zip and put portato.exe on PATH
portato version
# needs Go 1.26+
go install github.com/portuber/portato/cmd/portato@latest
# macOS / Linux: ~/.config/portato/config.yaml
# Windows: %AppData%\portato\config.yaml
tubers:
- name: redis
type: local # -L: listen here, forward to the host
local: 6379
remote: 6379
ssh: user@bastion.example.com
portato # TUI (smart launcher: attaches to a running daemon or starts standalone)
portato daemon # background daemon + IPC server
portato list # status on stdout