我们正在将 dotenvy 分叉为 dotenv-ng
摘要
SecretSpec 发布了 dotenv-ng,这是 dotenvy 的一个现代 Rust 分叉版,旨在修复诸如 bcrypt 片段等秘密的解析问题,并处理 .env 文件处理中的维护缺口。
暂无内容
查看缓存全文
缓存时间: 2026/08/17 18:54
# 我们正在将 dotenvy 分叉为 dotenv-ng
来源:https://secretspec.dev/blog/we-are-forking-dotenvy-into-dotenv-ng/
我们发布了 `dotenv-ng` (https://github.com/cachix/dotenv-ng) 1.0,这是一个用于加载和渲染 `.env` 文件的现代化 Rust 实现。它最初是从 `dotenvy` (https://github.com/allan2/dotenvy) 分叉而来,因为后者在解析器读取文件时修改了一个秘密值。
这听起来可能有些矛盾。SecretSpec 仍然致力于消除环境变量作为秘密接口 (https://secretspec.dev/blog/secrets-dont-belong-in-config/),并且我们已经撰文讨论过 `.env` 方式错在何处 (https://secretspec.dev/blog/where-env-went-wrong/)。它不应该成为秘密的最终存储位置。
但要从 `.env` 迁移出去,首先需要正确地读取它。
## 为什么分叉 dotenvy?
标题为“为什么分叉 dotenvy?”的部分 (https://secretspec.dev/blog/we-are-forking-dotenvy-into-dotenv-ng/#why-fork-dotenvy)
直接的失败原因是 SecretSpec 问题 #73 (https://github.com/cachix/secretspec/issues/73)。一个 dotenv 文件包含了一个带有 bcrypt 片段的值:
``
TEST="foo:$2a$10$TWoviNHS27HJMw1PKe4tBeIMlms6tWdYS9hKoHANKCQhluDlEt/gu"
``
文件本身是完好的。通过 dotenv 提供程序读取它时返回了不同的值,因为 `dotenvy` 将 `$` 前缀的片段视为变量替换。失败后来表现为一个认证错误,而不是解析错误。
一个上游的、旨在使替换可配置的请求自 2024 年起就已开放 (https://github.com/allan2/dotenvy/issues/113)。一个拉取请求 (https://github.com/allan2/dotenvy/pull/167) 在 2026 年才到达,但其目标是一个未发布的 API。迁移工具不能要求用户识别并转义他们秘密值内部的解析器语法。
## 维护空窗期
标题为“维护空窗期”的部分 (https://secretspec.dev/blog/we-are-forking-dotenvy-into-dotenv-ng/#the-maintenance-gap)
最初的 Rust `dotenv` crate 在 2020 年停止发布,并最终被 RustSec (https://rustsec.org/advisories/RUSTSEC-2021-0141.html) 标记为 un维护,后者将 dotenvy 列为替代方案。
Dotenvy 的描述仍然称其为“一个维护良好的分叉”。其最新发布的版本 0.15.7 发布于 2023 年 3 月 22 日 (https://github.com/allan2/dotenvy/releases/tag/v0.15.7)。一个 Rust 论坛讨论 (https://users.rust-lang.org/t/recommended-crate-for-storing-keys-for-web-site-database/133305/11) 在 2025 年注意到了这个两年的发布间隔。当 bcrypt 漏洞阻碍 SecretSpec 时,这个间隔已超过三年。
一个维护中的分叉重复其上游的发布问题,这其中存在着令人不适的讽刺。其维护者没有义务为我们发布新版本,但 SecretSpec 需要在我们控制的时间表内获得关键修复。
## dotenv-ng 改进了什么?
标题为“dotenv-ng 改进了什么?”的部分 (https://secretspec.dev/blog/we-are-forking-dotenvy-into-dotenv-ng/#what-does-dotenv-ng-improve-upon)
我们最初考虑使用一个小补丁。审计解析器发现了更多围绕 JSON、Windows 路径、Unicode 名称、优先级以及部分环境变更方面的问题。
因此,`dotenv-ng` 从 dotenvy 0.15.7 开始,但在正确性要求时故意打破兼容性。1.0 版本新增了:
- 带有结构化错误的、源感知的解析器;
- 默认使用字面美元符号,仅在调用者明确启用时才进行替换;
- 支持破折号、前导数字、前导点和 Unicode 的更广泛键语法;
- 仅添加解析回原始值所需的引号和转义的渲染器;
- 进程环境变更前的验证;以及
- 围绕该变更的明确 `unsafe` 边界。
属性测试演练任意 Unicode 和语法密集型值,检查引号仅在必要时使用,并对完整文档进行往返测试。解析器和渲染器作为重写的核心,均达到了 100% 的行覆盖率。
完整的兼容性和 API 变更记录在 `dotenv-ng` 1.0 的变更日志 (https://github.com/cachix/dotenv-ng/blob/v1.0.0/CHANGELOG.md) 中。
## 尝试 dotenv-ng 1.0
标题为“尝试 dotenv-ng 1.0”的部分 (https://secretspec.dev/blog/we-are-forking-dotenvy-into-dotenv-ng/#try-dotenv-ng-10)
该包已在 crates.io (https://crates.io/crates/dotenv-ng) 上架。应用程序可以通过依赖别名继续使用熟悉的 `dotenv` crate 名称:
``
[dependencies]dotenv = { package = "dotenv-ng", version = "1" }
``
从 SecretSpec 0.20 开始,dotenv-ng 将为整个 SecretSpec 提供 dotenv 解析和渲染功能。
相似文章
.env 错在哪里
一篇技术分析,探讨 .env 文件为何在缺乏模式、规范和安全语义的情况下仍成为事实上的配置标准,以及为什么团队应该用更持久的声明来取代它们。
SecretSpec 0.13:面向 Python、Node.js、Go、Ruby 和 Haskell 的 SDK
SecretSpec 0.13 发布了针对 Python、Node.js/TypeScript、Go、Ruby 和 Haskell 的原生 SDK,使应用程序能够直接解析 secretspec.toml 中声明的机密,而无需依赖 CLI。
envfix
envfix 是一个用于 Node.js 项目的小型 .env 修复工具,帮助修复和管理环境变量文件。
人人都该从 npmx 偷学的功能
npmx 是一个 MIT 授权的 npm 仓库替代前端,它在安全与可用性上做了增强:展示传递式安装体积、暴露安装脚本、可视化过期/含漏洞依赖树,还逼得 npmjs.com 终于上线了深色模式。
dani-garcia/vaultwarden
Vaultwarden 是一个替代的、轻量级的 Bitwarden API 服务器实现,用 Rust 编写,专为高效的自托管部署设计。