SecretSpec lanza dotenv-ng, dice que dotenvy cambió una credencial bcrypt
La bifurcación de Domen Kozar otorga a SecretSpec control sobre las correcciones y los lanzamientos del analizador utilizado en su ruta de migración de credenciales.
By RuntimeWire Staff · Published
Primary source: SecretSpec
Why it matters
Migration tooling cannot safely move credentials out of `.env` files if the parser changes them first. The fork gives SecretSpec control over a dependency inside its security boundary.

Domen Kozar, el fundador de Cachix, lanzó dotenv-ng 1.0 después de que SecretSpec descubriera que el analizador en Rust dotenvy que usaba podía cambiar silenciosamente una credencial mientras leía un archivo .env.
El lanzamiento del 15 de agosto pasó de un error estrecho a una decisión sobre el control de dependencias. En el anuncio de Kozar, SecretSpec dijo que la nueva biblioteca comenzó como un fork de dotenvy 0.15.7. SecretSpec inicialmente consideró aplicar un parche pequeño, pero luego encontró suficientes problemas relacionados con JSON, rutas de Windows, nombres Unicode, precedencia y la mutación del entorno del proceso como para justificar una reescritura incompatible (breaking) para la versión 1.0.
Kozar ha pasado gran parte de su carrera suavizando los bordes filosos de la infraestructura para desarrolladores. Estudió telecomunicaciones en la University of Ljubljana, participó en Google Summer of Code de 2010 a 2012 y comenzó a contribuir a Nix en 2012. Según la historia de Cachix, inició la consultoría de Nix Enlambda en 2016 y lanzó Cachix en 2018 para facilitar las compilaciones reproducibles y la distribución de software para equipos de ingeniería. Calm Company Fund anunció una inversión en Cachix en mayo de 2020. La biografía de Kozar proporciona información adicional sobre su trabajo antes de Cachix.
El analizador convirtió una credencial en otra cadena
El fallo que desencadenó el fork fue documentado en SecretSpec issue #73, abierto el 17 de abril. Un archivo de prueba .env contenía fragmentos de bcrypt que empezaban con campos con prefijo de dólar como $2a$10. El archivo en sí estaba intacto, pero dotenvy interpretó esos fragmentos como sustituciones de variables.
El ejemplo que reproduce el problema muestra que el valor cargado pierde piezas de las cadenas bcrypt. SecretSpec encontró el daño más tarde como una falla de autenticación, lo que desvió la investigación del analizador que lo había causado. El analizador devolvió un valor sintácticamente válido, por lo que no hubo un error de parseo inmediato que señalara a los desarrolladores la falla real.
Ese modo de fallo conlleva más riesgo que un rechazo claro. Un error visible detiene la ejecución cerca de su causa. Un token, contraseña o hash modificado silenciosamente puede viajar dentro de una aplicación y fallar en una base de datos, un servicio de autenticación o una API externa, donde parece credenciales incorrectas o un error de configuración.
El comportamiento ya era conocido en el proyecto upstream. Se abrió una solicitud en dotenvy para deshabilitar la sustitución el 29 de julio de 2024, con la advertencia de que los signos de dólar en los valores de entorno podrían desaparecer inesperadamente. Una pull request que añadía la opción llegó en 2026 y apuntaba a una API no publicada. Eso dejó a SecretSpec sin poder confiar en una versión publicada de dotenvy para una sustitución configurable. El repositorio aún identifica 0.15.7, lanzada el 22 de marzo de 2023, como su última versión publicada.
Un fork para controlar los lanzamientos
La cadena de dependencias de dotenv en Rust ya pasó por una entrega de mantenimiento. El crate original dotenv dejó de publicar en 2020, y RustSec lo clasificó como sin mantenimiento, señalando a los usuarios hacia dotenvy como alternativa.
Dotenvy se describe como un fork bien mantenido, pero su brecha de lanzamientos ya llevaba tres años cuando el bug bloqueó a SecretSpec. Kozar reconoció que los mantenedores de código abierto no le deben a los usuarios aguas abajo una versión. SecretSpec aún necesitaba "correcciones incompatibles en un calendario que controlamos".
Ese calendario es la razón estratégica de dotenv-ng. SecretSpec maneja credenciales que se mueven entre archivos locales, gestores de contraseñas y almacenes de secretos en la nube. Un analizador situado profundamente en esa ruta de migración puede convertirse en parte del perímetro de seguridad de SecretSpec incluso cuando lo mantenga otra persona. Hacer un fork convierte a Cachix en responsable del código, de las rupturas de compatibilidad y de la cadencia de lanzamientos.
El intercambio es una obligación de mantenimiento permanente. Cachix ahora debe seguir los cambios de Rust, los casos límite del analizador y los dialectos divergentes de .env. El README de dotenv-ng dice que el renderizado sigue la sintaxis de dotenv-ng y no promete compatibilidad con todos los dialectos de dotenv. Ese contrato más restringido le da a Kozar espacio para priorizar un parseo sin pérdidas sobre el comportamiento heredado.
Qué cambia dotenv-ng
Los signos de dólar son literales por defecto en dotenv-ng. Las aplicaciones que necesiten sustitución de variables deben habilitarla explícitamente. Eso revierte la suposición que causó la falla con bcrypt y protege contraseñas, hashes y tokens que contienen segmentos con prefijo de dólar.
La reescritura también introduce errores estructurados con información de la fuente, valida entradas completas antes de cambiar el entorno del proceso y coloca un límite explícito unsafe de Rust alrededor de la mutación del entorno. Su gramática acepta guiones, dígitos iniciales, puntos al inicio y Unicode en las claves, mientras que su renderizador añade solo el citadoado y el escape necesarios para que un valor sobreviva a un ciclo de parseo y renderizado.
SecretSpec dice que las pruebas de propiedades cubren Unicode arbitrario, valores con sintaxis compleja y documentos completos. Kozar también informa 100% de cobertura de líneas para el analizador y el renderizador. Esas son métricas de pruebas reportadas por el mantenedor más que evidencia de que cada dialecto de .env se parseará de forma idéntica, una distinción que las notas de compatibilidad dejan clara.
Las aplicaciones Rust pueden instalar dotenv-ng desde crates.io mientras conservan el familiar nombre de dependencia dotenv mediante un alias de Cargo. La biblioteca recomienda la carga no mutante para la mayoría de las aplicaciones y reserva la mutación del entorno para llamadas explícitas hechas antes de que se inicien hilos adicionales o un runtime asíncrono.
SecretSpec quiere controlar la rampa de salida
El fork encaja en una aparente contradicción del producto de SecretSpec. SecretSpec sostiene que las variables de entorno y los archivos .env son interfaces pobres a largo plazo para credenciales, y sin embargo ha invertido en un nuevo analizador de .env.
La página principal de SecretSpec lista 30 proveedores y nueve categorías de SDK por lenguaje, que abarcan llaveros locales, gestores de contraseñas, Vault, almacenes de secretos en la nube, SOPS, archivos .env y entornos de proceso. Los archivos .env existentes suelen ser el punto de partida para la adopción. Si SecretSpec interpreta mal esos archivos durante la importación o la ejecución, su modelo de migración más amplio falla antes de que una credencial alcance un proveedor más seguro.
Kozar está tratando .env como una rampa de salida. Poseer el analizador da a SecretSpec control sobre el primer y más propenso a errores paso: leer las credenciales existentes del usuario sin cambiarlas. A partir de SecretSpec 0.20, dotenv-ng se encargará del parseo y renderizado de dotenv en todo SecretSpec.
El lanzamiento también captura una decisión familiar de fundador en el open source. Una startup puede esperar un lanzamiento upstream, mantener un parche privado o aceptar la responsabilidad de un fork. Kozar eligió el fork porque la falla afectó material de credenciales y el calendario de lanzamientos upstream ya no coincidía con el de SecretSpec. La biblioteca resultante es pequeña, pero vuelve a colocar una dependencia importante bajo el control del fundador.