Making Git SSH Commands Permanent: Best Practices for Repository-Specific SSH Keys
The Problem
Have you ever found yourself typing this long command every time you want to pull from a specific repository?
GIT_SSH_COMMAND='ssh -o IdentitiesOnly=yes -i /root/.ssh/repo' git pull
It's tedious, error-prone, and breaks your workflow. Let's fix that permanently.
Quick Solution: Repository-Specific Git Config
The cleanest solution is to use Git's built-in core.sshCommand setting at the repository level:
git config --local core.sshCommand "ssh -o IdentitiesOnly=yes -i /root/.ssh/repo"
After this one-time setup, you can simply run:
git pull
git push
git fetch
# All Git operations will use your custom SSH command
Alternative Approaches
Option 1: Global Git Config (For All Repositories)
git config --global core.sshCommand "ssh -o IdentitiesOnly=yes -i /root/.ssh/repo"
⚠️ Caution: This applies to every Git operation on your system.
Option 2: Shell Alias
Add to ~/.bashrc, ~/.zshrc, or ~/.bash_aliases:
alias gmirror='GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i /root/.ssh/repo" git'
Usage: gmirror pull
Option 3: Environment Management with direnv
Create .envrc in your repository:
export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i /root/.ssh/repo"
Then run direnv allow. The variable activates when you enter the directory.
Option 4: SSH Config File (Most Elegant for Multiple Keys)
Edit ~/.ssh/config:
# Specific host with custom key
Host github-repo
HostName github.com
User git
IdentityFile /root/.ssh/repo
IdentitiesOnly yes
# Or match by repository pattern
Match host github.com exec "[[ $PWD =~ /path/to/your/repo ]]"
IdentityFile /root/.ssh/repo
IdentitiesOnly yes
Then change your remote URL:
git remote set-url origin git@github-repo:username/repo.git
Best Practices for Managing Multiple SSH Keys
1. Use SSH Config for Complex Setups
The SSH config file is the most maintainable solution when juggling multiple keys:
# Personal GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_personal
IdentitiesOnly yes
# Work GitHub
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_work
IdentitiesOnly yes
# GitLab (different host)
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_rsa_gitlab
IdentitiesOnly yes
# Legacy server with non-standard port
Host old-git-server
HostName git.legacy.com
Port 2222
User git
IdentityFile ~/.ssh/id_rsa_legacy
2. Directory-Based SSH Config with Match
Use the Match directive for automatic key selection:
# Auto-select key based on current directory
Match host github.com exec "[[ $PWD =~ /work/ ]]"
IdentityFile ~/.ssh/id_rsa_work
IdentitiesOnly yes
Match host github.com exec "[[ $PWD =~ /personal/ ]]"
IdentityFile ~/.ssh/id_rsa_personal
IdentitiesOnly yes
# Default fallback
Match host github.com
IdentityFile ~/.ssh/id_rsa_default
3. Verify Your Configuration
# Test which SSH key will be used
ssh -T git@github.com -v
# Check Git's effective SSH command
git config core.sshCommand
# List all Git configurations
git config --list --show-origin
# Test SSH connection with specific key
ssh -T -i /root/.ssh/repo git@github.com
4. Security Best Practices
Key Permissions
# Set correct permissions for SSH keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa*
chmod 644 ~/.ssh/*.pub
chmod 600 ~/.ssh/config
Use SSH Agent for Passphrase-Protected Keys
# Start SSH agent
eval "$(ssh-agent -s)"
# Add keys to agent (enter passphrase once per session)
ssh-add ~/.ssh/id_rsa_personal
ssh-add ~/.ssh/id_rsa_work
# List loaded keys
ssh-add -l
# Use agent in Git
git config --local core.sshCommand "ssh -o IdentitiesOnly=yes -o ForwardAgent=no"
Regular Key Rotation
# Generate new key with stronger encryption
ssh-keygen -t ed25519 -a 100 -C "your_email@example.com"
# Or RSA with 4096 bits
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
5. Troubleshooting Common Issues
Problem: "Permission denied (publickey)"
# Check if key is added to SSH agent
ssh-add -l
# Test connection with verbose output
ssh -Tv git@github.com
# Verify key is added to GitHub/GitLab
cat ~/.ssh/id_rsa.pub
Problem: Wrong key being used despite configuration
# Ensure IdentitiesOnly is set to prevent SSH from trying other keys
git config --local core.sshCommand "ssh -o IdentitiesOnly=yes -i /path/to/key"
# Check all matching keys
ssh -T git@github.com -v 2>&1 | grep "Offering"
Problem: SSH config not being respected
# Test SSH config parsing
ssh -F /dev/null -G github.com
# Debug SSH config loading
ssh -T git@github.com -F ~/.ssh/config -v
6. Team Collaboration Tips
When working in a team with shared repositories:
# Add to .gitconfig (user-specific, not committed)
git config --local core.sshCommand "ssh -i ~/.ssh/team-key"
# Or use includeIf for conditional includes
git config --global includeIf.gitdir:~/work/.path "~/work/.gitconfig"
Create a README.md section for your team:
## SSH Setup for This Repository
This repository requires a specific SSH key. Set it up with:
```bash
git config --local core.sshCommand "ssh -i ~/.ssh/our-team-key -o IdentitiesOnly=yes"
Or add to your ~/.ssh/config:
Host github.com
IdentityFile ~/.ssh/our-team-key
IdentitiesOnly yes
### 7. **Automation Script**
Save this as `setup-git-ssh.sh`:
```bash
#!/bin/bash
# Script to automate Git SSH configuration for a repository
REPO_PATH="${1:-.}"
SSH_KEY="${2}"
if [ -z "$SSH_KEY" ]; then
echo "Usage: $0 <repository-path> <ssh-key-path>"
echo "Example: $0 . ~/.ssh/repo"
exit 1
fi
if [ ! -f "$SSH_KEY" ]; then
echo "Error: SSH key not found at $SSH_KEY"
exit 1
fi
cd "$REPO_PATH" || exit 1
if [ ! -d ".git" ]; then
echo "Error: Not a git repository"
exit 1
fi
# Set the SSH command
git config --local core.sshCommand "ssh -o IdentitiesOnly=yes -i $SSH_KEY"
# Verify
echo "✅ SSH command configured:"
git config --local core.sshCommand
# Test connection
echo "🔍 Testing connection..."
ssh -T -o IdentitiesOnly=yes -i "$SSH_KEY" git@github.com 2>&1 | grep -q "successfully authenticated" && \
echo "✅ Authentication successful" || \
echo "⚠️ Please verify your SSH key is added to your Git provider"
Conclusion
While the quick fix of setting core.sshCommand locally works great for single repositories, implementing proper SSH config management is crucial as your projects grow. The SSH config file approach offers:
- Centralized management of all SSH keys
- Automatic key selection based on host or directory
- Consistent behavior across Git and other SSH commands
- Better security with per-key options
Start with the repository-specific config for quick wins, then evolve to SSH config files as your key collection grows.
Quick Reference Card
# Single repo setup
git config --local core.sshCommand "ssh -i ~/.ssh/specific-key -o IdentitiesOnly=yes"
# Check current config
git config --local core.sshCommand
# Remove config
git config --local --unset core.sshCommand
# SSH config example
echo 'Host github.com
IdentityFile ~/.ssh/specific-key
IdentitiesOnly yes' >> ~/.ssh/config
Remember: The best solution depends on your workflow. For one-off repositories, use git config --local. For power users managing dozens of keys, invest time in ~/.ssh/config.
This blog post covers:
- The main solution with Git config
- Four alternative approaches
- Security best practices
- SSH config file patterns
- Troubleshooting guide
- Team collaboration tips
- An automation script
- Quick reference card