Skip to content

fix: survive the host's ssh agent and the bar's PATH - #140

Draft
jzetterman wants to merge 2 commits into
nixfred:mainfrom
jzetterman:fix/ssh-agent-and-bar-path
Draft

jzetterman wants to merge 2 commits into
nixfred:mainfrom
jzetterman:fix/ssh-agent-and-bar-path

Conversation

@jzetterman

Copy link
Copy Markdown

What

Two fixes for hosts whose own setup gets in Blip's way.

  1. Every ssh call that uses the dedicated key now passes -o IdentityAgent=none. That covers blip-shim, the confinement check in blip-setup, and the imsg serve channel in blip-bridged.
  2. blip-setup now checks that bun is on the PATH the bar sees, not only on the PATH of the shell that runs setup. If it isn't, setup stops and prints the symlink that fixes it. The bar's "cannot start bun" error now names the same cause.

Why

The agent wins over -i. ssh offers keys held in an agent before keys read from disk, whatever the order in the config. IdentitiesOnly=yes limits which keys ssh may offer. It does not change that order. So if the user's ssh_config names an agent-held key for the Mac, that key authenticates first, and blip_ed25519 is never offered. I hit this on my own machine:

  • blip-setup gets a normal shell back, decides the key is not confined, and aborts with "dedicated key did not confine as expected". The Mac's authorized_keys was correct the whole time.
  • At runtime the shim and blip-bridged hit the same thing, and nothing tells you. The forced command lives on the dedicated key's line, so a session that logs in with the everyday key skips blip-dispatch and runs the bridge with a full shell. The confinement from SECURITY.md finding blip-check: probe every Contacts source, not just glob()[0] #2 no longer applies.

The dedicated key is always read from disk and never lives in an agent, so turning the agent off for these calls costs nothing.

bun on the wrong PATH. Quickshell inherits the graphical session's environment, which never reads ~/.zshrc or ~/.bashrc. bun's own installer puts bun in ~/.bun/bin and adds it to the shell rc. So setup passes, and every widget action then fails to start. The icon says the Mac is unreachable over a bridge that works fine. Setup reads PATH from the running Quickshell process, or from systemctl --user show-environment when the bar isn't running, and checks for bun there.

How it was verified

  • bun test is green: 750 tests, 0 failures, run locally
  • Every Python test step in ci.yml passes locally (21 files), as does CI's shellcheck -S warning command
  • New test test_the_dedicated_key_channel_refuses_agent_keys in bridge/linux/test_bridged.py. It failed before the blip-bridged change and passes after. All 37 blip-bridged tests pass.
  • Ran the bun check against three cases: bar not running and no user manager (setup continues), bar PATH without bun (setup stops with the fix-it message), live bar (setup continues)
  • The patched shim reads through my own Mac's bridge. I have not re-run the agent bypass live since rebasing. It needs a network path where the everyday key is accepted, and my Mac isn't on one right now.
  • Any send/receive behavior was exercised against my own number only: not applicable, nothing here sends
  • UI change → screenshot attached: not applicable, the only QML change is one error string

Invariants touched: the dedicated-key confinement in docs/SECURITY.md finding #2. The rule itself doesn't change. These fixes make the code keep it on hosts that run an ssh agent.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XNiq5jKqtnDCZpmotePMPf

jzetterman and others added 2 commits October 10, 2026 08:45
ssh offers agent-held keys before on-disk ones no matter what order they
appear in, and IdentitiesOnly only limits which keys may be offered, not
the order they are tried. So on a machine whose ssh_config pins an
agent-held key for the Mac, `ssh -i blip_ed25519` never gets to offer the
dedicated key.

Two consequences, and the second one is the reason this is a fix and not
a tidy-up:

blip-setup's confinement check reads the resulting normal shell as "not
confined" and aborts with "dedicated key did not confine as expected",
pointing the user at a Mac whose authorized_keys is already correct.

blip-shim hits the same thing at runtime. The forced command lives on the
dedicated key's authorized_keys line, so authenticating with the other
key silently bypasses it and the bridge runs with a full shell instead of
blip-dispatch. The confinement SECURITY.md describes stops applying, with
nothing visible to say so.

blip-bridged, added upstream since, builds the same ssh command for its
`imsg serve` channel and has the same hole.

Pass IdentityAgent=none in all three, which costs nothing because the
dedicated key is read from disk and never lives in an agent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPZgnvM2YpZjvkeZuismQP
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNiq5jKqtnDCZpmotePMPf
Quickshell inherits the graphical session environment, which never sources
a shell rc. A bun installed by bun's own script into ~/.bun/bin is
therefore on the user's interactive PATH and absent from the bar's, so
blip-setup's prerequisite check passes while every widget action fails to
start.

That failure is near silent. A process that cannot start returns no useful
status, so the icon falls back to "Mac unreachable" and blames the Mac.
The bridge, the key, and the Mac permissions can all be perfect.

Check bun a second time against the PATH the bar will actually use, read
from a running quickshell when there is one and from the systemd user
environment otherwise. On a mismatch, print the ready-made ln command,
choosing a link directory already on that PATH.

Also correct the widget's own message, which said to install bun with
pacman. Bun was installed every time this fired, so that advice sent
people the wrong way. Recommend a symlink over a second install, since two
copies are free to drift to different versions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPZgnvM2YpZjvkeZuismQP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant