Mac 上通过 SSH 管理多个 GitHub 账户 — 工作与个人密钥分离
通过 ~/.ssh/config 干净分离多个主机/账户(工作 GitHub、个人 GitHub、外部客户)的直接方法。
在同一台机器上同时使用工作 GitHub 账户和个人 GitHub 账户,第一天就会出问题 — git push 推到了错误账户,刚克隆的仓库因权限拒绝而失败,gh CLI 始终登录同一个账户。本指南是在 macOS 14+ / OpenSSH 9.x 上通过 ~/.ssh/config 分离账户/主机的直接方法。
我认为多账户 SSH 配置的核心不是技术难度,而是一次性把 ~/.ssh/config 设置正确的纪律。以前开发者靠手动切换账户;如今通过主机别名和 includeIf 自动切换,由于那个自动化,工作账户和个人账户的混淆从根本上被消除了。
是 Mac 初始配置 的后续篇,那里你创建了第一个 ed25519 密钥。同样适用于外部客户的 GitLab/Bitbucket。
TL;DR
- 为每个账户创建独立 SSH 密钥(ed25519),使用不同的文件名
- 在
~/.ssh/config中为每个主机显式设置IdentityFile+Host别名 - 在克隆 URL 中使用别名:
git@github-work:user/repo.git而不是git@github.com:... - 通过
.gitconfig的includeIf按工作目录自动分支user.email ghCLI 1.x+ 支持同时使用多个账户
前提条件
- macOS 14+,OpenSSH 9.x(
ssh -V确认) - 每个身份对应一个 GitHub/GitLab 账户
- 来自 Mac 初始配置 或同等配置的现有单密钥设置
1. 按账户生成 SSH 密钥 — 5 分钟
使用刻意区分的文件名。
# 工作账户
ssh-keygen -t ed25519 -C "work@example.com" -f ~/.ssh/id_ed25519_work
# 个人账户
ssh-keygen -t ed25519 -C "personal@example.com" -f ~/.ssh/id_ed25519_personal
# 外部客户(可选)
ssh-keygen -t ed25519 -C "client-foo@example.com" -f ~/.ssh/id_ed25519_client仅在每个 GitHub/GitLab 账户上注册公钥:
pbcopy < ~/.ssh/id_ed25519_work.pub # 工作 GitHub
pbcopy < ~/.ssh/id_ed25519_personal.pub # 个人 GitHub在浏览器中访问 https://github.com/settings/ssh/new,以各账户登录,粘贴并保存。
💡 GitHub 拒绝在两个账户上重复使用同一密钥("Key is already in use")。因此按账户分离密钥是必须的。
2. 编写 ~/.ssh/config — 10 分钟
用主机别名拆分。与 macOS 钥匙串 + Touch ID 扩展集成。
# ~/.ssh/config
# 工作 GitHub
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
AddKeysToAgent yes
UseKeychain yes
# 个人 GitHub
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
AddKeysToAgent yes
UseKeychain yes
# 客户 GitLab
Host gitlab-client
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_client
IdentitiesOnly yes
AddKeysToAgent yes
UseKeychain yes关键选项:
IdentitiesOnly yes— 即使 agent 中存有其他密钥,也只使用显式指定的密钥。不加此选项,错误的密钥会被优先尝试,GitHub 返回 403。AddKeysToAgent yes+UseKeychain yes— macOS 钥匙串集成。密码短语输入一次,之后自动使用。
将密钥添加到 SSH agent
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_personal
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_client验证
ssh -T git@github-work
# Hi work-username! You've successfully authenticated...
ssh -T git@github-personal
# Hi personal-username! You've successfully authenticated...如果打招呼的是错误账户,参见第 3 节 / 故障排除。
3. 在克隆 URL 中使用别名 — 日常模式
工作仓库:
# 普通 GitHub URL — IdentitiesOnly 仍会选对密钥,但使用显式别名更清晰
git clone git@github.com:org/repo.git # IdentitiesOnly + 首次匹配 — 有歧义
# 使用别名 — 明确无误
git clone git@github-work:org/repo.git个人仓库:
git clone git@github-personal:me/myrepo.git已克隆的仓库:更改远端地址。
cd ~/work/repo
git remote set-url origin git@github-work:org/repo.git
cd ~/personal/myrepo
git remote set-url origin git@github-personal:me/myrepo.git用 git remote -v 验证。
4. 自动分支 user.email — includeIf — 5 分钟
按文件夹位置分支 git config user.email。强制工作文件夹的提交使用工作邮箱,个人文件夹使用个人邮箱。
主 ~/.gitconfig
[user]
name = Your Name
# 留空默认邮箱,或使用最常用的
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:~/personal/"]
path = ~/.gitconfig-personal⚠️
gitdir:后的路径必须以斜杠结尾。~/work是错误的,~/work/才是正确的。
~/.gitconfig-work
[user]
email = you@company.com
name = Your Name (Company)
[commit]
gpgsign = true # 如果工作政策要求签名提交
[gpg]
format = ssh
[gpg "ssh"]
defaultKeyCommand = ssh-add -L
program = ssh-keygen~/.gitconfig-personal
[user]
email = you@personal.com
name = Your Name验证
cd ~/work/some-repo
git config user.email
# you@company.com
cd ~/personal/some-repo
git config user.email
# you@personal.com自动路由生效。这从结构上防止了使用错误邮箱提交的情况。
5. gh CLI 多账户 — 同时认证
gh 2.40+ 支持多账户。可以在同一台机器上同时登录工作和个人 GitHub.com。
添加认证
# 第一个账户(如果已登录则跳过)
gh auth login
# 第二个账户
gh auth login # 以不同的 GitHub.com 账户登录切换活跃账户
gh auth status
# 列出所有已登录账户以及当前活跃账户
gh auth switch
# 交互式 — 选择另一个账户
gh auth switch -u personal-username按仓库指定活跃账户(可选)
# 在工作仓库中,激活工作账户
cd ~/work/repo
gh auth switch -u work-usernamegh 命令使用活跃账户。SSH 通过第 2 节的配置分支,不会冲突。
6. 常见问题
6.1 Personal Access Token(PAT)冲突
如果在 gh auth login 中选择了 HTTPS,PAT 存储在系统钥匙串中。其他账户使用了错误的 PAT:
gh auth status # 查看哪个 PAT 存储在哪里
security find-internet-password -s github.com -a "your-username"
security delete-internet-password -s github.com -a "wrong-username"
gh auth login # 重新认证6.2 两个账户访问同一组织
如果个人账户也是工作 GitHub 组织的协作者,克隆 URL 会产生歧义:
# 使用显式别名
git clone git@github-work:org/shared-repo.git work-side
git clone git@github-personal:org/shared-repo.git personal-side将它们放在不同目录,分别对应不同的 user.email + 密钥选择。
6.3 macOS 钥匙串遗忘密码短语
某些 macOS 15+ 配置中,~/.ssh/config 中的 UseKeychain yes 被忽略。解决方法:
# 显式启动 ssh-agent + 添加密钥
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work如有需要,可将自动注册代码片段添加到 .zshrc。
7. 安全检查清单
- 绝不共享私钥 — 只有
.pub文件注册到外部 - 使用密码短语 — 加密密钥文件。macOS 钥匙串缓存,只需输入一次
- 工作/个人密钥分离 — 限制一个密钥泄露的影响范围
-
~/.ssh/config权限 —chmod 600 ~/.ssh/config -
~/.ssh目录权限 —chmod 700 ~/.ssh - 硬件密钥(可选) — YubiKey + FIDO2 通过
ssh-keygen -t ed25519-sk(单独指南)
8. 故障排除
尽管显式指定了密钥,仍提示 Permission denied (publickey)
缺少 IdentitiesOnly yes — agent 中的其他密钥被优先尝试并被拒绝。添加到配置中。
ssh -vT git@github-work 2>&1 | grep -E "(Offering|identity file)"如果尝试了多个密钥,说明缺少 IdentitiesOnly yes。
打招呼的是错误账户
ssh -T git@github-work 返回个人账户。原因:
- ssh-agent 中密钥优先级错误
~/.ssh/config中Host github-work/IdentityFile的块顺序或拼写有误
ssh-add -L # 查看 agent 中有哪些密钥
ssh-add -D # 清除所有
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
ssh -T git@github-workgit push 推到了个人账户
URL 是 git@github.com:org/repo.git,个人密钥在 agent 中优先。更改 URL。
git remote set-url origin git@github-work:org/repo.gitincludeIf 未生效
- 路径缺少末尾斜杠(
~/work❌,~/work/✅) - 文件夹是符号链接 — 取决于 OS。使用真实路径。
gh auth switch 不可用
gh 版本低于 2.40。升级:
brew upgrade gh
gh --version下一步
- Mac 初始配置 — 第一个 SSH 密钥的生成
- Mac dotfiles — 将
.ssh/config和.gitconfig作为 dotfiles 管理 - Brewfile 管理 — 冻结其余开发环境
参考资料
更新日志
- 2026-05-12 — 初始版本(devAlice M3 种子扩展)