跳到正文

Moatgator Vault

在一处管理后端、CI 和移动应用的机密

在原本写值的地方放一个 mg:// 引用。CLI、GitHub Actions 和移动 SDK 在运行时解析它,而你的应用只会在通过 Attest 的设备上收到机密。

Startup 套餐起提供。

terminal示例
$ moatgator secrets run --env-file .env.tpl -- npm start$ moatgator secrets inject -i .env.tpl -o .env$ moatgator secrets get mg://api/prod/DATABASE_URL

mg:// 引用

提交引用,而不是值

引用指明一个项目、一个环境和一个机密,例如 mg://api/prod/DATABASE_URL。它可以放心地保存在 Git 中:只有具备访问权限的身份才能把它解析成值。

  1. 01

    仓库中的 .env.tpl

    保留一个包含引用的模板。moatgator secrets inject 以 0600 权限写入 .env,没有 --force 时不会覆盖已有文件。

    .env.tpl示例
    # .env.tpl: safe to commitDATABASE_URL=mg://api/prod/DATABASE_URLSTRIPE_KEY=mg://api/prod/STRIPE_KEYSENTRY_DSN=mg://api/prod/SENTRY_DSN
  2. 02

    moatgator secrets run

    把机密作为环境变量来运行你的命令,并在命令输出中隐藏它们的值。moatgator secrets get 读取单个引用。

    terminal示例
    $ moatgator secrets run --env-file .env.tpl -- npm start$ moatgator secrets inject -i .env.tpl -o .env$ moatgator secrets get mg://api/prod/DATABASE_URL
  3. 03

    应用中使用同一个引用

    在 Android SDK 中,Moatgator.vault.get("mg://mobile/prod/PARTNER_KEY") 读取控制台中与该应用关联的环境。值永远不会打包进 APK。

    Kotlin示例
    // Android (Kotlin), off the main threadMoatgator.startSession(playIntegrityProvider)val key = Moatgator.vault.get("mg://mobile/prod/PARTNER_KEY")

项目、环境与版本

  • 项目与环境

    每个项目默认带有 dev、staging 和 prod。需要时可以添加自己的环境。

  • 继承与覆盖

    一个环境可以继承另一个环境,最多三层。同名机密会覆盖继承来的机密。

  • 受保护的环境

    prod 默认受保护:只有所有者和管理员可以读取其中的值或向其写入。

  • 版本与回滚

    每次修改都会生成一个带历史记录的版本。回滚会创建新版本,因此历史永远不会被改写。

  • 即时撤销

    撤销一个机密或服务令牌后,下一次读取就会被拒绝,无需等到过期日期。

  • 角色

    所有者、管理员、开发者和读者四种角色决定谁能看到值、谁能修改值。

仅限已证明的设备

同一个机密,只在通过 Attest 的设备上交付给你的移动应用

机密管理工具通常服务于服务器、开发者和 CI。Vault 还服务于用户手中的应用:SDK 在运行时请求,API 检查设备的 Attest 结果(Play Integrity 或 App Attest,加上 Moatgator RASP 的信号),并用该会话的临时密钥加密后发送值。二进制文件中不放入任何内容。

SDK 只在内存中保存值,绝不写入磁盘或日志。mg:// 引用可在 Android SDK 中使用。

按机密设置的策略

  • 最低判定结果为每个机密选择可以接收它的最低 Attest 判定结果。
  • 要求平台证明要求平台证明结果,而不只是 SDK 自身的信号。
  • 证明的最长时效当设备的证明早于你允许的时限时,拒绝下发该机密。

CI 与服务器

CI 中不存放长期令牌

GitHub Action moatgator-hq/github-action/vault 用作业的 OIDC 令牌换取一个有效期 15 分钟的读取令牌。Pull request 永远拿不到令牌。在没有 OIDC 的地方,请使用服务令牌。

  • 服务令牌(mgvt_…)为只读,并绑定到一个项目以及你选择的环境。
  • 必须设置过期时间:默认 90 天,最长一年。
  • 值在作业日志中会被遮蔽,且永远不会成为步骤输出。
  • 无法解析的引用会让该步骤失败,且不导出任何内容。
.github/workflows/deploy.yml示例
permissions: { contents: read, id-token: write }steps:  - uses: moatgator-hq/github-action/vault@v1    with:      project-id: vpj_…      secrets: |        DATABASE_URL=mg://api/prod/DATABASE_URL  - run: ./deploy.sh   # $DATABASE_URL, *** in the log

同步与轮换

把机密推送到你部署的地方,并按计划轮换

同步会把一个环境(含继承)持续复制到 GitHub Actions 机密、Railway 或 Vercel。它在创建时运行一次,之后该环境或它所继承的环境每次变更后都会再次运行。

  • GitHub Actions 机密

    同步到一个仓库或一个 GitHub 环境。每个值在离开 Moatgator 之前,都会用该仓库的公钥加密。

  • Railway

    同步到某个 Railway 项目和环境的变量,或单个服务的变量。

  • Vercel

    同步到某个 Vercel 项目的 production、preview 或 development 变量,并以加密变量的形式保存。

  • 明确授权与状态

    你需要确认每个目标,并为它提供一个仅限该目标使用的令牌,令牌以加密形式保存。每个同步都会显示上次运行时间、写入了多少个机密以及出现的错误。

定期轮换

  • 按计划生成新的随机值适用于只有你的公司使用的机密,例如 HMAC 密钥和会话机密:Moatgator 会生成新值、创建一个版本并运行同步。
  • 其他提供方密钥的提醒对于由其他服务签发的密钥,所有者和管理员会在到期时收到邮件,控制台会将该轮换显示为已逾期,直到保存了新值为止。

同步只向目标写入,并且只删除它自己在那里写入的机密。删除一个同步不会改动目标中的内容。

按组织加密,每次读取都有审计

  • 按租户的信封加密

    每个组织都有自己的密钥,由主密钥封装。

  • 密文绑定到其位置

    每份密文都绑定到其项目、环境、名称和版本,因此无法被挪到另一个机密下。

  • 值不进入日志

    机密的值从不写入我们的日志,CLI 和 Action 也会在你的输出中隐藏它们。

  • 每次读取的审计记录

    每次读取都会记录:谁读取、从哪里读取、哪个版本以及结果。

对比

Moatgator Vault、1Password 与 Doppler

1Password 和 Doppler 是成熟的机密管理工具,两者都能完成 Vault 的大部分工作。下表展示各自的情况,凡是关于它们的单元格,都附有公开来源和我们核实的日期。Vault 不是面向个人的密码管理器:它专注于应用、CI 和移动设备。

机密管理功能并排对比
功能Moatgator Vault1PasswordDoppler
用引用代替值

mg://project/environment/NAME,移动 SDK 中同样可用

1

op://vault/item/field

部分23

Doppler 内的 ${…} 引用;用于文件的 {{.NAME}} 模板

以环境变量形式注入机密并运行命令

值在输出中隐藏

4

op run,默认在输出中遮蔽值

56

doppler run;CLI 的输出遮蔽未见文档说明

从模板生成文件

以 0600 权限写入文件

7

op inject

3

secrets substitute 和 --mount

支持继承的环境

最多 3 层,按名称覆盖

部分8

有 Environments,彼此独立

910

branch configs 继承自根 config;Team 和 Enterprise 支持 config 继承

版本历史与回滚

回滚会创建新版本

11

条目历史与恢复

12

可从日志回滚

限定范围且带过期时间的机器令牌

只读,按项目和环境限定,必须设置过期时间

1314

service accounts,按 vault 设置权限,过期时间可选

15

service tokens 按 config 限定,过期时间可选

即时撤销令牌1615
通过 OIDC 接入 CI,无需存储令牌

GitHub Actions,15 分钟令牌

部分1718

load-secrets-action 使用存储的令牌;支持 OIDC 的 Credential Broker 处于公开预览阶段

196

service account identities,Team 和 Enterprise 套餐

同步到 GitHub Actions、Railway 和 Vercel

每次变更后执行;只写入,只删除自己写入的内容

部分820

Environments 可同步到 AWS Secrets Manager(beta);未找到 GitHub、Railway 和 Vercel

2122

GitHub、Vercel 和 Railway 集成会自动推送机密

定期轮换部分

为你自有的机密生成新的随机值;第三方密钥通过邮件提醒

公开文档中未找到2316

service account 令牌需手动轮换;未找到对已存储机密的定期轮换

24

在 Team 和 Enterprise 上自动轮换受支持的服务,例如数据库

角色与受保护的生产环境

所有者、管理员、开发者和读者;prod 受保护

258

vault 和 Environment 权限

26

项目和环境角色

每次机密读取的审计

谁、从哪里、版本和结果

27

1Password Business 中的使用报告

部分28

访问日志保留每个操作者的首次和最近一次读取

仅在已证明的设备上向移动应用交付

Attest 加 RASP,按会话加密

公开文档中未找到2930

在 SDK 和 Connect 文档中未找到

公开文档中未找到3121

在 SDK 和集成文档中未找到

1Password 的优势

  • 端到端加密,Secret Key 永远不会发送给 1Password。3233
  • op run 默认在命令输出中遮蔽机密的值。4
  • 提供 Go、JavaScript 和 Python 官方 SDK。29

Doppler 的优势

  • 有文档记载的云平台与 CI 平台原生集成列表。21
  • doppler run --mount 通过临时命名管道而不是磁盘上的文件提供机密。5
  • 每个 workplace 一个加密密钥,Enterprise 套餐还支持客户自管密钥(EKM)。3435

来源

  1. 1. 1Password CLI — Secret references · 核实于
  2. 2. Doppler — Secrets (referencing) · 核实于
  3. 3. Doppler — Secret injection with templates · 核实于
  4. 4. 1Password CLI — op run · 核实于
  5. 5. Doppler — Accessing secrets (run, --mount) · 核实于
  6. 6. Doppler — GitHub OIDC examples · 核实于
  7. 7. 1Password — Load secrets into config files (op inject) · 核实于
  8. 8. 1Password Environments · 核实于
  9. 9. Doppler — Branch configs · 核实于
  10. 10. Doppler — Config inheritance · 核实于
  11. 11. 1Password — View and restore previous versions of items · 核实于
  12. 12. Doppler — Versioning · 核实于
  13. 13. 1Password CLI — op service-account · 核实于
  14. 14. 1Password CLI — op connect · 核实于
  15. 15. Doppler — Service tokens · 核实于
  16. 16. 1Password — Manage service accounts · 核实于
  17. 17. 1Password — GitHub Actions (load-secrets-action) · 核实于
  18. 18. 1Password Credential Broker — GitHub Actions (public preview) · 核实于
  19. 19. Doppler — Service account identities (OIDC) · 核实于
  20. 20. 1Password — Sync Environments to AWS Secrets Manager (beta) · 核实于
  21. 21. Doppler — Integrations · 核实于
  22. 22. Doppler — GitHub Actions integration · 核实于
  23. 23. 1Password Secrets Automation · 核实于
  24. 24. Doppler — Secrets rotation · 核实于
  25. 25. 1Password — Create, share, and manage vaults · 核实于
  26. 26. Doppler — Project permissions · 核实于
  27. 27. 1Password — Reports (usage reports) · 核实于
  28. 28. Doppler — Access logs · 核实于
  29. 29. 1Password SDKs · 核实于
  30. 30. 1Password Connect · 核实于
  31. 31. Doppler — Future SDKs and integration roadmap · 核实于
  32. 32. 1Password — About the 1Password security model · 核实于
  33. 33. 1Password — About your Secret Key · 核实于
  34. 34. Doppler — Security fact sheet · 核实于
  35. 35. Doppler — Pricing · 核实于

1Password 和 Doppler 是其各自所有者的商标,此处提及仅为标识所比较的产品。我们对它们的描述来自所示日期的公开文档。“未找到”表示我们在所引用的页面中没有找到,并不代表该产品不具备。如有变化,请联系我们,我们会更正。

套餐

Vault 包含在 Startup、Scale 和 Enterprise 套餐中。

套餐每个组织的项目数每个环境的机密数
Startup5100
Scale50500
Enterprise2001,000
查看所有套餐

常见问题

使用 Vault 需要修改代码吗?

在服务器和 CI 上不需要:你的代码照常读取环境变量,只需用 moatgator secrets run 或 GitHub Action 启动进程。在 Android 应用中,用引用调用 Moatgator.vault.get。

拿到我的 APK 的人能读取 Vault 中的机密吗?

值不在 APK 中。API 只会把它发送给按该机密策略通过 Attest 的设备,并针对该会话加密,SDK 也只在内存中保存它。设备在通过检查后仍可能被攻破,因此凡是涉及资金流动的操作,请保留服务器端检查。

服务令牌泄露了怎么办?

在控制台中撤销它,下一次请求就会被拒绝。服务令牌为只读,仅限一个项目和你选择的环境,默认 90 天后过期。

Vault 会取代 1Password 或 Doppler 吗?

不一定。如果你已经在服务器和 CI 上使用其中之一,可以继续使用。Vault 增加了在已证明设备上向移动应用交付机密的能力;如果你更想只用一个工具,它也能覆盖服务器和 CI。

哪些套餐包含 Vault?

Startup、Scale 和 Enterprise。每个组织的项目数:5、50 和 200。每个环境的机密数:100、500 和 1,000。

从一个机密开始

创建一个项目,添加一个机密,然后通过 CLI、你的 CI 或你的应用来解析它。