Combining Keychain and 1Password CLI for SSH Agent Management
A method to use 1Password CLI for secure SSH key passphrase storage while leveraging Keychain for persistent agent access and minimal prompts.
Combining Keychain and 1Password CLI for SSH Agent Management #
For about a decade, I’ve relied on two key tools in my development workflow: Funtoo Keychain for managing my ssh-agent
and 1Password for securely storing secrets.
While I used them extensively, I never actually integrated them directly for SSH key passphrase handling.
Recently, with the advent of 1Password’s built-in SSH agent, I gave it a try, attracted by the promise of managing keys directly within my vault. However, I quickly found myself frequently prompted for my master password or biometrics, which interrupted my flow more often than I preferred compared to Keychain’s persistence.
This led me back to the reliable “unlock once per session” behavior of Keychain.
But the experience using the 1Password Command-Line Interface (op
) during that time sparked an idea: could I combine the persistence of Keychain with the secure passphrase retrieval of the op
CLI?
The answer is yes, and this post outlines the setup that achieves that balance.
The Goal: Use 1Password as the secure vault for the SSH key passphrase but rely on keychain
to manage the ssh-agent
process and ensure the key, once unlocked, remains available for the entire login session without further prompts from 1Password.
op
) and Funtoo Keychain installed.
This post assumes you have a working SSH key and a 1Password with the CLI installed and authenticated.
Run brew install --cask 1password-cli
and brew install keychain
to install them.Why This Approach?
This setup directly addresses the trade-off I encountered.
Funtoo keychain
excels at starting ssh-agent
reliably on login and keeping keys available throughout a session with just one initial unlock.
While the native 1Password agent is convenient for vault integration, its session management, in my experience, led to more frequent authentication prompts than desired for long-running sessions.
By using keychain
for agent management and calling the op
CLI via the standard SSH_ASKPASS
mechanism only for the initial key load, we get the best of both worlds: 1Password’s secure storage for the passphrase and Keychain’s persistent agent access with minimal prompting after the first unlock.
The Components:
- Funtoo
keychain
: Managesssh-agent
lifecycle and loads specified keys. - 1Password CLI (
op
): Securely retrieves secrets (the passphrase) from your 1Password vault. Requiresop
to be installed and logged in. askpass-1password.sh
: A small helper script thatssh-add
(viakeychain
) calls to get the passphrase. This script invokesop
.setup_ssh_agent.sh
: A script sourced by your shell startup file (.zshrc
,.bashrc
, etc.) to orchestrate the setup.
Implementation:
Step 1: Create the askpass
Helper Script
This script simply calls op read
to fetch the passphrase using its Secret Reference URI.

- Find your SSH key item in 1Password.
- Locate the passphrase field, click the options/arrow, and copy the “Copy Secret Reference”.
- Create the script at
~/.ssh/askpass-1password.sh
:
#!/bin/sh
# ~/.ssh/askpass-1password.sh
# Provides the SSH key passphrase from 1Password CLI via SSH_ASKPASS
# Paste your Secret Reference URI here
OP_SECRET_REFERENCE="op://YourVault/YourSSHKeyItem/password"
# Use 'op read' to retrieve and print the passphrase to stdout
# Requires 1Password CLI ('op') to be installed and authenticated.
op read "$OP_SECRET_REFERENCE"
- Make it executable:
chmod u+x ~/.ssh/askpass-1password.sh
Step 2: Create the Setup Orchestration Script
This script checks if op
is available and conditionally configures keychain
to use the helper script.
(Adjust path ~/dotfiles/scripts/setup_ssh_agent.sh
as needed)
#!/bin/zsh
# ~/dotfiles/scripts/setup_ssh_agent.sh - Sets up ssh-agent via keychain.
# If 'op' CLI and the askpass helper script are available, uses 1Password for passphrase.
# Intended to be sourced by .zshrc or similar.
_askpass_helper="$HOME/.ssh/askpass-1password.sh"
_askpass_vars_set=false
# Check if 'op' CLI is installed and the helper script is usable
if command -v op >/dev/null 2>&1 && [[ -f "$_askpass_helper" ]] && [[ -x "$_askpass_helper" ]]; then
# Configure environment for 1Password helper script
export SSH_ASKPASS="$_askpass_helper"
export SSH_ASKPASS_REQUIRE="prefer" # Use ASKPASS even in terminals
_askpass_vars_set=true
fi
# Execute keychain to start/find agent, load key, and set env vars
# (Adjust key name 'id_ed25519' as needed)
eval $(keychain --eval --quiet --agents ssh --inherit any-once id_ed25519)
# Clean up ASKPASS variables if they were set
if $_askpass_vars_set; then
unset SSH_ASKPASS
unset SSH_ASKPASS_REQUIRE
fi
Step 3: Source the Setup Script in .zshrc
Add this to your ~/.zshrc
(or equivalent):
# --- SSH Agent Configuration (via keychain & 1Password) ---
# Source the dedicated setup script if it exists.
_ssh_setup_script="${HOME}/dotfiles/scripts/setup_ssh_agent.sh"
if [[ -f "$_ssh_setup_script" ]]; then
source "$_ssh_setup_script"
fi
# --- End SSH Agent Configuration ---
How It Works:
- When you start a new shell session,
.zshrc
sourcessetup_ssh_agent.sh
. - The script checks if
op
is installed and theaskpass-1password.sh
helper is ready. - If yes, it sets the
SSH_ASKPASS
andSSH_ASKPASS_REQUIRE
environment variables. - It runs
keychain --eval id_ed25519
. keychain
starts or connects tossh-agent
and usesssh-add
to loadid_ed25519
.ssh-add
seesSSH_ASKPASS
is set and executesaskpass-1password.sh
.- The helper script runs
op read ...
. - The 1Password CLI handles authentication (prompting for your master password or using biometrics/system auth if necessary based on its current session state – typically only if the
op
session has expired). op read
outputs the passphrase.ssh-add
receives the passphrase and unlocks the key, adding it to the agent.keychain --eval
outputs the necessaryexport SSH_AUTH_SOCK=...
commands.eval
executes these commands, configuring your current shell to use the agent.- The
ASKPASS
variables are unset.
Conclusion:
After years of using Funtoo Keychain and 1Password separately, and a brief foray into the native 1Password agent, this combined approach hits the sweet spot for me.
It leverages 1Password’s secure vault for storing the SSH key passphrase but restores the “unlock once per session” convenience I appreciate from keychain
.
It requires a single passphrase entry via 1Password when the key is first added (typically on login/boot), after which the key remains available via the standard ssh-agent
mechanism without further 1Password interaction for that session.