让 Git 提交自动带「Verified」徽章:GitHub SSH 签名免 ssh-agent 实战
你有没有遇到过这种情况:兴冲冲给 Git 配好 SSH 签名,结果一提交就报错
Couldn't get agent socket?,然后被「每次开终端先eval "$(ssh-agent -s)"再ssh-add」的繁琐流程劝退?本文讲一个更简单的方案:把
user.signingkey直接指向私钥文件,从此git commit全自动签名,彻底不需要 ssh-agent、不需要 Windows 服务、不需要任何前置命令。
为什么要给提交签名
没签名的提交,GitHub 上长这样:
liuweiqing committed 2 minutes ago签名之后:
liuweiqing committed 2 minutes ago ✓ Verified那个绿色Verified徽章的意义是:这个提交确实出自你本人,没有被中间人篡改或冒名顶替。在开源协作、团队 CI 校验、供应链安全越来越受重视的今天,签名提交正在从「加分项」变成「默认项」。
GitHub 支持三种签名方式:GPG / SSH / S/MIME。本文聚焦最省事的SSH 签名——前提是你已经有一把 SSH 密钥(大概率你已经在用它git push了)。
背景:SSH 签名的两个阶段
Git 的 SSH 签名机制分两步:
- 签名:
git调用ssh-keygen -Y sign,用你的私钥对提交内容生成签名。 - 验证:
git log --show-signature调用ssh-keygen -Y verify,用allowed_signers文件把邮箱映射到公钥来校验。
问题就出在第 1 步。Git 默认把user.signingkey当作公钥,交给ssh-keygen去签名——但ssh-keygen只能从 ssh-agent 拿私钥,没法直接读私钥文件。于是:
- 没有 agent → 报错
Couldn't get agent socket? - 有了 agent 但没
ssh-add→ 还是报错
这就是「每次开终端都要折腾 agent」这个坏习惯的来源。
关键技巧:让 signingkey 直接指向私钥文件
绕开 agent 的核心就一句话:
把
user.signingkey设成私钥文件路径(如~/.ssh/id_rsa),而不是公钥内容。
当signingkey是一个文件路径时,ssh-keygen会直接读取该文件里的私钥完成签名,完全不需要 agent 中转。这一改,整个繁琐链路就消失了。
完整配置步骤(从 0 到 Verified)
以下示例邮箱为liuweiqing147@gmail.com,请替换成你自己的。
1. 确认已有 SSH 密钥
ls~/.ssh/*.pub# 输出示例:/c/Users/13963/.ssh/id_rsa.pub如果没有,先生成一把(推荐复用你登录 GitHub 的那把,省事):
# 仅当你还没有密钥时才需要ssh-keygen-trsa-b4096-C"you@example.com"2. 写入 Git 全局签名配置
# 告诉 git 用 SSH 格式签名gitconfig--globalgpg.formatssh# ★ 关键:signingkey 指向「私钥文件」,不是公钥内容gitconfig--globaluser.signingkey ~/.ssh/id_rsa# 提交和 tag 自动签名(之后不需要再手动加 -S)gitconfig--globalcommit.gpgsigntruegitconfig--globaltag.gpgsigntrue3. 创建 allowed_signers 文件
这是 SSH 签名必须的映射文件,把邮箱和公钥对应起来(验证阶段要用):
gitconfig--globalgpg.ssh.allowedSignersFile ~/.ssh/allowed_signers# 把你自己的邮箱 + 公钥写进去printf'%s namespaces="git" %s\n'\"liuweiqing147@gmail.com"\"$(cat~/.ssh/id_rsa.pub)">~/.ssh/allowed_signers文件内容形如:
liuweiqing147@gmail.com namespaces="git" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC...4. 完成 —— 不需要启动任何 agent
到此为止,配置全部完成。没有 ssh-agent、没有 Windows 服务、没有前置命令。
验证签名链路
随便建个临时仓库测一下(不开 agent,纯全局配置):
cd/tmp&&rm-rfgit-check&&mkdirgit-check&&cdgit-checkgitinit-qgitcommit-q--allow-empty-S-m"test signed commit"# 或直接 git commit(已全局开启)gitlog --show-signature-1看到这行就成功了:
Good "git" signature for liuweiqing147@gmail.com with RSA key SHA256:V6n/4TEs...8A如果显示Good,说明签名 + 本地验证全链路打通。
还差你最后一步:把公钥加到 GitHub
Git 这边配好了,但 GitHub不知道这把公钥是你的,所以提交推上去仍是Unverified。需要在 GitHub 网页单独登记一次「签名密钥」:
- 复制公钥内容:
cat~/.ssh/id_rsa.pub - 打开 👉 https://github.com/settings/ssh/new
- Title随便填(如
laptop-signing) - Key type 务必选
Signing Key(默认是 Authentication Key,选错不会生效!) - 粘贴公钥 →Add SSH key
⚠️ 即使这把
id_rsa已经作为「Authentication key」加过,GitHub 也要求再单独加一次到 Signing keys 区。两者是分开管理的。
加完之后,再git push上来的提交就会显示绿色Verified徽章 🔏
常见坑 & FAQ
| 现象 | 原因 | 解决 |
|---|---|---|
Couldn't get agent socket? | signingkey是公钥,git 去找 agent 拿私钥 | 把signingkey改成私钥文件路径 |
本地Good但 GitHub 显示Unverified | 公钥没加到 GitHub 的Signing keys | 去 settings/ssh/new,Key type 选 Signing Key 重加 |
No principal matched/ 验证失败 | allowed_signers里邮箱和提交邮箱不一致 | 确保allowed_signers邮箱 =git config user.email |
| 私钥有密码时仍提示输入 | 正常,签名时要解锁私钥 | 要么输密码,要么换无密码密钥(注意保管) |
关于私钥密码:本文示例用的是无密码密钥,所以签名完全无感。如果你的私钥设了密码,每次签名仍需输一次——这是安全与便利的取舍,按需选择。
总结
让 Git 提交自动带Verified徽章,最省事的配置就这几行:
gitconfig--globalgpg.formatsshgitconfig--globaluser.signingkey ~/.ssh/id_rsa# 私钥文件,免 agent 的关键gitconfig--globalcommit.gpgsigntruegitconfig--globaltag.gpgsigntruegitconfig--globalgpg.ssh.allowedSignersFile ~/.ssh/allowed_signers再加上 GitHub 网页登记一次 Signing Key,就齐活了。告别 ssh-agent,从此git commit即签名。
本文基于 Windows + Git for Windows 2.53 + OpenSSH 实测验证。其他平台(macOS / Linux)步骤完全一致,区别仅在于密钥路径。