← 中文资源

简体中文版本

用 SOPS 与 age 加密入库的秘密

用 SOPS 与 age 把加密秘密与配置同库存储,解密密钥留在库外,并支持免全量重加密的轮换。

阅读英文原文

目标

仓库适合存放配置的“形状”,却是存放秘密的糟糕地方。SOPS 加 age 把两者拆开:文件留在 git 里、键名可读、值是密文,评审能看到结构上改了什么,而只有持有正确私钥的环境才能看到值。轮换只需原地重包数据密钥,明文永不回到工作区。

步骤要点

  1. 为每个环境生成 age 密钥对,只有公钥进仓库,私钥走密钥分发流程。
  2. sops –encrypt –age 各环境公钥 –in-place 加密 secrets.yaml,键名可读、值变密文、可 diff 可合并。
  3. git grep 确认工作区再无明文,本机持有 staging 私钥时可正常解密验证。
  4. CI 用注入的 SOPS_AGE_KEY(完整私钥文件内容)解密后部署,密钥永不入库。
  5. 环境密钥泄漏时跑 sops –rotate –in-place:数据密钥重包给新接收者,秘密本身不动、无需重录。

排错提示

新机器克隆后解不开是私钥没分发到位,私钥走环境分发渠道而不是仓库;CI 报 keyring 错误多半是 SOPS_AGE_KEY 没存完整文件内容(含换行);加密文件合并冲突时解密两侧、合并明文映射、重新加密即可,因为按键加密保留了结构可读性。

适用边界

git 静态加密的前提是私钥本身被严守,仓库从来不是密钥保险箱而是数据柜;SOPS 保护的是值不是键名与结构,后者有意保持可见以支持评审。

代码示例

# Encrypt for the environments that may read it
sops --encrypt --age age1stagingpub,age1prodpub \
  --in-place config/secrets.yaml

# CI decrypts with an injected private key
SOPS_AGE_KEY="$KEY_FILE" sops --decrypt config/secrets.yaml