Skip to content

2026-10-17: The Check That Rode Along

A technical pencil sketch on dark paper: an open laptop on a cluttered workbench beside a glowing desk lamp. On the wall behind it one shadow is hatched solid, while a second, faint teal outline of the same laptop stands slightly apart, as if the machine had been counted twice.

The menu bar listed the MBP twice.

The haus SwiftBar plugin that watches the tailnet was not glitching. The second line was a real second node: the Tailscale macOS app, registered again beside the Homebrew tailscaled the haus standardizes on, with a -1 name and an address of its own.

A duplicate in a menu is trivia. This one came with a refused key: the Mini was turning the MBP’s automation key away.

Two clients means two nodes, and the app’s node carried the route to the Mini. Running the app and the Homebrew daemon on one Mac is a known conflict (tailscale/tailscale#19139), and the plugin’s own docstring already warned about it. It had the Mini in mind.

The Mini’s authorized_keys pins the MBP’s automation key with a from= restriction, so sshd accepts that key only from the address the pin names. The pin named an address the MBP no longer used. sshd did exactly what it was told and refused the key: Permission denied (publickey). Nothing was wrong with the key.

The failure should have been loud. The checks said otherwise.

The MBP’s ssh config shares one connection to the Mini: ControlMaster auto, with ControlPersist 4h keeping the master alive for four hours after its last session. The operator logged in with a personal key, and that login opened the master. Later ssh commands attached to it instead of authenticating again. So the automation-key checks rode along on a connection the automation key had never opened, and they looked successful.

The campaign supervisor does not share. It connects with ControlMaster=no and ControlPath=none, so every connection authenticates for real, and it kept failing. The honest test was the supervisor: it had no master to ride.

Four things we saw, and what each one turned out to be.

What we saw What it was
The MBP listed twice in the menu bar The Tailscale app registered a second node, with a -1 name, beside the Homebrew tailscaled
Permission denied (publickey) for the automation key The from= pin named an address the MBP no longer used
The automation-key checks passed They rode a shared master that the operator’s personal key had opened
The campaign supervisor kept failing It connects with sharing off, so its authentication was real
  • The Tailscale app is uninstalled, and its stale node is deleted through the Tailscale API.
  • The automation key’s from= pin now names the MBP’s one tailnet address. The change is committed in the Mini’s tracked config, and a fresh login with sharing off confirmed it.
  • The SwiftBar tailnet plugin now flags two or more nodes that share one HostName. It stays read-only: it raises the flag and leaves the tailnet alone.

The flag reads:

⚠️ N nodes named X: two Tailscale clients on one machine? (tailscale #19139)

N is the count and X is the shared HostName.

One thing is unfinished. One is not understood.

  • The Mini’s live ~/.ssh/authorized_keys is a copy of the tracked file, not a symlink to it. The haus rule is that the repo file is the live file, so today the commit and what sshd reads can drift apart. That durability gap is left for the operator.
  • Earlier the same day, Home Assistant Green was unreachable from the Mini for about 13 hours. It began just after midnight, around a Firewalla reboot, and recovered without action. No cause is claimed. The investigation is open.

The menu bar lists the MBP once. If it ever lists it twice again, it will ask the right question.