GET STARTED
Upgrade from 1.x
Tether 2.0 signs machine records, checks synced packages before it installs them, and gives packages to profiles. After the upgrade, each machine must trust your other machines once. Until then, packages from those machines wait in the Inbox.
Work through this checklist on each machine, one machine at a time.
Before you start
- You can upgrade one machine at a time. A sync repo can hold 1.x and 2.0 machines together. Machines on 1.11.10, 1.12.0, 1.13.1 and 1.13.2 read the files that 2.0 writes
- Patch each machine that stays on 1.x for a while to 1.13.2 first. Earlier 1.x builds push their old copy of
config.tomlback after they apply a synced one. That reverts config changes from other machines. Homebrew now installs 2.0, so install 1.13.2 from its GitHub release (macOS), or build it:cargo install --locked --git https://github.com/paddo-tech/tether-cli --tag v1.13.2. See Machines on 1.x - Plan to make config changes, such as profiles, after the upgrade. See Config merge
Checklist for each machine
1. Upgrade the binary
brew upgrade tether-cli If you used the install script, run it again. If you installed a release download or built from source, install the new version the same way. See Install.
On Linux, run tether daemon install again after the upgrade. The systemd unit names the path of the binary that installed it, and Homebrew removes the old version's path.
2. Sync once in a terminal
tether sync The first sync makes the machine's signing key and signs its record. On macOS, it also moves the daemon to a fixed copy of Tether. See App Management on macOS.
The sync then asks "Install these packages?". Choose Decide later.
"Install all" approves every package it can name in one step. That includes packages that only unsigned 1.x records list, and formulae from taps you do not trust. Trust your machines first. Their packages then install without a question, and the Inbox keeps only the items that need a look.
3. Trust your upgraded machines
On each upgraded machine, read its id and full key fingerprint:
tether machines show On each other upgraded machine, trust it with the fingerprint you read:
tether machines trust <host> --fingerprint SHA256:... Read each fingerprint on the machine itself. A fingerprint from the sync repo proves nothing, because anyone who can push can change the repo. If this machine does not have the record yet, machines trust pulls the sync repo first.
A machine on 1.x has no signed record, so you cannot trust it yet. Upgrade it, sync it, then trust it.
4. Sync again and review what is left
tether sync
tether packages inbox The sync installs the packages that your trusted machines list, when they pass the package checks. The Inbox shows what is left, grouped by source machine and reason. Approve or reject each item, or approve a reviewed group:
tether packages approve <manager:name>
tether packages approve --all --from <machine> # after you review the list approve --all lists the packages and asks first. It leaves machine keys, malicious packages, packages whose record fails its signature, and packages without a version or tap to name in the Inbox. See The Inbox.
5. Allow App Management on macOS
On macOS, launchd now runs a copy of Tether at ~/.tether/bin/tether. The plist names the installed binary in TETHER_DAEMON_SOURCE. When that binary changes, the daemon copies it again and restarts. So the daemon follows each upgrade by itself.
macOS keeps the App Management permission per program path. The fixed path keeps one permission across upgrades. Before, each upgrade asked again.
- The first
tether syncin a terminal after the upgrade moves an installed daemon to the copy.tether daemon installdoes this too - macOS then asks once for App Management for the new path. Allow it in System Settings > Privacy & Security > App Management
- To add the copy by hand in the file picker, press Cmd+Shift+. to show hidden folders such as
~/.tether - Remove the old
tetherrows from the App Management list tether daemon uninstallremoves the copy
6. Delete the old plaintext config copy
Earlier versions wrote a plaintext copy of the synced config to ~/tether/config.toml once, on the first sync of a new machine. Tether no longer writes it. You can delete it:
rm ~/tether/config.toml 7. Check your settings
- Add the third-party Homebrew taps you use to
packages.brew.trusted_taps. See Homebrew taps - Add packages that need install scripts to
packages.allow_scripts - Change
packages.min_release_age_daysif 7 days does not suit you - Remove records that
tether machines listmarks as an old id of this machine. See Old machine ids - Check that each machine has the profile you want. Packages now go only to the profiles that have them. See Packages per profile
Machines on 1.x
tether status, tether machines list and the dashboard Machines tab mark each machine that still runs 1.x as "on 1.x".
- A machine on 1.x does not run the new checks. It still installs every synced package without them
- Its record has no signature. Its packages wait in the Inbox of 2.0 machines as "from another machine". Approve them one by one, or upgrade that machine and trust it
- It ignores profiles. It installs the packages of every profile
- A 1.x machine before 1.13.2 pushes its old copy of
config.tomlagain after it applies a synced one. That copy reverts config changes made since, and 2.0 cannot tell it from a real change. Patch or upgrade the 1.x machines, then make the change again - When a synced config changes this machine's profile, a 2.0 sync warns, names both profiles, and names the command that restores it
What changed in 2.0
- A synced package installs on its own only when a trusted machine record lists it. A line in a manifest grants no trust
- A machine installs only the packages of its own profile. Nothing is uninstalled. The first sync counts the packages that no longer come to this machine, and names the commands that list and share them
- Packages from untrusted Homebrew taps now wait in the Inbox. Before, Tether skipped them with a warning
- For gem, and for npm before 11.10, pnpm before 10.16 or at a 12.0.0 prerelease, and bun before 1.3, Tether checks the release age itself in the registry. It installs the release it checked. It holds a package only when the release is too new or the registry check fails
- Tether checks npm, pnpm, bun, uv and gem packages against OSV before it installs or upgrades them
- npm, pnpm and bun install with install scripts off
- Tether no longer runs
brew update. Run it yourself to update Homebrew tether upgradeasks first, lists what it changes, and never downgrades a packagetether packagesnow lists packages.tether packages uninstallreplacesremove, which stays as an aliastether ignore secretsandtether ignore filesreplace the oldtether ignoreforms, which still worktether machines rename <NEW>renames only the machine it runs on-yconfirms prompts and takes their defaults. It does not trust keys. It approves Inbox items only intether packages approve --all -y. See Exit codes and -y- A failed command exits with status 1 and prints one
Error:line. A usage error, such as an unknown flag, exits with status 2 - A sync merges
config.tomlthree ways, so edits from two machines both stay. See Config merge - The Config tab no longer shows the
sync_versionssettings. Tether still writes them, because 1.x builds need them to read the synced config. A new config getsfalse, and an existing value stays