Documentation pages

CONCEPTS

Machine trust

Anyone who can push to your sync repo can edit a manifest. So a line in a manifest grants no trust. Instead, each machine signs a record of the packages it installed. Each machine decides for itself which machine keys it trusts.

TRUST A MACHINE By fingerprint, not by Git
Tether trusts a key only when it matches the fingerprint you read on that machine. A record edited in Git fails its signature.↔

Signed machine records

Each machine has an SSH signing key in ~/.tether/signing_key. Tether makes it on tether init, or on the first sync after an upgrade from 1.x. Tether signs this machine's record, machines/<id>.json, in machines/<id>.json.sig. A sync signs it again when its content changed, or when the signed copy is 60 minutes old. The record lists the machine's packages and versions, its profile and its OS.

Tether also signs its commits in the personal sync repo. Commit signatures are an audit trail only. They do not grant trust.

The trust list

Each machine keeps its own trust list in ~/.tether/trusted_keys. The list never syncs. It starts with this machine's own key.

  • A package installs on its own only when a trusted, signed record lists it
  • Trust is transitive. A signed record lists every package its machine installed. So when you trust a machine, you also trust those packages, whoever installed them. A package you rejected on this machine stays blocked
  • A sync adds manifest lines only from this machine's record and the records it trusts

Trust a machine

A key that signs a new machine's record waits in the Inbox as "new machine key". Before you trust it, compare its fingerprint. On the new machine, read its id and full fingerprint:

Terminal
tether machines show

On each of your other machines, trust it with that fingerprint:

Terminal
tether machines trust work-laptop --fingerprint SHA256:...
# or
tether packages approve machine:work-laptop --expect SHA256:...
  • Tether trusts the key only if the fingerprint matches
  • Without --fingerprint, Tether shows the current fingerprint and asks. This works in a terminal only
  • When this machine does not have the signed record yet, machines trust pulls the sync repo first. If the record is still missing, run tether sync on that machine
  • On the dashboard Machines tab, press a on a machine's card to trust its key, or x to untrust it. Both ask first

To stop trusting a machine:

Terminal
tether machines untrust work-laptop

Fleet commands

From one machine, you can change your other machines. Add --on with machine ids or hostnames, separated by commas, or all:

Terminal
tether packages uninstall npm:typescript --on mini,studio
tether packages install brew:ripgrep --on mini
tether machines profile set server --on mini
tether machines trust new-laptop --fingerprint SHA256:... --on all
  • Tether signs the command with this machine's key and pushes it to the personal sync repo. Each machine runs it on its next sync
  • A machine runs a command only when it trusts the key that signed it. Trust already lets a machine's record install packages on your other machines, so trust also lets it send commands
  • Each command has a number and expires after 7 days. A machine never runs a command twice, and does not run an expired command
  • install runs the same checks as tether packages install. A malicious package, a rejected one or one that waits in the Inbox does not install
  • uninstall --on uninstalls the package on those machines and stops their syncs from installing it again. Profiles do not change
  • machines trust --on needs the fingerprint. Compare it on the new machine first. With it, you trust a new machine on all your machines from one machine
  • Tether refuses a machine that it does not trust, and a machine on 2.0.1 or earlier, which cannot run commands
  • machines profile set --on refuses a profile that you created here but did not sync yet. Run tether sync first
  • tether machines show <MACHINE> lists the commands that wait for that machine, and the results it reported: applied, failed or expired. The daemon on the target shows a notification when it runs commands
  • Team and collab repos never carry commands

The dashboard sends the same commands. On the Machines tab, open another machine's details. They list its pending commands, its results and its packages. Press x to uninstall the selected package there, i to install one, p to set its profile, or c to cancel a pending command. Press A on a card to trust that machine's key here and on every machine that runs commands. On the Packages tab, x and i ask which machines when other machines can take the change. Each question names the machines and warns when one has not synced for a day.

A cancel can come too late. A machine that pulled the command before the cancel still runs it. Anyone who can push to the sync repo can also restore a cancelled command until it expires, because its signature stays valid.

Protection against changed records

  • Changed key: when a trusted machine signs with a different key, Tether warns you and holds the new key in the Inbox as "key changed". It does not trust that record until you approve the new key
  • Failed signature: Tether ignores a record that fails its signature and warns: "Record for <id> fails its signature"
  • Replay: each record has a generation that grows with every save. An older signed record from the same key, such as one from git history, does not count
  • Renamed machines: trust never moves to another machine id on its own. A renamed machine waits in the Inbox as a new machine
  • Your own record: this machine builds its record from ~/.tether/machine.json, not from the repo copy

tether machines list and the dashboard Machines cards show each record as a sync reads it. A record that a sync ignores shows "replayed (ignored)" or "signature failed (ignored)".

Old machine ids

Builds before random machine ids used the hostname as the id. Tether marks a record that may be an old id of this machine. This is only a guess. Check that no other machine uses that hostname before you remove it.

tether machines list and tether status show the command that removes it. On the dashboard Machines tab, press D, then y.

Terminal
tether machines remove <old-id>

machines remove also removes the machine's key from the trust list on this machine.

Limits

  • Anyone with a machine's ~/.tether/signing_key can sign records as that machine. Protect it like an SSH key
  • Machines on 1.x have no signing key. Their records grant no trust