文章摘要
SecretSpec 是一种声明式的密钥管理工具,旨在解决传统 .env 文件在密钥管理中的问题,如应用与密钥分离、解析不明确、密码管理器集成困难、供应商锁定和缺乏加密等。尽管现有工具如 dotenvx 和 sops 提供了加密功能,但它们也带来了单密钥管理、信任需求和密钥轮换复杂性的新挑战。SecretSpec 通过更高效和安全的方式管理密钥,适用于大型团队和复杂环境。
文章总结
标题:宣布SecretSpec:声明式密钥管理 - devenv
主要内容:
我们之前支持通过.env文件管理密钥,但这种方式存在一些问题,如应用程序与密钥之间缺乏明确的契约、.env文件解析不清晰、密码管理器集成困难、供应商锁定以及缺乏加密等。虽然我们可以推荐像dotenvx或sops这样的解决方案来加密.env文件,但这些方案也带来了新的挑战,如单一密钥管理、信任要求和密钥轮换复杂性。
为了解决这些问题,我们创建了SecretSpec,并将其集成到devenv中。SecretSpec将密钥管理分为三个独立的关注点:
- WHAT - 应用程序需要哪些密钥?(如DATABASEURL, APIKEY)
- HOW - 密钥的要求(如是否必需、默认值、验证、环境)
- WHERE - 这些密钥存储在哪里?(如环境变量、Vault、AWS Secrets Manager)
通过分离这些关注点,应用程序可以在一个简单的TOML文件中声明所需的密钥。每个开发者、CI系统和生产环境都可以从他们首选的存储中提供这些密钥,而无需更改任何应用程序代码。
示例:一个规范,多个环境,不同的提供者
假设你提交了一个secretspec.toml文件,声明了应用程序所需的密钥。在不同的环境中,你可以使用不同的密钥提供者:
- macOS用户:使用Keychain存储密钥,通过
secretspec --provider keyring run -- cmd args命令获取。 - Linux用户:使用GNOME Keyring存储密钥,相同的命令仍然适用。
- 本地开发:仍然可以使用
.env文件。 - CI/CD:从GitHub Actions的环境变量中读取密钥。
- 生产环境:使用AWS Secret Manager提供密钥。
示例:从.env迁移到SecretSpec
- 本地开发:在
devenv.yaml中启用SecretSpec,并在devenv.nix中配置相关服务。 - CI/CD:在GitHub Actions的配置文件中,通过环境变量提供密钥。
- 生产环境:在Fly.io的配置文件中,通过环境变量提供密钥。
在应用程序中加载密钥
虽然secretspec run命令可以将密钥作为环境变量提供,但应用程序仍然不知道它需要哪些密钥。Rust SDK通过提供类型安全的访问方式,填补了这一空白。应用程序代码只需通过TOML文件声明所需的密钥,而无需指定密钥的来源。
未来展望
我们正在探索未来的工作流程功能,如无需关闭应用程序的密钥轮换、生成密钥和混合提供者等。
结语
让我们将密钥管理变得像包管理一样声明式。停止通过Slack分享.env文件,为开发者构建更好的工具。欢迎在我们的Discord社区分享你的想法,或在GitHub上提出问题。
作者:Domen
评论总结
对LastPass的负面评价
- 主要观点:LastPass存在多次安全漏洞,建议用户和集成者远离。
- 关键引用:
- "They've been breached at least seven times since 2011."
- "The net will be better off with fewer integrations to it."
对secretspec的质疑
- 主要观点:secretspec的CI/CD示例并不比简单的
.env文件管理更优,且同样存在信任和密钥轮换问题。 - 关键引用:
- "The CI/CD example strikes me as not obviously better than doing
cat > .env." - "Even with secretspec you would have to rotate dev secrets when someone is offboarded."
- "The CI/CD example strikes me as not obviously better than doing
- 主要观点:secretspec的CI/CD示例并不比简单的
对加密密钥提交到Git仓库的质疑
- 主要观点:提交加密密钥到Git仓库并未被广泛接受或鼓励。
- 关键引用:
- "When has this ever been allowed/encouraged/normalized?"
对密钥存储方式的疑问
- 主要观点:不清楚密钥在存储中如何引用,文档未明确说明。
- 关键引用:
- "It’s not clear to me how the secrets are referenced in storage."
对分散式密钥管理的批评
- 主要观点:分散式密钥管理可能导致混乱,建议采用集中式管理。
- 关键引用:
- "Giving each developer control and management of their own secrets is just begging for trouble."
- "Centralised secrets management or bust, IMO."
对密钥与配置分离的实践
- 主要观点:分离密钥与配置在实际操作中非常困难,且加密实现可能增加复杂性。
- 关键引用:
- "Splitting general config from secrets is practically extremely difficult."
- "Putting plaintext secrets in a file on disk adds minuscule risk compared to the additional complexity of adding encryption."
对secretspec的正面评价
- 主要观点:secretspec在应用端的处理方式优于其他工具,特别是Rust示例中的
secretspec_derive功能。 - 关键引用:
- "I really like this."
- "I love the additional secretspec_derive bit for the Rust example."
- 主要观点:secretspec在应用端的处理方式优于其他工具,特别是Rust示例中的
对Teller工具的推荐
- 主要观点:Teller是一个简单易用的替代工具,支持从远程服务获取密钥。
- 关键引用:
- "It's a standalone tool with YAML configuration, simple to use."
- "Whenever you run
$ teller run ...it fetches the data from the remote service."
对配置管理的深入讨论
- 主要观点:应将配置分为“静态”和“动态”,并采用基础设施即代码(IaC)模式,避免环境不一致性。
- 关键引用:
- "How do you specify configuration for development and production without running into inconsistency bugs?"
- "Use ephemeral infrastructure (the 'cattle' in 'pets vs cattle')."