Build1 distinct publisher3 min readUpdated
SecretSpec's dotenv-ng 1.0 makes dollar signs literal after dotenvy silently dropped parts of a bcrypt hash. The damage surfaced as an authentication failure, far from the parser that caused it.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
Domen Kozar, the founder of Cachix, released dotenv-ng 1.0 on August 15 after SecretSpec found that dotenvy, the Rust .env parser it depended on, could silently change a credential while reading a file [1]. The consequence worth noting is not the bug itself but its category: a library that loads secrets is inside the security boundary of everything downstream of it, which makes its correctness a supply-chain property rather than a convenience choice [17].
The failure was documented in SecretSpec issue #73, opened on April 17 [3]. A test .env file contained bcrypt fragments beginning with dollar-prefixed fields such as $2a$10 [4]. The file on disk was intact, but dotenvy read those fragments as variable substitutions, and the issue's reproducer shows the loaded value losing pieces of the bcrypt strings [5]. There was no parse error, because the parser returned a syntactically valid value [7]. SecretSpec met the damage much later, as an authentication failure, which pointed the investigation away from the parser [6]. That is the expensive shape of a bug. A visible error stops execution near its cause; a quietly modified token, password or hash travels into a database, an auth service or a third-party API and presents as bad credentials or a misconfiguration [8].
The behavior was already known upstream. A dotenvy request to disable substitution was opened on July 29, 2024, warning that dollar signs in environment values could disappear unexpectedly [9]. A pull request adding the option arrived in 2026 but targeted an unreleased API, so no published dotenvy release offered configurable substitution [10]. The repository still identifies 0.15.7, released on March 22, 2023, as its latest published release [11]. That is roughly three years between the last shipped release and the arrival of the fix in unreleased form [2], and 0.15.7 is also the version dotenv-ng forked from, so the only paths available were an unpublished API or a fork [2][1].
This dependency chain has already been handed off once: the original dotenv crate stopped releasing in 2020 and RustSec classified it as unmaintained, pointing users toward dotenvy [12]. Dotenvy describes itself as a well-maintained fork, yet its release gap had passed three years by the time the bug blocked SecretSpec [13]. Kozar acknowledged that maintainers do not owe downstream users a release, but said SecretSpec needed "breaking fixes on a schedule we control" [14]. SecretSpec moves credentials among local files, password managers and cloud secret stores, so a parser in that path becomes part of its security boundary regardless of who maintains it [17].
SecretSpec first considered carrying a small patch, then found enough problems around JSON, Windows paths, Unicode names, precedence and process-environment mutation to justify a breaking 1.0 rewrite [15]. In dotenv-ng, dollar signs are literal by default and substitution must be enabled explicitly [18]. The rewrite adds source-aware structured errors, validates complete inputs before changing the process environment, and puts an explicit Rust unsafe boundary around environment mutation [19]. Its grammar accepts dashes, leading digits, leading dots and Unicode in keys [20]. The README does not promise compatibility with every dotenv dialect [21]. The cost is a standing obligation for Cachix, which launched in 2018 to make reproducible builds easier for engineering teams [22], to track Rust changes, parser edge cases and divergent .env dialects [16].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
Domen Kozar, the founder of Cachix, released dotenv-ng 1.0 on August 15 after SecretSpec found that the Rust dotenvy parser it used could silently change a credential while reading a .env file.
SecretSpec said the new library began as a fork of dotenvy 0.15.7.
The failure that triggered the fork was documented in SecretSpec issue #73, opened on April 17.
A test .env file contained bcrypt fragments beginning with dollar-prefixed fields such as $2a$10.
The .env file itself was intact, but dotenvy interpreted the bcrypt fragments as variable substitutions, and the issue's reproducer shows the loaded value losing pieces of the bcrypt strings.
SecretSpec encountered the damage later as an authentication failure, which sent the investigation away from the parser that caused it.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Concrete artifacts, one publisher, maintainer-sourced
The account rests on checkable artifacts: SecretSpec issue #73 with a reproducer, an upstream dotenvy request from July 2024, a 2026 pull request against an unreleased API, and published release dates including dotenvy 0.15.7 of March 22, 2023. It is nonetheless a single publisher retelling the maintainer's own announcement and README, with no upstream response, independent reproduction, or third-party validation of the reported test coverage.
Fresh 1.0 release, no external uptake evidence
Adoption evidence stops at existence: dotenv-ng 1.0 shipped on August 15 and is installable from crates.io with a Cargo alias, and its first known consumer is SecretSpec itself. The sources give no downloads, dependent counts, or any third-party project switching from dotenvy, while dotenvy remains the incumbent whose last published release is 0.15.7.
Framing runs slightly ahead of verified scope
The core technical finding is well grounded in a dated reproducer and in dotenvy's published release history, and the source itself flags that property tests and 100% line coverage are maintainer-reported. Mild overstatement comes from generalizing one library's substitution default into a broad secret-corruption risk while no independent reproduction, upstream comment, or adoption signal exists yet, and from the narrower compatibility contract that limits how far dotenv-ng can substitute for dotenvy.
Vendor announcement about a vendor-owned dependency
The narrative originates with Kozar and Cachix, a commercial company whose SecretSpec product benefits from controlling the .env import path, and the reporting reproduces that announcement, README and company history including the 2018 founding and prior outside investment. The fork also converts a criticism of an upstream project into a reason to adopt the vendor's own library, and no upstream or independent voice appears to balance it.
Verifiable specifics, single-publisher record
Dates, versions, issue numbers and behavioral changes are specific enough to be checked against public repositories, which supports moderate confidence in the technical core. Confidence is capped by a one-publisher, vendor-sourced record with no upstream rebuttal, no independent reproduction, and no adoption data on which to judge impact.
invest
Rust's arrayref hijack lasted 86 minutes, and Wiz ties it to North Korea1 distinct publisher
build
The only way to prove a contract test can fail is to ship a server that lies1 distinct publisher
build
The failure modes of AI agents in low-level code have names, and names can be gated in CI1 distinct publisher
build
Your agent needs the API call, not the API key1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
1 article · August 17, 2026