The secrets module provides the public API and implementation for managing dotenv secret files with
SOPS and age. It encrypts plaintext .env files to .env.enc, decrypts .env.enc files back to
.env materialized files, verifies required external tooling, securely removes decrypted material,
and runs the deploy pipeline that decrypts, generates stack compose data, renders environment
substitutions, deploys with Docker, and cleans up decrypted files.
- External command adapter: all subprocess calls use the
ProcessRunnerinterface, withRealProcessRunneras the default and injectable runners for tests or callers. - Result objects over thrown errors for operational steps: encrypt, decrypt, clean, and deploy
return structured success, warning, and error values. Tooling enforcement is the exception, where
ensureToolingthrows on missing dependencies. - SOPS-owned key resolution: encryption and decryption invoke SOPS with dotenv input and output
types, and do not pass age recipients or key paths. SOPS resolves age configuration from its own
config, typically
.sops.yaml. - Best-effort cleanup: decrypted files are removed with
shred -ufirst, thenrm -fas a fallback when shredding fails or is unavailable. - Dry-run propagation: the deploy pipeline records intended mutations as warnings, and cleanup returns the files that would be removed without deleting them.
- Tooling checks call
runner.which("sops")andrunner.which("age"); status checks also call<tool> --versionthroughrunner.runand capture the first stdout line. - Encryption accepts a plaintext source path, verifies it exists, derives
<source>.enc, then runssops --encrypt --input-type dotenv --output-type dotenv --output <source>.enc <source>. - Decryption accepts an encrypted source path, strips the
.encsuffix for the plaintext output path, verifies the encrypted file exists, then runssops --decrypt --input-type dotenv --output-type dotenv --output <plainPath> <source>. - Discovery walks the working directory and collects files named
.env.encor.env.example, skipping.git,.rendered, andnode_modules. - The deploy pipeline discovers
.env.encfiles, decrypts each one, derives affected stack names from each encrypted file parent directory, resolves stack configuration, discovers compose files, generates in-memory stack YAML, renders${VAR}placeholders against the repository context, deploys each rendered stack with Docker, and finally cleans up every materialized.envfile. - Cleanup iterates materialized env files and invokes
shred -u <path>through the runner. If that command does not succeed, it invokesrm -f <path>through the same runner.
Age key generation is not implemented in this module. The code checks for the age binary but does
not invoke age-keygen, create key files, or manage recipient material directly.
index.tsre-exports the public types and functions fromtypes.tsandmod.ts.types.tsdefines deploy, tooling, encryption, decryption, and cleanup result contracts.../process/types.tssuppliesProcessRunner;../process/runner.tssuppliesRealProcessRunnerfor command execution.@std/fssuppliesexistsandwalkfor source validation and repository traversal.../config/mod.tsprovidesresolveConfigfor pipeline configuration and repository root resolution.../compose/mod.tsprovides compose discovery and in-memory stack generation.../render/mod.tsprovidesrenderStackfor environment interpolation before deployment.../docker/mod.tsprovidesdockerStackDeployfor stack deployment.@std/yamlparses generated YAML before rendering and stringifies rendered compose data into a temporary deployment file.