First stable release of Keychain 3.
Keychain 3 is a ground-up Python 3 evolution of Daniel Robbins' long-running SSH and GPG agent orchestrator. It preserves Keychain's single-file deployment model as a single-file, self-contained keychain.pyz (see Python Rationale), while replacing the historical Bourne shell implementation with a tested, auditable Python package. It requires Python 3.9 or newer and has no third-party runtime dependencies.
The 3.0.0 release incorporates the work delivered through all three public betas. Highlights include:
-
One coordinated agent experience across terminals and sessions. Keychain discovers, validates, starts, and reconnects to a long-running agent per user and host. Managed
ssh-agentsockets now live at stable, host-specific paths under~/.keychain/, avoiding fragile temporary socket directories. -
Coordinated multi-terminal initialization. When several shells discover missing keys at the same time, they cooperate instead of racing for a lock or displaying duplicate passphrase prompts. Any waiting terminal can take over an inaccessible prompt, and all participants are notified when key loading completes.
-
A modern interface with strong 2.x compatibility. The action-oriented command surface includes
add,agent,list,env,inspect,help, andman. Traditional Keychain 2.x invocations remain supported through an explicit compatibility layer; intentional differences are documented underkeychain man topic:compat. -
Broader SSH and GPG workflows. Keychain can load PKCS#11 providers for smartcards and hardware tokens, use or start
gpg-agentwith SSH support, and explicitly warm GPG signing, encryption, and decryption credentials. Verification failures are reported instead of being mistaken for success. -
Native macOS confirmation support. When
--confirmis used with a new Keychain-managedssh-agent, Keychain installs a private, confirmation-onlyosascripthelper and gives OpenSSH a zero-dependency, native macOS Allow/Deny dialog for each key use. It works entirely with facilities built into macOS, with no additional askpass package or graphical toolkit to install. Denial, cancellation, a missing desktop session, or helper failure all fail closed.--confirmand--no-guiare intentionally incompatible. -
Configuration, inspection, and embedded documentation. Persistent preferences may live in an optional
~/.keychainrc;keychain inspectexposes resolved runtime state in human-readable or JSON form; and the complete, versioned manual ships inside the zipapp with topic and option-level help (keychain manandkeychain man --list). -
Hardened state handling and testing. Agent sockets, pidfiles, locks, coordination state, and waiter endpoints are ownership- and permission- checked. The test suite covers modern and legacy CLI behavior, real SSH and GPG integration, multi-terminal coordination, and supported platform differences.
Changes since 3.0.0_beta3:
- Added zero-dependency, native macOS
--confirmdialog support (#222). - Made
--confirm --no-guifail explicitly. - Fixed an issue where
--quietsuppressed the prompt to press Enter to initialize keys (#223). - Expanded
inspectwith.keychainrcstatus, effective settings and their sources, runtime identity, and relevant environment state.inspect --jsonnow emits a versioned diagnostic report suitable for bug reports. - Completed a dedicated security hardening pass across runtime storage, configuration, agent handling, and generated shell output. Keychain now rejects unsafe ownership or permissions on
.keychainrcand runtime files, validates SSH endpoints before use, rechecks agent identity before stopping it, writes private state atomically, quotes exports for each target shell, and rejects unsafe control characters. - Reworked concurrent initialization around operating-system advisory locks. Lock ownership and liveness no longer depend on PID heuristics; locks are released automatically when the owning process exits, and abandoned activation handoffs are safely reconciled.
- Hardened the release pipeline with commit-pinned GitHub Actions, verified release artifacts, and automatically generated SHA256 checksums.
- Converted command timeouts, malformed agent arguments, and operating-system failures into concise user errors instead of Python tracebacks (#224).
- Corrected askpass environment handling to follow OpenSSH's
DISPLAY,WAYLAND_DISPLAY, andSSH_ASKPASS_REQUIRE=forcerules. - Strengthened GPG warm-up verification so
gpga:proves both signing and decryption capability before reporting success, and made decrypt verification portable by avoiding/dev/nullas the temporary encrypted payload. - Expanded end-to-end SSH confirmation and agent startup coverage.
- Shortened managed
ssh-agentsocket names to avoid UNIX-domain socket path limits on macOS, Linux, and other POSIX systems. - Extensive code cleanups throughout the codebase (removing deprecated code, simplifying logic where possible, etc.)
macOS --confirm note: Keychain’s native confirmation dialog requires an ssh-agent started by Keychain, because an existing launchd-managed agent cannot receive the required SSH_ASKPASS environment after it has started. Before first enabling confirmation, run keychain agent stop, then invoke Keychain with --no-inherit --confirm. For persistent use, set inherit = false and confirm = true under [agent] in ~/.keychainrc.