使用 SOPS 管理 Git 仓库中敏感信息的完整教程
引言
在现代软件开发中,敏感信息如数据库连接字符串、API 密钥、令牌等常常需要存储在代码仓库中(如 Git)。直接以明文形式存储这些信息会带来严重的安全风险,例如仓库被泄露时导致数据暴露。为了解决这个问题,我们可以使用 SOPS(Secrets OPerationS)工具来加密这些敏感数据。SOPS 由 Mozilla 开发,目前是 CNCF Sandbox 项目,它支持多种加密后端(如 age、PGP、AWS KMS 等),并允许在本地开发时透明地编辑明文,而仓库中保持加密状态。
本教程将一步步指导你使用 SOPS + age(一种简单、安全的加密工具)来实现:
- 在 Git 仓库中存储加密的敏感文件(如 YAML/JSON 配置)。
- 本地开发者透明编辑(看到明文)。
- 服务器拉取代码后,使用服务器上的密钥解密,并在程序中读取。
这种方案特别适合自托管环境或团队协作,避免了明文泄露,同时集成 GitOps 工具(如 Flux 或 ArgoCD)也很友好。预计完成时间:30-60 分钟。
先决条件
- 操作系统:Linux、macOS 或 Windows(WSL 推荐)。
- Git:已安装并配置好仓库。
- 编辑器:如 VS Code、Vim,支持 YAML/JSON。
- 基本命令行知识:熟悉 bash 或类似 shell。
- 示例文件:准备一个敏感配置文件,例如
secrets.yaml:db: url: "mysql://user:pass123@host:3306/mydb" password: "verysecret" api: key: "sk-abcdefghijklmnopqrstuvwxyz" - 可选:如果使用云服务,可替换 age 为 AWS KMS 等,但本教程聚焦 age。
步骤 1: 安装 SOPS 和 age
-
下载 SOPS:
- 访问 GitHub 仓库:https://github.com/getsops/sops/releases
- 下载最新版本(推荐 v3.8.1 或更高)。例如,对于 Linux AMD64:
wget https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1.linux.amd64 -O /usr/local/bin/sops chmod +x /usr/local/bin/sops - macOS:使用 Homebrew
brew install sops。 - Windows:下载 .exe 文件并添加到 PATH。
-
下载 age:
- 访问 GitHub 仓库:https://github.com/FiloSottile/age/releases
- 下载最新版本(推荐 v1.2.0 或更高)。例如,对于 Linux:
wget https://github.com/FiloSottile/age/releases/download/v1.2.0/age-v1.2.0-linux-amd64.tar.gz tar xzf age-v1.2.0-linux-amd64.tar.gz sudo mv age/age age/age-keygen /usr/local/bin/ - macOS:
brew install age。 - Windows:类似下载并配置。
-
验证安装:
sops --version age --version age-keygen --version输出应显示版本号。
步骤 2: 生成 age 密钥对
age 使用公钥加密、私钥解密。密钥对只需生成一次。
-
在安全位置运行:
age-keygen -o agekeys.txt- 这会生成一个文件
agekeys.txt,内容类似:# created: 2026-01-14T19:00:00+08:00 # public key: age1ql52nd0j2lhfsda6lxpck0w80pn8n7vx3qlt2cpmegpj4kw67kmq7xxxxx AGE-SECRET-KEY-1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - 公钥(以
age1开头):用于加密,可公开。 - 私钥(以
AGE-SECRET-KEY-开头):用于解密,严格保密。
- 这会生成一个文件
-
安全存储密钥:
- 本地开发者:将私钥存入密码管理器(如 1Password、LastPass)。
- 服务器:将私钥存到受保护文件,如
/etc/age-server.key(权限chmod 600),或作为环境变量SOPS_AGE_KEY。 - 警告:切勿将私钥提交到 Git!丢失私钥将导致数据永久不可解密。
-
团队协作:如果多人开发,为每个成员生成独立密钥对,并收集公钥(稍后配置)。
步骤 3: 配置 SOPS(创建 .sops.yaml)
在 Git 仓库根目录创建 .sops.yaml 文件,用于定义加密规则。
-
编辑
.sops.yaml:creation_rules: - path_regex: \.(yaml|yml|json)$ # 匹配 YAML/JSON 文件 encrypted_regex: ^(data|stringData|password|token|key|secret|api_key|db_url|pass|credentials)$ # 只加密匹配这些键的 value age: - recipient: age1ql52nd0j2lhfsda6lxpck0w80pn8n7vx3qlt2cpmegpj4kw67kmq7xxxxx # 你的公钥 # - recipient: age1anotherpubkey... # 加其他成员公钥path_regex:指定哪些文件应用规则。encrypted_regex:结构化加密,只加密敏感字段(如 password),而非整个文件。age:列出所有允许加密的公钥。
-
提交到 Git:
git add .sops.yaml git commit -m "Add SOPS configuration" git push
步骤 4: 加密和编辑敏感文件(本地透明操作)
SOPS 允许你像编辑普通文件一样操作,但仓库中自动加密。
-
创建新加密文件:
sops secrets.yaml- SOPS 会打开默认编辑器(可配置为 VS Code:
export EDITOR=code --wait)。 - 输入明文内容,保存退出 → 文件自动加密保存。
- Git 中查看:
cat secrets.yaml显示加密形式(如ENC[AES256_GCM,data:xxxx...,iv:...,tag:...,type:str])。
- SOPS 会打开默认编辑器(可配置为 VS Code:
-
编辑现有文件:
sops secrets.yaml- SOPS 先用私钥解密,显示明文 → 编辑 → 保存后重新加密。
- 透明性:无需手动解密/加密,感觉像普通文件。配置环境变量
SOPS_AGE_KEY_FILE=~/agekeys.txt后,甚至无需每次输入密码。
-
提交到 Git:
git add secrets.yaml git commit -m "Add encrypted secrets" git push- 仓库中始终是加密态。
-
解密查看(可选):
sops --decrypt secrets.yaml- 输出明文,但不修改文件。
步骤 5: 服务器侧部署和解密
服务器拉取代码后,文件是加密的。需要在部署流程中解密。
-
安装 SOPS 和 age:服务器上重复步骤 1。
-
存储私钥:如
echo "AGE-SECRET-KEY-..." > /etc/age-server.key && chmod 600 /etc/age-server.key。 -
在部署脚本中解密:
-
简单方式:生成明文文件。
export SOPS_AGE_KEY_FILE=/etc/age-server.key sops --decrypt secrets.yaml > decrypted-secrets.yaml -
程序读取
decrypted-secrets.yaml。 -
更安全方式(不落地明文):使用
exec-env注入环境变量。export SOPS_AGE_KEY_FILE=/etc/age-server.key sops exec-env secrets.yaml 'your-app-command --arg'- 示例:在 Python 程序中:
import os import mysql.connector db_url = os.getenv('db__url') # SOPS 注入的环境变量(双下划线分隔嵌套键) db_password = os.getenv('db__password') api_key = os.getenv('api__key') # 连接数据库 conn = mysql.connector.connect( host="host", user="user", password=db_password, database="mydb" ) # 使用 api_key 调用 API - 运行:
sops exec-env secrets.yaml 'python app.py'。
- 示例:在 Python 程序中:
-
-
集成 CI/CD:在 Jenkins/Dockerfile 中添加解密步骤,或使用 Kubernetes Secrets Operator。
步骤 6: 团队协作和密钥管理
-
添加新成员:
- 为新成员生成 age 密钥对。
- 将其公钥添加到
.sops.yaml的age列表。 - 运行
sops updatekeys secrets.yaml更新所有文件(用新密钥重新加密)。
-
撤销访问:
- 从
.sops.yaml移除公钥。 - 运行
sops updatekeys secrets.yaml。 - 旧成员无法再解密新版本文件。
- 从
-
密钥轮换:
- 生成新密钥对。
- 更新
.sops.yaml。 sops updatekeys --all重新加密所有匹配文件。
-
备份:定期备份私钥到安全位置(如加密 U 盘)。
注意事项和最佳实践
- 安全性:始终使用强密钥,避免共享私钥。考虑集成硬件密钥(如 YubiKey)。
- 性能:SOPS 只加密敏感部分,不会影响大文件。
- 错误处理:如果解密失败,检查环境变量或密钥文件权限。常见错误:
sops: no valid recipients found(公钥不匹配)。 - 替代后端:如果使用 AWS,替换 age 为
kms: - arn:aws:kms:...(需 AWS CLI 配置)。 - Git 集成:添加 Git hook(如 pre-commit)确保敏感文件始终加密。
- 审计:使用
git log检查历史,确保无明文泄露。 - 局限性:SOPS 不支持二进制文件加密(如证书),用 age 单独处理。
- 资源:官方文档 https://github.com/getsops/sops;age 文档 https://age-encryption.org/。
结尾
通过本教程,你已学会使用 SOPS + age 安全管理 Git 仓库中的敏感信息。这种方法平衡了安全性和便利性,适用于从个人项目到企业级应用的各种场景。如果遇到问题,检查日志或社区论坛。欢迎反馈或扩展到其他后端!

浙公网安备 33010602011771号