如何配置 Git 仓库权限防止敏感代码泄露到公网?

文章导读
单纯依靠 Git 仓库的服务器权限无法完全阻止敏感文件被提交,最有效的方案是结合本地 .gitignore 规则、预提交钩子检查以及服务端分支保护策略。虽然标题提到权限配置,但权限是最后一道防线,防止泄露的核心在于“提交前拦截”与“历史清理”。
📋 目录
  1. 命令速用版
  2. 核心逻辑:为什么仅靠权限不够
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

单纯依靠 Git 仓库的服务器权限无法完全阻止敏感文件被提交,最有效的方案是结合本地 .gitignore 规则、预提交钩子检查以及服务端分支保护策略。虽然标题提到权限配置,但权限是最后一道防线,防止泄露的核心在于“提交前拦截”与“历史清理”。

先说结论:防止敏感配置文件泄露需要“本地忽略 + 历史清理 + 服务端管控”三重防护,仅靠仓库权限不够。

  • 先判断:确认哪些文件属于敏感信息 (如密钥、密码、本地配置)
  • 优先做:配置.gitignore 并使用 git rm `--cached` 移除已跟踪文件
  • 再验证:通过 git check-ignore 测试忽略规则,并检查提交历史

命令速用版

# 从缓存移除已跟踪的敏感文件 (不会删除本地文件)
git rm `--cached` *.env
git rm `--cached` config/local.yml

# 测试忽略规则是否生效
git check-ignore -v .env

# 清理历史中的敏感文件 (推荐使用 git-filter-repo)
git filter-repo `--path` .env `--invert-paths`

核心逻辑:为什么仅靠权限不够

Git 是分布式版本控制系统,一旦执行 commit,数据就进入了本地仓库的历史快照;一旦 push,数据就同步到了远程。即使后来删除了文件,历史记录里依然保留着之前的内容。仓库权限只能控制谁可以 push 或 merge,但无法阻止开发者在本地将敏感文件 add 并提交到历史中。因此,必须在提交前通过忽略规则和钩子拦截,并在发现泄露后彻底清理历史。

分步处理

第一步:配置本地忽略规则

在项目根目录创建或编辑 .gitignore 文件,添加敏感文件模式。常见的包括环境变量 (.env)、密钥文件 (*.pem, *.key)、本地配置 (config/local.yml) 等。如果文件已被跟踪,先从缓存移除。

第二步:启用预提交钩子 (Pre-commit)

为防止人为疏忽,可配置 pre-commit 钩子在提交前自动检查敏感信息。在项目根目录 .git/hooks/pre-commit 文件中添加以下脚本示例,检查是否包含敏感关键词:

#!/bin/sh
# .git/hooks/pre-commit 示例脚本

# 定义敏感关键词模式
PATTERNS="password|secret|api_key|aws_secret"

# 检查暂存区文件内容
if git diff `--cached` `--name-only` | xargs grep -E "$PATTERNS"; then
    echo "错误:检测到潜在敏感信息,提交已拦截!"
    exit 1
fi

exit 0

添加脚本后,赋予执行权限:chmod +x .git/hooks/pre-commit。

第三步:清理已提交的历史记录

警告:清理历史会改写提交哈希,所有协作者都需要重新克隆仓库。操作前务必备份仓库,并通知团队成员暂停开发。git filter-branch 已废弃,建议使用 git-filter-repo。

如何配置 Git 仓库权限防止敏感代码泄露到公网?

安装工具:

pip install git-filter-repo

执行清理(示例):

git filter-repo `--path` .env `--invert-paths`
# 清理后必须强制推送
git push `--force` `--all`

第四步:服务端分支保护配置

在 Git 服务器上设置分支保护规则,限制直接 push 到主分支,增加人工检查防线。

  • GitHub:进入 Settings -> Branches -> Add branch protection rule。选择分支(如 main),勾选"Require pull request reviews before merging"。
  • GitLab:进入 Settings -> Repository -> Protected Branches。选择分支,设置"Allowed to merge"为 Maintainers,"Allowed to push"为 No one。

怎么验证是否生效

使用 git check-ignore 命令测试特定文件是否被忽略。尝试添加敏感文件并执行 commit,观察 pre-commit 钩子是否拦截。检查 git log 历史,确认敏感文件路径不再出现在新的提交记录中。在服务端查看分支保护规则是否生效,尝试直接 push 看是否被拒绝。

常见坑

1. 清理历史会改写提交哈希,所有协作者都需要重新克隆仓库,操作前务必备份。

2. 强制推送(git push `--force`)有风险,确保只有清理历史时才使用,避免覆盖他人代码。

3. .gitattributes 文件本身不能加密,必须保持明文,否则 git-crypt 等工具无法工作。

4. 单纯删除文件不能解决问题,因为数据仍存在于提交历史中,必须清理历史。

参考来源