pickey 0.4.0

Automatic SSH key selection for git
<p align="center">
  <br>
  <br>
  <img src="logo.svg" width="160" alt="Pickey Mouse">
  <br>
  <br>
</p>

# πŸ”‘πŸ€ pickey

_/ˈpΙͺkiː/_

**Two GitHub accounts, one laptop?**
*`pickey`* picks the right SSH key, automatically!

---

- πŸ”‘ **Automatic SSH key selection** β€” rules match by host, org, or repo path
- πŸ‘€ **Observable** β€” every `git push` / `pull` shows which key is being used
- ⚑ **Fast** β€” single static Rust binary, no runtime dependencies
- πŸ€– **Just works** β€” at clone time, from `/tmp`, from AI agent terminals, any shell

```
$ git push
[πŸ”‘πŸ€] git@github.com:WORK/my-api.git β†’ ~/.ssh/id_work
Pushing…
```

## Install

### Homebrew

```bash
brew install simeoncode/tap/pickey
pickey init # --dry-run (to only preview changes)
```

### Cargo

```bash
cargo install pickey --locked
pickey init # --dry-run (to only preview changes)
```

### Prebuilt Binary

```bash
curl -fsSL https://raw.githubusercontent.com/simeoncode/pickey/main/install.sh | sh
…
pickey init # --dry-run (to only preview changes)
```

## Usage

```bash
pickey [status]           # Shows pickey status + current repo
pickey init               # Enable pickey
pickey init --dry-run     # Preview activation changes
pickey init --revert      # Undo changes made by init
pickey list               # List all rules
pickey check <url>        # See matching rules for URL
pickey test               # Test SSH connection
```

## Configuration

`~/.config/pickey/config.toml`:

```toml
[[rule]]
host = "github.com"
match = "WORK-Internal/*"
key = "~/.ssh/id_work"
email = "email@work.com"
name = "My Name"

[[rule]]
host = "github.com"
match = "MyPersonalOrg/*"
key = "~/.ssh/id_personal"

# macOS Keychain integration is enabled by default.
# Uncomment to disable:
# [macos]
# use_keychain = false
```

Rules auto-detected by `pickey init` include `auto = true` β€” these are safely replaced when you re-run init. Manually added rules (without `auto = true`) are always preserved.

Rules are evaluated top-to-bottom, first match wins. `match` is a glob pattern against the full path after the host. If no rule matches, pickey falls through to plain `ssh` (with a warning).

On macOS, pickey automatically integrates with Keychain for passphrase-protected keys. When a rule matches, pickey uses Apple's OpenSSH (`/usr/bin/ssh`) and injects `-o UseKeychain=yes` and `-o AddKeysToAgent=yes` so passphrases are read from Keychain β€” and saved there on first use. The first `git push` with a new passphrase key prompts once; every subsequent operation is silent. To opt out, set `[macos] use_keychain = false`.

### Fields

| Field | Required? | Description |
|-------|----------|-------------|
| `auto` |  | This rule was auto-generated by `pickey init` |
| `host` | yes | Exact match against the SSH hostname |
| `match` |  | Glob against the path after the host. Omit to match any path on that host |
| `key` | yes | Path to private key (`~` expansion supported) |
| `port` |  | SSH port override (for non-standard ports) |
| `email` |  | Sets repo-local `user.email` β€” [see why]DESIGN.md#why-emailname-in-config |
| `name` |  | Sets repo-local `user.name` |

## How it works

pickey sits as git's `sshCommand`. When git calls SSH, pickey matches the remote against your rules and injects `-i <key>` with `-o IdentitiesOnly=yes` β€” so the right key is used and no others are offered. On Linux, `IdentityAgent=none` disables the agent entirely. On macOS, the agent stays connected (pointing to `$SSH_AUTH_SOCK`) so Keychain can supply passphrases transparently.