Automatic SSH agent management and key loading for Windows (Git Bash), Linux, and macOS.
✅ Single SSH Agent - Only one ssh-agent runs regardless of how many terminal sessions you open
✅ Auto-Load Keys - Automatically loads all SSH private keys from ~/.ssh/
✅ Smart Agent Reuse - Detects and reuses existing agent across sessions
✅ Cross-Platform - Works on Windows (Git Bash), Linux (bash/zsh), and macOS (bash/zsh)
✅ macOS Keychain Integration - Optional integration with macOS Keychain for passphrase storage
Warning: The commands below append to your shell config. If you already have SSH agent management in your
.bashrc/.zshrc, review for conflicts before sourcing.
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.bashrc-windows-gitbash >> ~/.bashrc
source ~/.bashrcFor bash:
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.bashrc-linux >> ~/.bashrc
source ~/.bashrcFor zsh:
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.zshrc-linux >> ~/.zshrc
source ~/.zshrcFor zsh (default since macOS Catalina 10.15):
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.zshrc-macos >> ~/.zshrc
source ~/.zshrcFor bash:
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.bashrc-macos >> ~/.bashrc
source ~/.bashrc| File | Purpose |
|---|---|
.bashrc-windows-gitbash |
For Windows Git Bash |
.bashrc-linux |
For Linux systems (bash) |
.zshrc-linux |
For Linux systems (zsh) |
.bashrc-macos |
For macOS (bash) - includes Keychain integration |
.zshrc-macos |
For macOS (zsh) - recommended for macOS |
ssh-config-macos |
Optional SSH config for enhanced macOS Keychain integration |
-
SSH directory must exist and have correct permissions:
mkdir -p ~/.ssh chmod 700 ~/.ssh
-
Private keys should have secure permissions:
chmod 600 ~/.ssh/id_* chmod 600 ~/.ssh/*_rsa # Repeat for all your private keys
Important: These commands append to your existing config — they will not overwrite your current
.bashrcor.zshrc. If you prefer a clean install, back up your config first and use-oinstead of>>.
# For Windows Git Bash
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.bashrc-windows-gitbash >> ~/.bashrc
# For Linux (bash)
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.bashrc-linux >> ~/.bashrc
# For Linux (zsh)
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.zshrc-linux >> ~/.zshrc
# For macOS with zsh (recommended)
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.zshrc-macos >> ~/.zshrc
# For macOS with bash
curl -fsSL https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/.bashrc-macos >> ~/.bashrc# For bash
source ~/.bashrc
# For zsh
source ~/.zshrcOr simply restart your terminal.
For automatic passphrase storage in macOS Keychain:
# Back up existing SSH config (if any)
[ -f ~/.ssh/config ] && cp ~/.ssh/config ~/.ssh/config.bak
# Download the SSH config
curl -fsSL -o ~/.ssh/config https://raw.githubusercontent.com/ZlatanOmerovic/ssh-agent/master/ssh-config-macos
# Set correct permissions
chmod 600 ~/.ssh/configThis enables:
- Automatic passphrase storage in Keychain
- Keys persist across reboots
- No need to re-enter passphrases
The script automatically loads SSH keys from ~/.ssh/, excluding:
- Directories (including the
agent/directory) - Files ending in
.pub(public keys) - Files ending in
.ppk(PuTTY format keys) known_hostsand related filesconfigfilesauthorized_keysfiles- Log, backup, and text files (
.log,.bak,.old,.txt)
Any remaining file is attempted with ssh-add. If it is not a valid key, it is silently skipped.
- First terminal session: Starts a new ssh-agent and loads all keys
- Subsequent sessions: Detects existing agent and reuses it
- After reboot: Starts fresh agent and reloads keys
- No duplicates: Only one ssh-agent process runs at a time
- Crash recovery: Detects dead/unresponsive agents and restarts automatically
- Corruption resistant: Handles corrupted or empty environment files gracefully
The macOS versions include automatic detection and use of the --apple-use-keychain flag:
- macOS 12.0+: Uses
--apple-use-keychainflag - Older macOS: Falls back to standard
ssh-add - Stores passphrases securely in macOS Keychain
- Works with both bash and zsh versions
After installation, open a new terminal. You should see:
Starting new SSH agent...
Added: id_ed25519
Added: id_rsa
Open another terminal window - it should connect silently (agent already running).
To manually check loaded keys:
ssh-add -lUncomment these lines at the bottom of your .bashrc or .zshrc:
echo "Loaded SSH keys:"
ssh-add -lAdd patterns to the skip conditions in the load_ssh_keys function:
# Add to the existing case statement
case "$(basename "$key")" in
known_hosts*|environment*|config*|authorized_keys*|*.log|*.bak|*.old|*.txt|my_special_key) continue ;;
esacDuplicate the for loop and change the path:
for key in ~/my-other-keys/*; do
# ... same logic
doneCheck file permissions:
ls -la ~/.ssh/Private keys should be -rw------- (600).
Verify keys are valid:
ssh-keygen -y -f ~/.ssh/your_keyCheck for passphrase issues: If your keys have passphrases, you'll be prompted to enter them. On macOS, enable Keychain integration to store passphrases.
Kill all ssh-agent processes:
# Linux/macOS
pkill ssh-agent
# Windows Git Bash
taskkill /F /IM ssh-agent.exeRemove environment file:
rm ~/.ssh/agent/environmentRestart terminal.
Ensure SSH config has correct permissions:
chmod 600 ~/.ssh/configManually add keys to Keychain:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519Verify Keychain integration:
ssh-add -lCheck your default shell:
echo $SHELL- If
/bin/zsh: Use.zshrc-macos - If
/bin/bash: Use.bashrc-macos
Change default shell to zsh (recommended):
chsh -s /bin/zsh- ✅ Windows 10/11 with Git Bash
- ✅ Linux (all distributions with bash/zsh)
- ✅ macOS 10.15 Catalina and later
- ✅ bash (all platforms)
- ✅ zsh (macOS, Linux)
⚠️ Other shells: May work but not tested
- ✅ OpenSSH 7.0+
- ✅ OpenSSH 8.0+ (recommended for macOS Keychain support)
The project includes a full test suite that runs safely inside Docker — it will never touch your host machine's SSH config, keys, or agent.
- Docker installed and running
./test/run-tests.sh# Bash configs only (.bashrc-linux, .bashrc-macos, .bashrc-windows-gitbash)
./test/run-tests.sh bash
# Zsh configs only (.zshrc-linux, .zshrc-macos)
./test/run-tests.sh zshThe test suite runs 11 tests per config across all 5 shell config variants (85 tests total):
| Test | Description |
|---|---|
| 1 | Start agent with no keys in ~/.ssh/ |
| 2 | Start agent and load multiple keys (ed25519 + RSA) |
| 3 | Reuse existing agent across sessions (same PID, keys preserved) |
| 4 | Recover from agent crash (killed process, stale env file) |
| 5 | Handle corrupted environment file (no shell errors leaked) |
| 6 | Handle empty environment file |
| 7 | Detect stale PID after reboot (PID reused by another process) |
| 8 | Handle non-numeric PID in environment file |
| 9 | Reload keys after ssh-add -D (agent running but empty) |
| 10 | Skip non-key files (known_hosts, authorized_keys, .txt, .log, .bak) |
| 11 | No duplicate ssh-agent processes after repeated sourcing |
╔══════════════════════════════════════════════════════════════╗
║ FINAL SUMMARY
╠══════════════════════════════════════════════════════════════╣
║ Suites passed: 5
║ Suites failed: 0
╚══════════════════════════════════════════════════════════════╝
- Agent environment file is stored with 600 permissions (owner read/write only)
- Private keys should always be 600 permissions
- Public keys can be 644 permissions
- On macOS, Keychain provides encrypted storage for passphrases
- Never commit private keys to version control
Contributions are welcome! Please feel free to submit a Pull Request.
When reporting issues, please include:
- Operating system and version
- Shell type and version (
bash --versionorzsh --version) - SSH version (
ssh -V) - Contents of
~/.ssh/(filenames only, no keys!) - Error messages
MIT License - Feel free to use and modify as needed.
Inspired by the need for consistent SSH agent management across multiple platforms and terminal sessions.
Star this repo if you find it useful! ⭐
