Documentation
Your own sync server
termiport-server is the sync server. It is not the terminal. The macOS app — and the Android build while it is under development — talk to it over HTTPS and store only ciphertext. You run the server yourself.
Any server is free for any number of accounts. Without a license, each account has three active devices. Through 2028 (the development and testing period), free licenses for unlimited devices and unlimited duration are issued on request; a license for the account email raises that account’s device limit on every TermiPort server, not only the one that stored the file.
Install the package from the public repositories at deb.yukh.net (Debian 12 and 13, amd64) and alt.yukh.net (ALT p11 and Sisyphus, x86_64). Those repos also list other packages; the sync daemon is termiport-server.
Debian 12 and 13
On Debian bookworm (12) or trixie (13), add the repository signing key and an APT source, then install the package. Set SUITE to match the machine: bookworm or trixie.
export SUITE=trixie
sudo install -d -m 0755 /usr/share/keyrings
curl -fsSL https://deb.yukh.net/deb.yukh.net.gpg \
| sudo tee /usr/share/keyrings/yukh.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/yukh.gpg] https://deb.yukh.net $SUITE main" \
| sudo tee /etc/apt/sources.list.d/yukh.list
sudo apt update
sudo apt install termiport-server
The key file is also at https://deb.yukh.net/deb.yukh.net.gpg (and .asc). Check it with gpg --show-keys /usr/share/keyrings/yukh.gpg; the uid is deb.yukh.net (repository signing key).
The package creates the termiport-server user, /etc/termiport-server/config.toml, and a systemd service, and starts it on loopback with invite registration.
ALT Linux p11 and Sisyphus
On ALT, add the repository with apt-repo, then install. Set BRANCH to p11 or sisyphus.
export BRANCH=p11
apt-repo add rpm https://alt.yukh.net $BRANCH/branch/x86_64 classic
apt-get update
apt-get install termiport-server
systemctl enable --now termiport-server
The layout matches Debian: the same user, unit, config file, and data directory. As ALT presets require, the package installs the service disabled until you enable it.
What you configure
The process speaks plain HTTP. By default a package listens on 127.0.0.1:8080. HTTPS is a reverse proxy in front of it. Leave the server’s own tls.cert and tls.key empty.
public_url is required. It is the https:// address people type in the app, for example https://sync.example.org. The app refuses to sync if the server calls itself something else. After a move, put the old address in aliases so devices that still have it keep working.
registration is invite by default, or open. Open registration needs SMTP, because the server emails the confirmation code. With no SMTP, an administrator issues the code.
With SQLite, the data directory holds server.db and server.key. With PostgreSQL, the database holds the accounts and the ciphertext, and the data directory holds server.key. Losing server.key leaves existing TOTP factors unusable. The app still encrypts records; the server key is not the account key.
trusted_proxies is the reverse proxy the server will believe for X-Forwarded-For. The default is loopback, which is right when the proxy is on the same machine. Do not set it to every address. A proxy somewhere else must be listed as the address the server actually sees, or every client shares one sign-in limit.
First run
- Set
public_urlto the address the app will use. - Point the reverse proxy at the server and give it a certificate.
- Restart the service. The log line
listeningincludes the address, version, database, and whether mail is on. GET /v1/infoon the public URL returns the server name, version, API, registration mode, andpublic_url.- For invite registration, issue an invite for the first email. In the app: Settings → Sync → Set Up Sync… → Create Account…, with that address, email, and invite code. The rest of the flow is on Vault and sync.
What the server sees
- SSH sessions go from the app to your hosts. The sync server is not on that path and does not see your terminals.
- It stores ciphertext. It does not see host names, usernames, private keys, or device names.
- App updates come from the developer, separately from sync.