tui-tools

tui-vpn

WireGuard and its control plane, from the terminal

A terminal UI (TUI) for wg and headscale on Linux: WireGuard from the terminal, together with the self-hosted control plane that decides who is allowed onto it.

v0.3.0betanetworkMIT
The status screen: WireGuard interfaces, their state and peer counts, read from wg
The status screen: WireGuard interfaces, their state and peer counts, read from wg

WireGuard from the terminal, together with the self-hosted control plane that decides who is allowed onto it.

The status screen reads your interfaces straight from wg show all dump: peers, endpoints, handshakes, transfer, allowed IPs and keepalive. Creating an interface from zero, up/down, adding or removing a peer, saving the runtime config — every change is previewed as the exact command line and applied only after you confirm it. A private key is never shown, typed, or put on a command line.

With a Headscale control plane it also manages users, nodes and pre-auth keys, and configures identity itself: S writes server_url and listen_addr, O writes the whole oidc section of /etc/headscale/config.yaml, each previewing a minimal diff — only the lines that change. The OIDC client secret is typed masked, written mode 600 to its own file owned by the account the headscale unit runs as, referenced as client_secret_path, and never displayed again. Login stays where it belongs: the client's browser, against your IdP.

Run it with --demo to see every screen with nothing installed.

Keys

KeyAction
tab / 1…5Switch screen (interfaces, peers, users, nodes, keys)
NCreate a new interface from zero (keygen, conf, optional up)
u / dBring the selected interface up / down
wSave the interface's runtime config (wg-quick save)
a / xAdd / remove a peer on the interface (add: optional pre-shared key file)
nCreate a Headscale user (users screen) or pre-auth key (keys screen)
S / OControl plane setup (users screen): server settings / identity provider (OIDC)
e / m / xExpire / rename / delete the selected node
r / ctrl+rReload
?Help
qQuit

Press ? inside the tool for the full help screen, which is generated from the same action table as the key map.

Compatibility

This tool is a face on the program below, so its version matters.Tested is not a claim: a version lands there only after the tool's own suite passed against it on a real machine in the lab, and the run is kept as evidence in the repository. At startup the tool probes the backend once and says what it found in its header — a version nobody has run against is shown as(untested) in the warning colour, one older than the minimum as (below minimum) in the error colour. Neither stops it: the backend still refuses what it cannot do, in its own words.

wireguard-tools

wg ≥ 1.0.20200513
Binary
wg
Minimum
1.0.20200513
Probed with
wg --version
Tested
No recorded run yet. The tool still runs and reports the version it found as untested.

headscale

headscale ≥ 0.22.0
Binary
headscale
Minimum
0.22.0
Probed with
headscale version
Tested
No recorded run yet. The tool still runs and reports the version it found as untested.

What changes on older versions

  • headscale <0.23

    preauthkeys list requires a --user, so the pre-auth keys screen may be empty; users and nodes are unaffected

Install

Once per machine, then every tool in the family is one pacman away.

Add the repository
$ curl -fsSL https://pkgs.tui.tools/install.sh | sh
Or run the same thing yourself, one command at a time

A family whose whole promise is preview before you run is not going to insist you pipe a script into a shell. These are the commands that script runs.

The one-time setup, by hand
$ curl -fsSL -o /tmp/tui-tools.asc https://pkgs.tui.tools/pubkey.asc
  sudo pacman-key --add /tmp/tui-tools.asc
  sudo pacman-key --lsign-key \
    "$(gpg --show-keys --with-colons /tmp/tui-tools.asc | awk -F: '/^fpr:/{print $10; exit}')"
  printf '[tui-tools]\nServer = https://pkgs.tui.tools/arch/$arch\n' \
    | sudo tee -a /etc/pacman.conf
  sudo pacman -Sy
Arch Linux · tui-vpn
$ sudo pacman -S tui-vpn

Available once the first release lands in pkgs.tui.tools.

What it can do to your machine

  • Preview, then confirm

    Every change is shown as an exact command line and confirmed before it runs. The dialog and the runner receive the same value, so the preview cannot drift from what executes.

  • Escalates for actions

    Reading a WireGuard interface needs CAP_NET_ADMIN, the Headscale CLI talks to a root-owned socket, and /etc/headscale/config.yaml is root-only, so those reads escalate; ip link and systemctl is-active do not. Every mutation escalates, previewed and confirmed first.

  • No daemon, no state of its own

    Nothing keeps running after you quit, and nothing is installed to run later. The system is the source of truth; the tool re-reads it after every change.

  • Opens network connections

    One outbound request, on demand only: when you configure an identity provider it fetches the issuer's public /.well-known/openid-configuration with curl, to check the URL before saving it. Read-only, unprivileged, and a failure is a warning, not a refusal. Nothing else leaves the machine.

  • Static binary

    Released statically linked, with no runtime dependencies to install.

  • Signed release, with provenance

    checksums.txt carries a keyless cosign signature from this repository's release workflow, every archive has a CycloneDX SBOM, and every archive, package and the checksum file carry SLSA build provenance. The security page shows the three commands that check it.

Reporting

Report a security issue privately, through GitHub's private vulnerability reporting on the repository's Security tab. The family-wide policy, and what counts as in scope, is on the security page.

Downloads

v0.3.0 · 2026-09-02
FileSizeSHA-256
checksums.txt996 B
checksums.txt.sigstore.json10 KB
provenance.intoto.jsonl12 KB
tui-vpn-0.3.0-1-aarch64.pkg.tar.zst1.8 MBab7e31e6b4d83bdfb382e250ec9bbf9a6414b6b7895db5c2b53e0e370dc641aa
tui-vpn-0.3.0-1-x86_64.pkg.tar.zst2.0 MBca1664f1df3dafed7200a454f6f961581f3ad9f65b8b2f30bee32fcb6f3f59cb
tui-vpn-0.3.0-1.aarch64.rpm1.8 MBb5d5089adab3450a1bfc148a4f509bb6c715551e9a21623b5c9fc04888639ce9
tui-vpn-0.3.0-1.x86_64.rpm2.0 MBdea5861d487f5486b26df4f7c877030e6029f9e2613753541090c20c656dedc7
tui-vpn_0.3.0_amd64.deb2.0 MBe2e8a79b0d094ca3ccdd71c4221184805ed85ede01ae1c39d3c84400927183e2
tui-vpn_0.3.0_arm64.deb1.8 MB2f811dfa81fa00c2ca6422749ba25395416306d7dd667ab1ad8bb9962e9b50c2
tui-vpn_0.3.0_linux_amd64.tar.gz2.0 MB1202b77b4dc3a7f2ed3ac5b8be26ab8c6669880a4e003cfe8bea41c37d16ce54
tui-vpn_0.3.0_linux_amd64.tar.gz.cyclonedx.json24 KBc678ba3f715616bd8d42cbc584592730cd07886937e5ff7ad576ffdb0e7a2fe0
tui-vpn_0.3.0_linux_arm64.tar.gz1.8 MB1dbc38c1cbbee381ef8e843d56c09b98e17bed7bbf5c7063d975380e61949d23
tui-vpn_0.3.0_linux_arm64.tar.gz.cyclonedx.json24 KB2b569455880948baaa6d81fbbc4599b61749c52a9d7a83f7e45fdcc839b991c7

Every release ships a checksums.txt. Download it next to the archive and run sha256sum -c checksums.txt --ignore-missing. See verifying a download.

Releases

v0.3.0

2026-09-02
## tui-vpn v0.3.0

v0.3.0: headscale server settings and OIDC identity provider setup from the users screen

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* e305fd9bb243a155c5f7c6c362e30987fb13692a Manage the control plane's identity, not just report on it (#8)

v0.2.1

2026-09-02
## tui-vpn v0.2.1

tui-kit v0.3.0: the dialogs wrap and scroll instead of clipping the
command preview, and the picker filters as you type.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* acb05fbcbb276183df33e515d6050cf3c615e520 Bump tui-kit to v0.3.0 (#7)
* 35cc8c9bdf18225d1372b40982fcce3b97fc1271 tool.json: released (#6)

v0.2.0

2026-09-01
## tui-vpn v0.2.0

Manage, not view: create and edit from the TUI (wave 1), lab-validated on the router image.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* b40ba2f90774e40ed7a58ca7c5168f78e5dc5e55 Manage, not view: interface bootstrap, persistence, preauth create, node ops (#5)

v0.1.0

2026-09-01
## tui-vpn v0.1.0

First validated release: the router-1.0 lab ran this tool against real VMs (tui-lab router topology).

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 237b88f9ebabbd872cd7bb1a79bf54642ee2816a Bump anchore/sbom-action/download-syft in the github-actions group (#1)
* 99ad5cf18e22469b643e1484677e8ea30400367a Initial commit
* 25578d404a7274369384ba7bdbfc64b5dbe02a2b Phase 1: WireGuard + Headscale (read-mostly, previewed mutations) (#2)
* e546638c2dc3256e2bbfe71931a52ce573c895c8 Render the screenshots from the demo, and name them for the real screens (#3)
* 9bf282e20ba44ac03ccb28d62ba4ef8cac86c62b headscale: read the gRPC-gateway build's protobuf-json (0.2x), not just ogen (#4)