fob

Your Mac as a key fob — SSH keys that live in the Secure Enclave, open only the doors they're badged for, and take one touch to use.

$brew install --cask olivierzol/fob/fob View on GitHub

Zero dependencies · macOS 13+ · open source (AGPL-3.0)

Keys that can't be stolen, used, or misdirected

The private key is generated inside the Secure Enclave and never leaves it — what's on disk is an enclave-wrapped blob that's useless anywhere else. No key file to steal, back up, or leak.

🔐

Keys in the Secure Enclave

Non-exportable. Nothing usable on disk, in memory, or in a backup.

👆

One touch per use

Every fresh signature needs Touch ID, Apple Watch, or your password.

🎯

Destination-aware prompts

See where you're connecting — cryptographically verified, not guessed.

📌

Per-host pinning

A key refuses every host but the one it's bound to. A stolen socket can't redirect it.

⏱️

Opt-in touch reuse

One touch can cover a quick git / rsync burst. Off by default.

✍️

Touch ID commit signing

Sign git commits from the enclave; GitHub & GitLab show Verified.

🚚

Safe migration

Moves an existing SSH host to fob alongside the old key — no cutover, no lockout.

🩺

SSH checkup

A read-only hygiene report of your ~/.ssh: weak keys, risky config, footguns.

📜

Tamper-evident audit log

A hash-chained record of every decision — so key use is never silent.

🖥️

Menu-bar app + CLI

Live activity feed, guided setup, and a scriptable fob command.

How it works

fob is a presence-gated key store — an ssh-agent that signs only with your finger, for the host you meant.

🎯 Destination-aware prompts

The Touch ID prompt names the verified host — fob checks the session-bind host-key signature and resolves the name from known_hosts. Unknown clients show as "an UNKNOWN destination."

📌 Per-host pinning

A pinned key is refused for any other destination before any prompt, so a blocked request never costs a touch.

fob pin mykey myhost

⏱️ Touch reuse

Let one approval cover the next few seconds of signatures — reused ones are still pin-checked, notified, and audited.

fob reuse mykey 30

📜 Tamper-evident audit

Every decision is appended to ~/.fob/audit.log as a SHA-256 hash chain you can verify.

fob audit --verify

Set up in a minute

Install, open fob from the menu bar, and point one host at it. Your existing keys keep working the whole time.

1 · Install
brew install --cask olivierzol/fob/fob

Then open fob from the menu bar and turn on “Launch at login”.

2 · Set up a host
fob setup myserver you@host

Creates a Secure Enclave key, installs it, and writes your ~/.ssh/config.

3 · Connect
ssh myserver # prompts for Touch ID, then connects

An honest security model

fob is a presence-gated key store, not a sandbox around your own logged-in session. Here's exactly what that buys you — and what it doesn't.

✅ Strongly protected

  • Key theft. The private key never leaves the enclave; the on-disk blob is device-bound and useless elsewhere.
  • Memory scraping. The enclave performs the signature; the key never enters process memory.
  • Silent use. Every fresh signature requires your presence.
  • Wrong destination. A pinned key signs only for its verified, bound host.

⚠︎ Not protected (by design)

  • Code running as you, unlocked. Inherent to any ssh-agent — each sign still hits Touch ID (unless a reuse window is open).
  • A compromised remote host / agent-forwarding hijack — prefer ProxyJump over ForwardAgent.
  • You, the owner. The audit log is tamper-evident, not tamper-proof.

Two independent audits (findings resolved) + a regression suite are in SECURITY_AUDIT_REPORT.md.