Git凭据缓存怎么安全更新

GitHub 停止密码认证后,很多旧项目因为 credential.helper store 继续读取磁盘中的旧密码,提交时反复失败。本文从故障现象讲起,说明 PAT、SSH、Git Credential Manager 和 .git-credentials 的关系,给出 Windows 下清理旧凭据、切换新认证方式和避免明文泄露的完整步骤。

以前在 Windows 上配置 Git,很多人会直接输入 GitHub 账号和密码,再让 Git 记住它。

git config --global credential.helper store
​

第一次 push 时输入一次,后面就不用再输,确实省事。

问题也埋在这里。

store 会把凭据保存到磁盘文件中,而且通常是明文或经过 URL 编码的明文。电脑一旦被其他人访问,或者备份文件泄露,Git 凭据也就一起泄露了。

后来 GitHub 关闭了 HTTPS 密码认证,旧项目突然开始报错:

remote: Support for password authentication was removed.
Please use a personal access token instead.
​

这篇就从这个故障讲起,把 Windows 下 Git 凭据到底存在哪里、怎么清理、PAT 和 SSH 怎么选讲清楚。

先说结论:不要继续把 GitHub 登录密码塞进 Git 凭据文件,优先使用 SSH 或 Git Credential Manager;确实使用 Token 时,也要最小权限、设置有效期并及时轮换。

为什么旧密码突然不能用了

Git 通过 HTTPS 推送代码时,需要完成身份认证。

以前可以输入账号和 GitHub 密码,后来平台逐步关闭了这种方式,要求改用 Personal Access Token,也就是 PAT,或者使用 SSH 密钥。

旧方式:Git HTTPS -> 用户名 + 登录密码

新方式:Git HTTPS -> 用户名 + Personal Access Token

另一种方式:Git SSH -> SSH 私钥 + 远程公钥
​

这里要注意:PAT 不是把密码换了个名字。

它是一段专门用于 API 或 Git 操作的凭据,可以单独设置权限和有效期。

登录密码用于登录账号,PAT 用于授权某些具体操作,两者应该分开管理。

GitHub 报错截图:

GitHub 停止密码认证提示

这个变化解决了一个现实问题:一旦登录密码泄露,攻击者可能拿到整个账号;而 Token 可以限制权限、限制仓库范围,也可以单独撤销。

当然,Token 如果被当成明文密码到处复制,照样会泄露。

credential.helper 到底做什么

Git 本身不会永远替我们保存账号密码。

凭据保存和读取通常由 credential.helper 配置决定。

可以先查看当前配置来源:

git config --show-origin --get-all credential.helper
​

这里的 --show-origin 很有用,它会告诉我们配置来自哪个文件。

Git 配置大致分几个层级:

system  系统级配置
   ↓
global  当前用户配置
   ↓
local   当前仓库配置
​

越靠近当前仓库的配置,通常优先级越高。

常见 helper 有:

  • store:写入磁盘文件,使用方便,但安全性较差
  • cache:只在内存中缓存一段时间,过期后重新输入
  • manager:交给 Git Credential Manager 管理,Windows 上更适合日常使用
  • osxkeychain:使用 macOS 钥匙串
  • Linux 下也可以使用系统密钥环或 Secret Service

不同 Git for Windows 版本显示的 helper 名称可能略有不同。

重点不是死记某个名字,而是确认凭据是否落在明文文件里。

.git-credentials 在哪里

使用 store 后,Git 常见的凭据文件是:

Windows:%USERPROFILE%\.git-credentials
Linux/macOS:~/.git-credentials
​

Windows 下可以在 Git Bash 中查看当前用户目录:

echo $HOME
​

也可以让 Git 告诉我们当前用户配置文件的位置:

git config --global --show-origin --get credential.helper
​

Windows 用户目录下可能会看到 .git-credentials:

Windows 用户目录中的 Git 凭据文件

文件内容可能类似这样:

https://USERNAME:[email protected]
​

真实文件中的密码或 Token 可能经过 URL 编码,例如特殊字符不一定会原样显示。

但不要因此误以为它已经被安全加密。

能够被读取并直接用于认证的凭据,仍然应该按敏感信息保护。

.git-credentials 中的凭据内容示意

先不要直接把文件内容贴出来

排查时不要执行下面这种命令并把结果发到群里:

cat ~/.git-credentials
​

Windows 下也不要直接复制整个 .git-credentials 文件内容。

它里面可能就是有效 Token。

如果已经误贴、误提交或发到公共日志里,应立即撤销对应 Token,再生成新的凭据。

如何清理旧的 store 凭据

如果只是要从 store 切换到更安全的 helper,可以先查看配置,再取消旧配置:

git config --global --get-all credential.helper
git config --global --unset-all credential.helper
​

如果仓库级别也配置过,需要进入仓库目录检查:

git config --local --get-all credential.helper
git config --local --unset-all credential.helper
​

注意 --unset-all 没有匹配项时可能返回非零状态,这不一定是故障,只表示对应层级没有这个配置。

清理配置后,可以删除或备份旧的 .git-credentials 文件。

如果文件里还保存着其他仓库的凭据,不建议一把删掉全部内容,可以使用 Git 的 credential 操作按 host 清理。

Git Bash 示例:

printf 'protocol=https\nhost=github.com\n\n' | git credential reject
​

这条命令不会把 Token 打到命令行里,Git 会根据协议和 host 请求凭据存储器删除匹配项。

执行后再检查配置和实际 push 行为,不要直接输出凭据文件验证。

HTTPS 和 PAT 怎么配置

如果继续使用 HTTPS,推荐使用 Git Credential Manager 保存 Token。

先确认 helper 配置:

git config --global credential.helper manager
​

不同 Git for Windows 版本可能已经默认配置好 Git Credential Manager。

如果执行 push 时弹出登录窗口,就按提示完成登录;如果平台要求输入 Token,则把 Token 当作密码输入,不要把登录密码再次填进去。

Username:GitHub 用户名
Password:Personal Access Token
​

这里的 Token 只会用于 Git 操作,不要把它写进脚本、README、截图或 CI 日志。

Token 权限要最小化

创建 Token 时不要习惯性勾选所有权限。

只授予当前仓库和当前任务需要的权限。

至少要关注:

  • 是否只允许访问指定仓库
  • 是否需要读写代码权限
  • 是否需要访问 Actions、Packages 或组织资源
  • 是否设置过期时间
  • 是否有组织策略要求额外审批

不同类型的 GitHub Token 页面和权限名称会变化,创建时以平台当前页面为准。

核心原则不变:权限越小越好,生命周期越短越好,用完及时撤销。

不建议把 Token 写进远程地址

下面这种方式虽然可能工作,但不建议作为长期配置:

git remote set-url origin https://USERNAME:[email protected]/OWNER/REPO.git
​

因为 Token 可能出现在:

  • shell 历史记录
  • .git/config
  • 进程参数
  • 日志和错误信息
  • 屏幕截图

如果只是临时排查,也不要使用真实生产 Token。

更不要把包含 Token 的 .git/config 提交进仓库。

SSH 是不是更适合

如果电脑长期维护 GitHub 仓库,我个人更倾向于使用 SSH。

SSH 的认证思路是:私钥保存在本机,公钥配置到代码托管平台,Git 通过密钥完成身份验证。

生成密钥时可以使用现代算法:

ssh-keygen -t ed25519 -C mebugs-github
​

生成后把公钥内容配置到 GitHub 的 SSH Keys 中:

cat ~/.ssh/id_ed25519.pub
​

然后把远程地址切换为 SSH:

git remote set-url origin [email protected]:OWNER/REPO.git
​

测试连接:

ssh -T [email protected]
​

SSH 的优势:

  • 不需要每次输入 Token
  • 私钥不上传到平台
  • 可以为不同平台配置不同密钥
  • 更适合长期开发机和自动化环境

但私钥本身就是高价值凭据。

不要把 id_ed25519 上传到仓库,也不要把私钥复制到公共机器。

Windows 下怎么选择

Windows 上可以按使用场景选择:

偶尔提交、希望弹窗管理:Git Credential Manager
长期开发机、多个代码平台:SSH
临时脚本或受控 CI:短期 Token + Secret 管理
历史项目继续使用 store:尽快清理并迁移
​

如果只是把旧密码换成新 Token,可以按这个顺序处理:

  1. 用 git config --show-origin --get-all credential.helper 确认保存方式
  2. 清理旧的 store 配置和旧凭据
  3. 撤销已经暴露或过期的旧 Token
  4. 选择 Git Credential Manager 或 SSH
  5. 再执行一次 git fetch 或 git push
  6. 检查远程地址、配置来源和日志,确认没有把凭据打印出来

不要只修改 .git-credentials 里的一行就结束。

能提交成功不代表凭据已经安全。

CI 里不要使用本地凭据

本地开发机和 CI 环境的凭据管理方式应该分开。

CI 中不要把 Token 直接写到 YAML:

# 不要这样写
TOKEN: real-token-value
​

应该使用平台的 Secret、变量库或密钥管理服务。

脚本里通过环境变量读取,并注意关闭命令回显:

# Token 从 CI Secret 注入,不写入仓库
git remote set-url origin https://USERNAME:${GIT_TOKEN}@github.com/OWNER/REPO.git
​

即使这样也要小心:命令参数、失败日志和调试输出都可能泄露 Token。

更稳妥的方案是使用 CI 平台提供的专用 Token、部署密钥或 OIDC 身份,不要复用个人长期 Token。

凭据泄露后怎么办

如果怀疑 Token 或密码已经泄露,不要先慢慢排查文件,先撤销凭据。

建议顺序:

  1. 到代码托管平台撤销 Token 或删除对应 SSH 公钥
  2. 检查 Token 的访问记录、组织审计日志和仓库操作记录
  3. 检查提交历史、Issue、构建日志和聊天记录中是否出现凭据
  4. 清理本地 .git-credentials、shell history 和 CI 变量
  5. 重新生成最小权限、短有效期的凭据
  6. 检查仓库是否存在异常提交、分支、Tag 或 Actions 任务

如果 Token 曾经进入 Git 提交历史,只删除当前文件还不够。

历史提交仍然可能被别人获取,需要按平台的敏感信息泄露流程处理,并在凭据撤销后再清理历史。

小结

这篇文章的故障背景来自 GitHub 关闭密码认证,但真正值得记住的是凭据管理原则:

  • credential.helper store 方便,但可能把凭据明文保存到 .git-credentials
  • HTTPS 提交应使用 PAT 或 Git Credential Manager,不要继续使用账号密码
  • Token 需要最小权限、有效期和轮换机制
  • 长期开发环境优先考虑 SSH,私钥必须妥善保管
  • 不要把 Token 放进远程 URL、脚本、日志、截图或代码仓库
  • CI 凭据使用 Secret、部署密钥或平台身份,不复用个人长期 Token
  • 一旦泄露,先撤销,再排查和清理

一句话总结:Git 凭据能让 push 成功只是第一步,凭据不落明文、不超权限、可撤销和可轮换,才算真正配置完成。

旧项目可以慢慢迁移,但不要继续把明文密码当成默认方案。安全这件事,离离原上谱一次就够了。

更多推荐

章节目录