devAlice
← Mac

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

  1. 为每个账户创建独立 SSH 密钥(ed25519),使用不同的文件名
  2. ~/.ssh/config 中为每个主机显式设置 IdentityFile + Host 别名
  3. 在克隆 URL 中使用别名git@github-work:user/repo.git 而不是 git@github.com:...
  4. 通过 .gitconfigincludeIf 按工作目录自动分支 user.email
  5. gh CLI 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.emailincludeIf — 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-username

gh 命令使用活跃账户。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/configHost github-work / IdentityFile 的块顺序或拼写有误
ssh-add -L                          # 查看 agent 中有哪些密钥
ssh-add -D                          # 清除所有
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
ssh -T git@github-work

git push 推到了个人账户

URL 是 git@github.com:org/repo.git,个人密钥在 agent 中优先。更改 URL。

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

includeIf 未生效

  • 路径缺少末尾斜杠(~/work ❌,~/work/ ✅)
  • 文件夹是符号链接 — 取决于 OS。使用真实路径。

gh auth switch 不可用

gh 版本低于 2.40。升级:

brew upgrade gh
gh --version

下一步

参考资料

更新日志

  • 2026-05-12 — 初始版本(devAlice M3 种子扩展)