SSH Keys vs The Alternatives

HTTPS authentication with tokens breaks when tokens expire. Switching Git configs manually means you'll eventually commit your side project to the company repo at 2am.

SSH Authentication

Git Configuration

SSH keys work because each one is tied to exactly one account. GitHub knows which SSH key belongs to which account - no shared credentials, no expiring tokens.

Why This Actually Matters

Personal commits in work repositories trigger security audits. That's how I learned our InfoSec team has way too much time on their hands and will absolutely call you at 9pm about that side project commit. Git's global config doesn't give a shit which remote you're pushing to - it uses whatever user.email you have set globally, even if it's your "420blazeit@gmail.com" address.

SSH keys with host aliases fix this. git push to git@github-work:company/repo.git uses the work key. Push to git@github-personal:username/repo.git uses the personal key. Different keys = different accounts = different identities.

SSH authentication isn't just password replacement - it's identity isolation. Each key links to one account, preventing wrong-identity commits.

The Options That Don't Work

Git credential helpers: Store passwords and tokens that expire every 90 days and break your CI pipeline at 3am on a Friday. Tied to URLs, not identities, so you'll still commit your OnlyFans bot to the company repo.

Git conditional includes: Directory-based switching works until you clone that urgent hotfix to your Desktop instead of your ~/work folder because you're panicking. SSH doesn't give a shit where your repo lives on disk.

Separate machines: VMs consume half your RAM, Docker containers for SSH are engineering masturbation, GitHub Codespaces cost $18/month per workspace. SSH keys on one machine cost zero dollars and actually work.

The Configuration That Actually Works

Your SSH config file (~/.ssh/config) becomes a routing table. Here's mine:

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Host github-personal
    HostName github.com  
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

git clone git@github-work:company/repo.git uses the work key. git clone git@github-personal:user/repo.git uses the personal key. `IdentitiesOnly yes` is critical - without it, SSH tries all your keys and GitHub rate-limits you with "too many authentication failures."

This pattern works across GitHub, GitLab, Bitbucket, and whatever Git server your company runs. Stack Overflow has more details if you need them.

Setup takes an hour the first time, 4 hours if you're me and keep forgetting that SSH config syntax is a pedantic asshole about indentation. After that it just works - no password prompts, no "why is my NSFW bot commit in the enterprise repo" Slack messages, no authentication failures when you're trying to push a hotfix at 3am and production is literally on fire.

SSH Account Management: What Actually Works

Method

Reality Check

When It Breaks

Time Investment

Sanity Cost

Manual Git Config Switching

Works until you forget

Every damn time

30 seconds per switch

High

  • you'll mess up

SSH Keys + Host Aliases

Actually reliable

SSH agent crashes

1 hour setup

Low

  • set and forget

Git Credential Manager

Platform dependent

Token expires

2 hours debugging

Medium

  • Windows quirks

Multiple User Configs

Directory dependent

Wrong directory

Forever tweaking

Very High

  • constant vigilance

SSH Setup Step-by-Step

This configuration avoids the common SSH pitfalls that cause authentication failures and wrong-identity commits.

SSH Key Generation

SSH Config Setup

Step 1: Generate Keys (And Avoid the Footgun)

ED25519 keys are faster and GitHub recommends them. All major platforms support ED25519 as of 2025. RSA keys still work but GitHub disabled RSA SHA-1 signatures in March 2022.

## Work account key - put it in a file you'll remember
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C \"work@company.com\"

## Personal account key
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_personal -C \"personal@gmail.com\"

## Client key (if you're freelancing)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_client -C \"freelance@client.com\"

Passphrase decision: SSH key passphrases add security but require typing every time the SSH agent dies (which happens every fucking Tuesday on Linux). For personal machines, skip them. For work laptops, use them because IT security will audit your shit. macOS Keychain integration breaks on every OS update - Monterey 12.3 completely fucked it, and Ventura 13.0 wasn't much better.

Step 2: Write the SSH Config That Doesn't Suck

Create or edit `~/.ssh/config`. This file might not exist yet - that's fine, just create it. Pay attention to the spacing - SSH config is picky about tabs vs spaces.

## Work GitHub - use this for company repos
Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes
    AddKeysToAgent yes

## Personal GitHub - use this for your side projects
Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes
    AddKeysToAgent yes

## If you use GitLab for work too
Host gitlab-work
    HostName gitlab.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes
    AddKeysToAgent yes

The magic is in the details:

SSH config gotchas that will ruin your entire fucking day:

Step 3: Copy Your Public Keys Like a Human

Copy the public key contents to your clipboard and paste them into each Git service:

## Copy work key to clipboard (macOS)
pbcopy < ~/.ssh/id_ed25519_work.pub

## Linux version  
xclip -selection clipboard < ~/.ssh/id_ed25519_work.pub

## Windows (Git Bash)
clip < ~/.ssh/id_ed25519_work.pub

## Or just display it and copy manually
cat ~/.ssh/id_ed25519_work.pub

Where to paste them:

  • GitHub: GitHub.com → Settings → SSH and GPG keys → New SSH key
  • GitLab: User Settings → SSH Keys → Add new key
  • Bitbucket: Personal settings → SSH keys → Add key

Title the keys something useful like "MacBook Pro Work" or "Personal Laptop" so you remember which machine they're from when you need to rotate them.

Step 4: Fix Your Repository URLs

Change your existing repositories to use the SSH host aliases. If you're still using HTTPS URLs (the https://github.com/... ones), this is why Git keeps asking for passwords.

## Check what you have now
git remote -v

## Fix work repositories to use work SSH alias
git remote set-url origin git@github-work:company/repo.git

## Fix personal repositories to use personal alias  
git remote set-url origin git@github-personal:username/repo.git

Pro tip: For new clones, copy the SSH URL from GitHub but modify the hostname:

  • GitHub gives you: git@github.com:user/repo.git
  • You want: git@github-work:user/repo.git or git@github-personal:user/repo.git

Step 5: Test It Before You Trust It

This is the step everyone skips and then wonders why nothing works:

## Test work connection - should show your work username
ssh -T git@github-work

## Test personal connection - should show your personal username
ssh -T git@github-personal

If you get "Permission denied (publickey)": This error message is about as helpful as a chocolate teapot. Run ssh -vT git@github-work to see what SSH is actually trying and why it's failing spectacularly.

If it shows the wrong username: Congratulations, you just uploaded your personal key to your work account. We've all done this. Delete the key from the wrong account and upload it to the right one.

Step 6: Stop Fucking Up New Repository Clones

When you clone new repositories, use your SSH aliases instead of the default URLs:

## For work projects
git clone git@github-work:company/new-repo.git

## For personal projects  
git clone git@github-personal:username/side-project.git

The gotcha: GitHub's clone button gives you git@github.com:... - you need to change the hostname to your alias.

The Missing Piece: Git User Configuration

SSH handles authentication, but Git still needs to know your name and email for commits. Either set these per repository:

## In each work repository
git config user.email \"professional@company.com\"
git config user.name \"Professional Name\"

## In each personal repository
git config user.email \"personal@gmail.com\"  
git config user.name \"Real Name\"

Or use Git conditional includes to automatically switch based on directory paths. But honestly, per-repo config is more reliable because you won't clone that emergency hotfix to the wrong folder at 2am when production is down.

When This Inevitably Breaks

Because SSH is SSH, here are the nuclear options for when nothing works:

SSH Agent Resurrection

If SSH stops working entirely, the agent probably died:

## Kill and restart ssh-agent
killall ssh-agent
eval \"$(ssh-agent -s)\"

## Re-add your keys
ssh-add ~/.ssh/id_ed25519_work
ssh-add ~/.ssh/id_ed25519_personal

## Check what's loaded
ssh-add -l

Connection Reuse (Performance Hack)

If SSH connections are slow, enable connection multiplexing:

## Add to ~/.ssh/config for faster connections
Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 5m

You need to create the sockets directory first: mkdir -p ~/.ssh/sockets

Corporate Firewall Bypass

If your company blocks SSH (port 22), GitHub supports SSH over HTTPS:

## Add this to your work SSH config
Host github-work
    HostName ssh.github.com
    Port 443
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

This tunnels SSH through port 443, which corporate firewalls usually allow.

That's it. This setup works across macOS, Linux, and Windows (with Git Bash). It scales from 2 accounts to 20 accounts. Once it's working, you can forget about Git authentication entirely and focus on actually writing code.

That's the complete setup process. Once configured, this system handles multiple Git accounts automatically.

SSH Debugging: When Everything Goes to Shit

Q

"Permission denied (publickey)" - SSH's Way of Saying "Something's Fucked But I Won't Tell You What"

A

This error message is SSH's way of being a useless piece of shit. It's like getting "Error: Error" - technically correct but tells you absolutely nothing. Here's how to actually debug it:

## Run SSH in verbose mode to see what's happening
ssh -vT git@github-work

Look for lines like "Offering public key" to see which keys SSH is trying. If you don't see your key being offered:

  1. SSH config path is wrong: Double-check the IdentityFile path in your config - you probably have a typo like id_es25519 instead of id_ed25519
  2. File permissions are fucked: Run chmod 600 ~/.ssh/id_ed25519_work - SSH is paranoid about who can read your keys
  3. SSH config syntax error: One wrong tab instead of spaces breaks everything because SSH config parser was designed by pedantic assholes
  4. Wrong key uploaded: You uploaded your personal "cumslut69" key to your work account during that late-night debugging session (we've all done this)
Q

"Git is still asking for my password, what the hell?"

A

You're probably still using HTTPS URLs like a caveman. Check what you actually have:

git remote -v

If you see https://github.com/... that's your problem. Fix it:

git remote set-url origin git@github-work:username/repo.git

The 3am debugging version: You set up SSH perfectly but forgot to change the remote URL on your existing repositories. SSH only works with git@hostname:... URLs, not https://... URLs.

Q

"SSH works from terminal but VS Code still asks for passwords"

A

IDEs are special snowflakes with their own Git integration. Here's the fix:

  • VS Code: Install GitLens extension, make sure it's using system Git not bundled Git
  • IntelliJ: File → Settings → Version Control → Git → Use credential helper
  • Terminal Git always works: If your IDE is being difficult, just git push from terminal

The real solution is telling your IDE to use the system Git binary that already has SSH configured, not whatever bundled version it ships with.

Q

"SSH test works but `git push` fails with weird errors"

A

SSH authentication passed but Git is confused about your identity:

## Check what Git thinks your identity is
git config user.email
git config user.name

## Set it correctly for this repository
git config user.email "correct@email.com"
git config user.name "Correct Name"

Common scenario: SSH connects with your work key, but Git commits with your personal email. This confuses GitHub's contribution tracking and sometimes triggers security policies.

Q

"Can I use the same SSH key everywhere?"

A

Same key on different platforms: Yes - one key works for GitHub, GitLab, and Bitbucket simultaneously.

Same key on same platform, different accounts: No fucking way. GitHub will tell you "Key is already in use" because they're not idiots. Each account needs its own unique key.

Trying to share keys anyway: Don't. Just generate more keys. ED25519 keys are tiny and SSH doesn't care if you have 10 of them.

Q

"Everything was working yesterday, now nothing works"

A

SSH agent probably died or your network changed. Debugging checklist:

  1. SSH agent died: eval $(ssh-agent -s) then ssh-add ~/.ssh/id_ed25519_work
  2. macOS keychain locked: Restart your computer (seriously, this fixes it) - common on macOS 14+ Sonoma/Sequoia
  3. VPN broke your shit: Corporate VPNs love to fuck with SSH routing - Cisco AnyConnect and Zscaler are particularly notorious for this in 2025
  4. GitHub rotated their host keys: Very rare, but ssh-keygen -R github.com clears the cache (last happened March 2023 and broke half the internet)
  5. You switched WiFi networks: If you're using a firewall bypass, Starbucks WiFi != office WiFi in terms of routing rules
  6. OpenSSH 9.0+ compatibility clusterfuck: OpenSSH 9.0 tightened security defaults and broke configs that worked fine for years - thanks for nothing, OpenBSD team
Q

"I need to rotate my SSH keys but I don't want to break everything"

A

Smart thinking. Here's the safe way:

  1. Generate new key with different filename: ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work_new
  2. Add new public key to GitHub (don't remove old one yet)
  3. Update SSH config to point to new key
  4. Test it: ssh -T git@github-work
  5. Remove old public key from GitHub only after new one works

Your existing repositories keep working because you didn't change the SSH host alias.

Q

"SSH config changes aren't doing shit"

A

SSH config is picky about syntax and permissions:

## Fix permissions (SSH ignores world-readable configs)
chmod 600 ~/.ssh/config

## Test SSH config syntax
ssh -F ~/.ssh/config -T git@github-work

## Nuclear option: restart SSH entirely
killall ssh-agent && eval $(ssh-agent -s)

Gotcha: SSH caches connections. If you change the config, run ssh -O exit git@github-work to force a fresh connection.

Q

"Corporate firewall blocks SSH port 22, now what?"

A

GitHub supports SSH over port 443 (HTTPS port that firewalls allow):

Host github-work
    HostName ssh.github.com
    Port 443
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

GitHub's SSH over HTTPS guide has the full details. Most corporate firewalls can't block port 443 without breaking half the internet.

Q

"I lost my SSH private key and everything is fucked"

A

Don't panic. Here's the recovery plan:

  1. Generate new SSH key immediately: ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work_new
  2. Remove old public key from GitHub (so nobody can use the lost private key)
  3. Add new public key to GitHub
  4. Update SSH config to point to new key file
  5. Test: ssh -T git@github-work

Your repositories are fine. SSH keys are just authentication - they don't affect your Git history or repository data.

Prevention: Backup ~/.ssh/ to your password manager or encrypted cloud storage. Don't store private keys in Dropbox or Google Drive unencrypted - that's how you end up on HaveIBeenPwned explaining to your boss why company infrastructure got compromised via your personal cloud storage.

SSH troubleshooting covers the most common failure modes. Security practices prevent key compromise and access control issues.

SSH Security Best Practices

SSH keys are more secure than passwords, but they require proper management. Key compromise can lead to supply chain attacks and repository breaches.

SSH Security

SSH Security Protocol

Key Management Basics

One key per account, period: Don't reuse SSH keys across accounts on the same platform. GitHub blocks this with "Key is already in use" errors because they're not fucking idiots. GitLab and Bitbucket might let you do stupid things, but that doesn't mean you should.

Rotate keys like you rotate passwords: Every 6-12 months, or immediately when you leave a job. Enterprise policies often require quarterly rotation, which is annoying but reasonable. As of 2025, SOC 2 Type II compliance typically mandates 90-day SSH key rotation for production access.

File permissions matter: SSH is paranoid about file permissions and will ignore your keys if they're world-readable:

## Fix SSH key permissions (run this now)
chmod 600 ~/.ssh/id_ed25519_*       # Private keys: owner-only access
chmod 644 ~/.ssh/id_ed25519_*.pub   # Public keys: world-readable
chmod 600 ~/.ssh/config            # SSH config: owner-only access

Don't put private keys in cloud storage: Unencrypted SSH keys in cloud storage create security vulnerabilities. Use password managers or encrypted storage if you need backups.

SSH Agent: Convenience vs Security

Agent forwarding is risky: SSH agent forwarding exposes your local SSH keys to remote servers. If that server gets compromised, your keys are compromised too:

## Disable agent forwarding by default
Host *
    ForwardAgent no

Time-limited key loading: Don't leave SSH keys loaded in your agent forever:

## Load key with 1-hour timeout
ssh-add -t 3600 ~/.ssh/id_ed25519_work

## Check what's currently loaded
ssh-add -l

## Nuclear option: clear all keys
ssh-add -D

Production key protection: For high-value keys (production access, client work), enable confirmation prompts:

ssh-add -c ~/.ssh/id_ed25519_production
## Now SSH asks "use this key?" before each connection

Corporate Network Bullshit

Firewall bypass: Some companies block SSH port 22 because their security team read a blog post in 2010. GitHub supports SSH over port 443:

Host github-work
    HostName ssh.github.com
    Port 443
    User git
    IdentityFile ~/.ssh/id_ed25519_work

Port 443 is HTTPS, so corporate firewalls can't block it without breaking the entire internet.

VPN interference: Corporate VPNs sometimes break SSH routing. If SSH works at home but not at the office, the VPN is probably doing "deep packet inspection" or routing SSH through a proxy. Try the port 443 workaround above.

When You Leave Your Job

Key cleanup checklist: Don't be the person who still has access to their old company's repositories:

  1. Remove work SSH public key from personal GitHub (if you added it there)
  2. Delete work SSH private key from your machine: rm ~/.ssh/id_ed25519_work*
  3. Clean up SSH config: Remove or comment out work host aliases
  4. Clear SSH agent: ssh-add -D to remove loaded keys
  5. Check repository access: Make sure you can't still push to company repos

The 2am security call from hell: My buddy got a panicked call at 2am because commits were still hitting production with his SSH key 6 months after he left the company. He had to explain to very angry security people why his personal porn scraper was somehow connected to their CI/CD pipeline. Don't be that person.

If Your SSH Key Gets Compromised

Immediate damage control:

  1. Remove public key from all Git services immediately
  2. Generate new SSH key pair: ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work_new
  3. Add new public key to services
  4. Update SSH config: Point to new key file
  5. Notify your team if it's a work key

How keys get compromised (real stories from the trenches):

  • Malware scanning your ~/.ssh/ directory while you're mining crypto on company hardware
  • Accidentally committing private keys to repositories (happened to my last company, exposed 200+ production servers)
  • Laptop theft from coffee shops - especially unencrypted drives
  • iCloud/Google Drive syncing your .ssh folder because you enabled "sync everything" like an idiot
  • Screen sharing during code reviews with your SSH config file open showing all your key paths
  • Docker container escape exposing host filesystem SSH keys (seen this twice in production)

Backup Strategy That Doesn't Suck

What to backup: Your SSH public keys and SSH config file. Private keys should never leave your machine unless encrypted.

How to backup: Most password managers can store SSH public keys and config files as secure notes. 1Password has SSH agent integration that's actually decent.

Don't backup: Private keys to cloud storage. Ever. If you need private key backup, use encrypted disk images or encrypted cloud storage that you control the keys for.

The bottom line: SSH keys are way more secure than passwords, but they're not fucking magic. Follow basic security hygiene and you'll be fine. Ignore security entirely and you'll be explaining to InfoSec at 3am why your furry roleplay bot's SSH key somehow had access to the customer database and why there are commits with the message "UwU fixed the payment processor OwO" in production code.

SSH security practices protect your keys and prevent unauthorized access. Professional-grade Git operations require proper key management and access controls.

Essential Resources for SSH Git Multiple Accounts

Related Tools & Recommendations

pricing
Similar content

Enterprise Git Hosting: GitHub, GitLab & Bitbucket Cost Analysis

When your boss ruins everything by asking for "enterprise features"

GitHub Enterprise
/pricing/github-enterprise-bitbucket-gitlab/enterprise-deployment-cost-analysis
100%
tool
Recommended

GitHub Copilot - AI Pair Programming That Actually Works

Stop copy-pasting from ChatGPT like a caveman - this thing lives inside your editor

GitHub Copilot
/tool/github-copilot/overview
73%
howto
Similar content

Undo Git Commits: Keep Changes & Fix Mistakes Safely

Committed too early and now you're fucked? Here's how to unfuck yourself without losing two weeks of work

Git
/howto/undo-git-commit-keep-changes/complete-undo-guide
65%
pricing
Similar content

GitHub Enterprise vs GitLab Ultimate - Total Cost Analysis 2025

The 2025 pricing reality that changed everything - complete breakdown and real costs

GitHub Enterprise
/pricing/github-enterprise-vs-gitlab-cost-comparison/total-cost-analysis
56%
integration
Recommended

Jenkins + Docker + Kubernetes: How to Deploy Without Breaking Production (Usually)

The Real Guide to CI/CD That Actually Works

Jenkins
/integration/jenkins-docker-kubernetes/enterprise-ci-cd-pipeline
55%
compare
Recommended

I Tested 4 AI Coding Tools So You Don't Have To

Here's what actually works and what broke my workflow

Cursor
/compare/cursor/github-copilot/claude-code/windsurf/codeium/comprehensive-ai-coding-assistant-comparison
47%
alternatives
Recommended

GitHub Copilot Alternatives - Stop Getting Screwed by Microsoft

Copilot's gotten expensive as hell and slow as shit. Here's what actually works better.

GitHub Copilot
/alternatives/github-copilot/enterprise-migration
47%
tool
Recommended

GitLab CI/CD - The Platform That Does Everything (Usually)

CI/CD, security scanning, and project management in one place - when it works, it's great

GitLab CI/CD
/tool/gitlab-ci-cd/overview
38%
tool
Recommended

Azure DevOps Services - Microsoft's Answer to GitHub

competes with Azure DevOps Services

Azure DevOps Services
/tool/azure-devops-services/overview
37%
troubleshoot
Recommended

Docker Won't Start on Windows 11? Here's How to Fix That Garbage

Stop the whale logo from spinning forever and actually get Docker working

Docker Desktop
/troubleshoot/docker-daemon-not-running-windows-11/daemon-startup-issues
35%
howto
Recommended

Stop Docker from Killing Your Containers at Random (Exit Code 137 Is Not Your Friend)

Three weeks into a project and Docker Desktop suddenly decides your container needs 16GB of RAM to run a basic Node.js app

Docker Desktop
/howto/setup-docker-development-environment/complete-development-setup
35%
news
Recommended

Docker Desktop's Stupidly Simple Container Escape Just Owned Everyone

integrates with Technology News Aggregation

Technology News Aggregation
/news/2025-08-26/docker-cve-security
35%
tool
Recommended

Jenkins - The CI/CD Server That Won't Die

integrates with Jenkins

Jenkins
/tool/jenkins/overview
34%
tool
Recommended

Jenkins Production Deployment - From Dev to Bulletproof

integrates with Jenkins

Jenkins
/tool/jenkins/production-deployment
34%
howto
Similar content

How to Set Up SSH Keys for Git & GitHub: A Complete Guide

Tired of typing your GitHub password every fucking time you push code?

Git
/howto/setup-git-ssh-keys-github/complete-ssh-setup-guide
33%
howto
Similar content

Git: How to Merge Specific Files from Another Branch

November 15th, 2023, 11:47 PM: Production is fucked. You need the bug fix from the feature branch. You do NOT need the 47 experimental commits that Jim pushed a

Git
/howto/merge-git-branch-specific-files/selective-file-merge-guide
32%
troubleshoot
Similar content

Fix Git 'Your Local Changes Would Be Overwritten' Error

The Git error that's fucked more developers than missing semicolons - 5 battle-tested solutions that actually work

Git
/troubleshoot/git-local-changes-overwritten/common-solutions
30%
troubleshoot
Similar content

Git Fatal Not a Git Repository - Fix It in Under 5 Minutes

When Git decides to fuck your deployment at 2am

Git
/troubleshoot/git-fatal-not-a-git-repository/common-errors-solutions
29%
troubleshoot
Similar content

Fix Git Checkout Failures: Local Changes Overwritten Error

When Git checkout blocks your workflow because uncommitted changes are in the way - battle-tested solutions for urgent branch switching

Git
/troubleshoot/git-local-changes-overwritten/branch-switching-checkout-failures
28%
troubleshoot
Similar content

Fix Git 'Failed to Push Some Refs' Error: Ultimate Guide

The definitive fix guide for the error that's destroyed more deployments than any other Git message

Git
/troubleshoot/git-failed-push-some-refs/push-rejection-solutions
28%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization