跳转至

安全

vault 装的是"丢一个毁一片"的东西。这页讲清楚安全模型,重点在两件事:

  1. 加密怎么做的 —— data/ 怎么保证即使仓库上云也不泄密
  2. 密钥怎么管 —— 丢了就全毁,必须备份

加密模型:git-crypt

data/ 目录下所有文件在 commit 时自动加密,在本地 checkout 时自动解密。你平时操作感知不到,但推上 GitHub 的是加密后的密文

加密规则

来自仓库根目录 .gitattributes

data/**/*.json filter=git-crypt diff=git-crypt
data/files/**  filter=git-crypt diff=git-crypt

凡是匹配这两条的文件,git 都走 git-crypt 过滤器。其它文件(src/ / docs/ / schemas/ / pyproject.toml / ...)不加密

验证已加密

# 远端看到的是密文(GITCRYPT 头部 + 乱码)
git show HEAD:data/credentials/aliyun-main.json | head -1

# 本地看到的是明文
cat data/credentials/aliyun-main.json | head -1

CI 能看到明文吗?

不能。GitHub Actions 拉代码时只拿到加密版。跑 vault check / pytest integration 这些需要真实数据的测试会失败,所以我们在 CI 里设 VAULT_SKIP_INTEGRATION=1 跳过它们。

CI 只做代码层面校验(ruff、schema 合法性、unit 测试、mkdocs build)。真实数据的验证留本地 pre-commit 做。


密钥管理:.git-crypt/keys/default

这一个文件就是整个 vault 的命门

路径

/Users/yarnb/vault/.git-crypt/keys/default

这个文件不在 git 里.git/ 本身就不跟踪),是初始化 git-crypt 时本地生成的对称密钥。

丢了会怎样

  • 本地其它用户(新机器、新同事)永远没法解密 data/ —— 仓库里看到的永远是 GITCRYPT 乱码
  • 哪怕你还记得每个平台的密码,你也读不了 vault 里存的那些
  • 唯一的自救:挨个平台手工轮换、手工重建 vault

结论:丢 key = vault 数据从此锁死。

必须做的备份

至少 3 备份原则:

位置 怎么做
本地 macOS 原始文件已在(~/vault/.git-crypt/keys/default
iCloud / Dropbox 加密目录 手动 cp .git-crypt/keys/default ~/Library/Mobile\ Documents/com~apple~CloudDocs/secure/git-crypt-vault.key
外部介质(U 盘 / 纸质打印 base64) 离线备份,长期存放

建议定期验证备份能解锁:

# 新目录模拟恢复
cd /tmp && git clone git@github.com:yarnovo/vault.git vault-restore
cd vault-restore
git-crypt unlock /path/to/backup/default  # 用备份的 key 解锁
cat data/credentials/aliyun-main.json     # 能看到明文就算成功

新机器怎么 unlock

git clone git@github.com:yarnovo/vault.git
cd vault
git-crypt unlock /path/to/your/backup.key
# 之后 data/ 自动可读

密钥本身能不能上云?

绝对不要。git-crypt key 上云 = 加密白做。


最小权限原则

当 vault 里的凭证要被外部系统使用时(比如 GitHub Actions 跑部署),不要直接把 main/root token 给它。另建一个权限最小的专用 token。

现成案例:cloudflare-pages-deploy

cloudflare-main              kind=api_token    (有 DNS / Zone / Workers 等全套权限)
cloudflare-pages-deploy      kind=api_token    (只有 Cloudflare Pages:Edit 权限)
                                               ← 这个才给 GitHub Actions

好处: - pages-deploy token 泄漏,别人只能搞 Pages,不能删你域名 DNS 记录 - 轮换独立,不影响另一个 - vault credential show cloudflare-pages-deploy 看到 metadata 里记录了它的 consumers(GitHub Actions secret 名字),一眼知道在哪用

设计上所有"外部可见"的 token 都应走这个模式,在 credential.metadata 里记: - scopes: 实际授予的权限列表 - consumers: 谁在用(哪个项目的哪个 secret) - created_at: 何时创建


消费方项目的本地 secrets

vault install 在消费方项目生成两个文件:

.vault/secrets.json      # 结构化凭证(按 alias)
.env                     # 扁平 env vars(只含显式映射)

权限约定

CLI 自动: - .vault/ 目录 chmod 700 - .vault/secrets.json chmod 600 - .env chmod 600

这些是本地文件权限,防止同机器其他用户读到。

gitignore

vault install 自动往项目 .gitignore 追加:

.vault/
.env

这两行绝不能漏,漏了直接 push 会把明文上 GitHub。

删除

消费方项目不用了:

rm -rf .vault/ .env

直接删,没历史包袱(vault 里的原 credential 还在)。


威胁模型清单

威胁 对抗 残余风险
GitHub 仓库被看到 git-crypt 加密 data/ 低:攻击者看到密文
本地 mac 被盗 FileVault + git-crypt key 不在仓库里 中:若 mac 未锁 + key 文件可读
token 泄漏 最小权限原则 + 按 consumer 拆 credential 中:泄漏到期前可能被滥用
CI log 泄漏 CI 不接触明文 data/;GitHub Secret 自动脱敏
消费方 secrets.json 被别的进程读 chmod 600 + gitignore 中:同机器其他 root 进程可读
git-crypt key 丢失 3-重备份 :数据永久锁死

最大的风险是 key 丢失,远大于 key 泄漏。


轮换

凭证轮换(日常)

# 比如 aliyun-main AK 轮换
vault credential edit aliyun-main       # 打开 $EDITOR 改 values.access_key_secret
# 所有引用这把 AK 的消费方项目
cd ~/xiangqin && vault sync              # 重拉最新值

git-crypt key 轮换(罕见 —— 只在疑似 key 泄漏时)

git-crypt 本身不支持原地换 key。你只能: 1. 导出所有明文 data/ 2. 删仓库,重新 git-crypt init 生成新 key 3. 重新 add + commit + push 4. 所有备份 + 新机器用新 key

大动作,非必要不做。


速查

事件 做什么
新 mac 第一次用 vault git clone + git-crypt unlock <备份 key>
GitHub 仓库被意外 public 立刻轮换所有 credential + 考虑 revoke git-crypt key
Mac 丢了 确认 FileVault 开了 → 轮换所有 credential(保险) → 新 mac 用备份 key 恢复
发现 .env 被 commit 了 git rm --cached .env + git commit + 立刻轮换该 env 里的所有值(已进 git history)
忘了 mac 密码 key 还在,但进不去 → 找苹果 recovery
忘了 key 放哪 挨个备份位置翻(macOS mdfind -name git-crypt-vault.key);都没就进入重建流程