Tips&Tricks Git with Custom URLs and Multiple SSH Keys
Problem
As a freelancer, you need to use different SSH keys for different clients when working with Git repositories on the same platform (e.g., Bitbucket, GitHub). You have multiple SSH host aliases configured in ~/.ssh/config, but Git remotes still use the default platform URL, causing the wrong key to be used.
Example Scenario
Your repository remote is configured as:
origin git@bitbucket.org:client1/project.git (fetch)
origin git@bitbucket.org:client1/project.git (push)
In your SSH configuration (~/.ssh/config), you have a custom host for this client:
Host bitbucketClient1
HostName bitbucket.org
User git
IdentityFile ~/.ssh/id_ed25519_client1
IdentitiesOnly yes
Git matches the remote URL against the SSH Host pattern. The remote uses git@bitbucket.org:client1/project.git, which matches the Host bitbucket.org block (if it exists) rather than your custom Host bitbucketClient1 block. This results in Git using the wrong SSH key.
Solution Options
Option 1: Global URL Rewriting (Recommended)
Configure Git to automatically rewrite all URLs matching a specific pattern to use your custom SSH host. This is the most convenient approach for managing multiple repositories for the same client.
# Rewrite all client1 Bitbucket URLs
git config --global url."git@bitbucketClient1:client1/".insteadOf "git@bitbucket.org:client1/"
How it works: The remote URL in git remote -v still displays as git@bitbucket.org:client1/project.git, but Git internally rewrites it to git@bitbucketClient1:client1/project.git when fetching or pushing. This means:
- All existing repositories continue to work without modification
- New clones can use the standard URL
- The correct SSH key is automatically selected
Verify the configuration:
# List all URL rewrites
git config --global --get-regexp url
# Output should include:
url.git@bitbucketclient1:client1/.insteadof git@bitbucket.org:client1/
Pros:
- Works across all existing and new repositories
- No need to modify individual repository configurations
- Maintains standard URL formatting in remotes
Cons: Slightly less obvious what’s happening under the hood.
Option 2: Per-Repository Remote URL Change
Manually change the remote URL to use your custom SSH host alias for existing repositories, or use the custom host directly when cloning new ones.
For existing repositories:
# In the repository
git remote set-url origin git@bitbucketClient1:client1/project.git
For new repositories:
git clone git@bitbucketClient1:client1/new-project.git
Verify the change:
git remote -v
# Should show: origin git@bitbucketClient1:client1/project.git
# Test SSH connection
ssh -T git@bitbucketClient1
Pros:
- Simple, explicit per-repository configuration
Cons:
- Must be done for each repository
- Has issues with submodules, as submodules typically use the original platform URL (e.g.,
git@bitbucket.org:client1/submodule.git) rather than the custom host, which can cause authentication problems unless each submodule remote is also manually updated
Setup Instructions for Ubuntu Linux
1. Create SSH Key for the Client
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_client1 -C "client1-work"
2. Add SSH Host Configuration
Edit ~/.ssh/config:
Host bitbucketClient1
HostName bitbucket.org
User git
IdentityFile ~/.ssh/id_ed25519_client1
IdentitiesOnly yes
3. Add Public Key to Client’s Account
Copy and add the public key to the client’s account on the platform:
cat ~/.ssh/id_ed25519_client1.pub
4. Apply Global URL Rewriting (Option 1)
git config --global url."git@bitbucketClient1:client1/".insteadOf "git@bitbucket.org:client1/"
For multiple clients, add similar entries:
# Client 2
git config --global url."git@bitbucketClient2:client2/".insteadOf "git@bitbucket.org:client2/"
# Client 3
git config --global url."git@bitbucketClient3:client3/".insteadOf "git@bitbucket.org:client3/"
5. Verify Everything Works
# Check SSH connection
ssh -T git@bitbucketClient1
# Check Git configuration
git config --global --get-regexp url
# In any existing repository, test fetching
cd ~/projects/client1/project
git fetch --dry-run
Important Notes
-
Don’t modify the default platform host: If you have a
Host bitbucket.orgentry in your SSH config, don’t change it to use a client-specific key. This would cause all Bitbucket repositories to use that key, defeating the purpose of separate client configurations. -
Pattern specificity: The
insteadOfpattern must match the repository URL prefix exactly. Usegit@bitbucket.org:client1/to match all repositories under that client’s namespace. -
Multiple platforms: The same approach works for GitHub, GitLab, or any other Git hosting service:
git config --global url."git@githubClient1:client1/".insteadOf "git@github.com:client1/" -
Existing repositories: After setting up URL rewriting, existing repositories work immediately without any changes to their remotes.
-
Security: Each client’s key should only be added to their respective accounts, not shared across clients.
Removing URL Rewrites
To remove a URL rewrite:
git config --global --unset url."git@bitbucketClient1:client1/".insteadOf
To remove all URL rewrites:
git config --global --remove-section url".*"
Summary
For freelancers managing multiple clients with separate SSH keys on the same Git hosting platform, Option 1 (global URL rewriting) is the recommended approach. It provides a clean, maintainable way to ensure the correct SSH key is used for each client’s repositories without modifying individual repository configurations.