Repository navigation
Releases: olivierzol/fob
Release list
fob v0.17.1
A small release: the Touch ID prompt now fits the redesigned macOS 27 dialog, and the menu-bar panel gets an opaque backdrop.
Touch ID prompt, retuned for macOS 27 (#39)
macOS 27 restyled the LocalAuthentication dialog — the separate bold app-name row is gone and the whole reason string is now the bold headline, in a narrower window. fob's prompt was written for the old regular-weight body slot, so it turned into a heavy four-line bold block.
The prompt is trimmed, without giving up what makes it an authorization decision rather than a rubber stamp:
fob is trying to connect to github-ousson (github.com)
for ssh (pid 10110).
Touch ID to continue with fob.
The signing key's name is dropped when it's already the destination alias, and kept when it isn't — notably for an UNKNOWN destination, where naming the key matters most. The wording reads fine on macOS 26 too, so there's no version-specific copy.
Menu-bar panel (#38)
An opaque backdrop behind the panel, so it no longer picks up whatever is behind it.
Install
brew install --cask olivierzol/fob/fobDeveloper ID–signed, notarized and stapled. sha256: 94982b96e81fe8c350ead7064494e8abf796063ecf960eda84e3db3eb4151a77
fob v0.17.0
Move your fob setup to a new Mac.
Secure Enclave keys physically can't leave the Mac that made them — that's the security property. What can move is everything around them, and now fob does it for you:
fob export-profile # on the old Mac
fob import-profile fob-profile.json # on the new one
- The profile contains no key material — just key names, policies (pins, reuse windows, namespaces, protection level), your
~/.ssh/confighost mappings, and the signing setup. - The import creates fresh enclave keys under the same names at the same protection level, restores every policy, rewrites
~/.ssh/config(diff + confirm + backup), and prints a checklist of where to register each new public key — with the retired key's fingerprint so old entries can be pruned. --dry-runshows the whole plan without touching anything.
Also in this release: each key's protection level (Touch-ID-only vs any user presence) is now recorded, so rotation and migration preserve it instead of silently downgrading.
Upgrade: brew upgrade --cask fob — or just click Update in the panel banner.
fob v0.16.5
One-click updates.
The "update available" banner now has an Update button that runs brew upgrade --cask fob in Terminal and reopens fob — no more copy-pasting the command. (It helps for updates after this one, since the installed build needs the button.)
Upgrade: brew upgrade --cask fob
fob v0.16.4
Security hardening from third-party (Codex) and follow-up self-audits — all Low severity; no critical/high/medium.
- Bounded ssh output + deadline: the agent can no longer be stalled or memory-exhausted by a malicious/compromised selected host during migrate/verify (CWE-400).
- Provider settings links restricted to canonical origins: a look-alike host like
github.com@evil/github.com.evilcan no longer open an attacker page under a provider button (CWE-601). - Shared
Hostline protection: migrating one alias of aHost a b(orHost a *.internal) line is refused instead of silently rewriting its siblings/wildcard matches (CWE-706). - Checkup now flags group/other-readable
fob_*.pubfiles (the perm that caused the "UNPROTECTED PRIVATE KEY → password" confusion) with a one-clickchmod 600. - Audit log no longer advances its hash chain on a failed append (avoids a false “tampered” on a write error).
Upgrade: brew upgrade --cask fob
fob v0.16.3
Clarifies fob's agent vs the system ssh-agent.
After a reboot, ssh-add -l shows "The agent has no identities" and it looks like your fob keys vanished — but fob keys live in fob's own agent (~/.fob/agent.sock, reached via IdentityAgent), not the system ssh-agent, so a plain ssh-add -l is expected to look empty (ssh <host> still works). Settings → Agent socket now explains this and offers a copy-able SSH_AUTH_SOCK=~/.fob/agent.sock ssh-add -l to list fob's keys.
Upgrade: brew upgrade --cask fob
fob v0.16.2
Security follow-up from an independent re-audit.
- CG-04 (server migration) fully fixed. The v0.16.1 first-use fingerprint warning covered git hosts but the server-migration flow had a gap: the key-install step (
accept-new) added the host key toknown_hostsbefore the UI recorded first-use state, and the server "Lock it down" step never showed the fingerprint warning. A first-connection (possibly MITM) host key could be pinned without an out-of-band check. fob now captures first-use state before making any connection and shows the SHA-256 fingerprint confirmation in the server flow too.
See SECURITY_AUDIT_REPORT.md for the full trail (found in the v0.16.1 re-audit, closed here).
Upgrade: brew upgrade --cask fob
fob v0.16.1
Security hardening + a fix for a confusing SSH failure.
Security (from an independent audit — see SECURITY_AUDIT_REPORT.md):
- Strict SSHSIG parsing: a malformed signing request is refused instead of signed under a "git commit" label.
- Policy changes (pin/reuse/rotation) now fail closed on an unreadable policy — no more silently dropping a pin. Key rename is transactional.
- Values read from
~/.ssh/configare revalidated before everysshcall (no leading--option injection). - Migrate/verify uses
StrictHostKeyChecking=yesfor already-known hosts and labels first-use connections as trust-on-first-use, showing the host-key fingerprint before pinning.
Fixes:
- Export
fob_<name>.pubas0600. A world-readable pub could makesshprint "UNPROTECTED PRIVATE KEY FILE … will be ignored" and fall back to a password when the agent was momentarily unavailable. Checkup now also flags any existing group/other-readable fob pub. - Configure window pages (Migrate, New key, Signing, Rotate) scroll instead of clipping a long list.
Upgrade: brew upgrade --cask fob
fob v0.16.0
SSH checkup now flags hosts you've connected to but never set up with fob.
If you ssh to a host with a password, its key lands in ~/.ssh/known_hosts but no ~/.ssh/config entry is written — so earlier checkups (which discovered hosts only from config) never saw it. Now the checkup surfaces any such host and offers to add a Touch ID-gated Secure Enclave key for it.
- App: a “Set up ‹host›…” button opens the New key tab prefilled for the host (git-host vs server auto-detected).
- CLI: same finding in
fob checkup, withfob setup ‹host›guidance. - Handles comma lists and
[host]:port; skips comments,@cert-authority/@revoked, wildcards, and localhost; counts unreadable hashed entries.
Upgrade: brew upgrade --cask fob
fob v0.15.0
In-app update nudge. fob now checks GitHub's public releases about once a day and shows a subtle banner in the panel when a newer version is out — with a Release-notes link and a copyable brew upgrade --cask fob.
- Opt-out via Settings → Check for updates automatically (default on), plus a Check now button and the running version.
- Zero new dependencies; no data about you is sent; silent no-op on failure or when disabled.
Upgrade: brew upgrade --cask fob
fob v0.14.0
Key rotation, completed.
- Rotate any key — Keys tab → ••• → Rotate… (or
fob rotate <key>) now works for server and git-host auth keys, not just signing keys. fob mints a fresh Secure Enclave key, adds it alongside the old one (servers: installed with your current key — no lockout; git hosts: you add it on the web), verifies the new key, then swaps and retires the old one — keeping the same name so your~/.ssh/configneeds no changes. - The old key is destroyed only after the new one is verified and in place; fob reminds you to remove the old key from the server/host.
Builds on v0.13.0 (signing-key rotation), so rotation now covers every key role.