Skip to content

davidalmeidac/sealed-env

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

117 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
sealed-env

Stop committing .env files. Stop hoping a leak doesn't happen.

A cross-stack, zero-trust secret management library for Node.js and Java/Spring Boot โ€” with optional TOTP-based unsealing for production deploys.

npm version Maven Central Node CI Java CI License Threat model CVE-2026-45091

Docs ยท Threat Model ยท File Format ยท Security Policy ยท Landing


Why this exists

In 2025 alone, supply-chain attacks on the JavaScript ecosystem stole thousands of plaintext secrets from CI/CD pipelines and developer machines. The Shai-Hulud worm (November 2025) compromised over 25,000 repositories by scanning for .env files and exfiltrating their contents to public GitHub repos. On May 12, 2026, TeamPCP open-sourced the full framework on GitHub; clones appeared within 48 hours.

The lesson is simple: plaintext .env is dead. And encrypted-at-rest alone isn't enough โ€” if the master key leaks (and they do โ€” see the tj-actions and GhostAction campaigns), the entire vault opens.

sealed-env solves both halves: it encrypts your secrets at rest, and it can require a fresh TOTP code from a human operator before each production deploy. Even if your CI pipeline is fully compromised, attackers cannot decrypt without the operator's phone.

Honest scope claim: sealed-env reduces the impact of Shai-Hulud-class supply-chain attacks by keeping master keys out of disk and process.env when configured with sealed-env keychain push and enterprise mode + short-TTL unseal tokens. It does not prevent the initial compromise of a developer machine or CI runner. Full per-module analysis: threat-research/analysis/shai-hulud-defense.md. Run sealed-env doctor for an automated posture check.

What you get

  • A .env.sealed file format that's identical across Node and Java. Mix stacks freely.
  • Three security modes the user picks: basic for dev, team for staging, enterprise for production with TOTP unseal.
  • Zero runtime dependencies in the Node package. Only Node's built-in crypto and fs.
  • A published threat model that says exactly what we defend against and what we don't.
  • A CLI (npx sealed-env) and a Spring Boot starter (Java).

Cross-stack architecture

   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Node side              โ”‚         โ”‚  Java side              โ”‚
   โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€           โ”‚         โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€           โ”‚
   โ”‚  โ€ข CLI: sealed-env seal โ”‚         โ”‚  โ€ข SealedEnv core lib   โ”‚
   โ”‚  โ€ข npm: sealed-env      โ”‚         โ”‚  โ€ข Spring Boot starter  โ”‚
   โ”‚  โ€ข writes KDF=scrypt    โ”‚         โ”‚  โ€ข writes KDF=argon2id  โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ”‚                                   โ”‚
                โ”‚  both speak SEALED-ENV-V1         โ”‚
                โ”‚  (byte-for-byte spec compliance)  โ”‚
                โ–ผ                                   โ–ผ
            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
            โ”‚            .env.sealed                 โ”‚
            โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€           โ”‚
            โ”‚  SEALED-ENV-V1 MODE=team               โ”‚
            โ”‚  KDF=<scrypt|argon2id>                 โ”‚
            โ”‚  KDF-PARAMS=...   SALT=...             โ”‚
            โ”‚  NONCE=...        AAD-DIGEST=...       โ”‚
            โ”‚  HMAC=...         CREATED=2026-...     โ”‚
            โ”‚                                        โ”‚
            โ”‚  <base64 ciphertext + GCM tag>         โ”‚
            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ–ฒ                                   โ–ฒ
                โ”‚       a file written by one       โ”‚
                โ”‚       stack decrypts in the       โ”‚
                โ”‚       other โ€” no conversion       โ”‚
                โ”‚                                   โ”‚
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Node app reads it      โ”‚         โ”‚  Java app reads it      โ”‚
   โ”‚  (loadSealed())         โ”‚         โ”‚  (Spring Environment)   โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Verify the install

From 0.2.1 onwards, every npm release ships with SLSA Build Level 3 provenance signed via Sigstore through GitHub Actions trusted publishing. After installing, you can confirm that the tarball was built from the source we publish (not from a compromised pipeline):

npm audit signatures sealed-env

Expect output that includes verified for sealed-env with a signature link to a Sigstore transparency log entry. If the command reports anything else, do not run sealed-env โ€” open an issue first.

This is a real check, not a marketing pixel: the TanStack supply-chain attack of May 2026 published malicious packages with valid-looking SLSA Build Level 3 provenance, so provenance alone is insufficient. But combined with version pinning + release-age cooldowns (pnpm 11 minimumReleaseAge: 24h or yarn npmMinimalAgeGate: 3d), it's a meaningful defensive layer.

30-second tour (Node)

# 1. Install
npm install sealed-env

# 2. Initialize a vault for your project
npx sealed-env init
# โ†’ generates a master key (saved locally to .env.local, gitignored)
# โ†’ if you choose 'enterprise' mode, also displays a QR code for your authenticator

# 3. Encrypt your existing .env
npx sealed-env encrypt .env
# โ†’ creates .env.sealed (commit this!)

# 4. Use it in code โ€” no API change
import 'sealed-env/config';
console.log(process.env.STRIPE_API_KEY);  // works as if it were a normal .env

30-second tour (Spring Boot)

<dependency>
    <groupId>io.github.davidalmeidac</groupId>
    <artifactId>sealed-env-spring-boot-starter</artifactId>
    <version>0.1.0</version>
</dependency>
# application.yml
sealed-env:
  file: .env.sealed
  key-source: env
@Value("${stripe.api.key}")  // resolved transparently from .env.sealed
private String stripeKey;

The three modes โ€” visualized

   basic                    team                     enterprise
   โ”€โ”€โ”€โ”€โ”€                    โ”€โ”€โ”€โ”€                     โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

   .env.sealed              .env.sealed              .env.sealed
        โ”‚                        โ”‚                        โ”‚
        โ–ผ                        โ–ผ                        โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚ AES-GCM โ”‚              โ”‚  HMAC   โ”‚              โ”‚  HMAC   โ”‚
   โ”‚ decrypt โ”‚              โ”‚ verify  โ”‚              โ”‚ verify  โ”‚
   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
        โ”‚                        โ–ผ                        โ–ผ
        โ–ผ                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   plaintext                โ”‚ AES-GCM โ”‚              โ”‚  TOTP   โ”‚
                            โ”‚ decrypt โ”‚              โ”‚  token  โ”‚
                            โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜              โ”‚ verify  โ”‚
                                 โ–ผ                   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
                            plaintext                     โ–ผ
                                                     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ–ฒ                        โ–ฒ                        โ”‚ deploy  โ”‚
   โ”‚ master_key             โ”‚ + signing_key          โ”‚  bind   โ”‚
                                                     โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
                                                          โ–ผ
                                                     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                                     โ”‚ AES-GCM โ”‚
                                                     โ”‚ decrypt โ”‚
                                                     โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
                                                          โ–ผ
                                                     plaintext

                                                     โ–ฒ
                                                     โ”‚ + unseal token (carries
                                                     โ”‚   salt-bound TOTP epoch)
                                                     โ”‚ + deploy_id

The three modes

basic team enterprise
AES-256-GCM cipher โœ“ โœ“ โœ“
Argon2id key derivation โœ“ โœ“ โœ“
HMAC integrity tag โ€” โœ“ โœ“
TOTP unseal required โ€” โ€” โœ“
Deploy-bound unseal tokens โ€” โ€” โœ“
Replay protection โ€” โ€” โœ“
Memory wipe after read โœ“ โœ“ โœ“
Host-side decrypt (deploy --remote) โœ“ โœ“ โœ“
Suitable for personal projects staging, small teams production, fintech, PII

Pick the one that fits your threat model. Upgrade later with one command:

npx sealed-env upgrade --to enterprise

How enterprise mode works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  1. push     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   developer  โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ โ”‚   github     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                     โ”‚ 2. CI runs
                                     โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚  CI pipeline โ”‚  paused, waiting for unseal
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                     โ”‚
                                     โ”‚ 3. notifies operator
                                     โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚   operator   โ”‚  4. opens authenticator app,
                              โ”‚   (you)      โ”‚     reads 6-digit TOTP code
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                     โ”‚
                                     โ”‚ 5. runs:
                                     โ”‚    sealed-env unseal --totp 482914 \
                                     โ”‚      --deploy-id <commit-sha>
                                     โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ unseal token (60s lifetime, bound to โ”‚
                              โ”‚ this specific deploy)                โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                     โ”‚ 6. paste into CI form
                                     โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ deploy runs  โ”‚  decrypts .env.sealed
                              โ”‚ to prod      โ”‚  with master_key + token
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

If the master key leaks AFTER the deploy โ†’ attacker still needs the operator's
TOTP. If the TOTP token leaks โ†’ useless for the next deploy (different commit).

How it compares

The honest version. Different tools for different threat models โ€” pick the one that matches yours.

sealed-env dotenv dotenvx Doppler HashiCorp Vault AWS Secrets Manager jasypt
Encryption at rest โœ… โŒ plaintext โœ… โœ… โœ… โœ… โœ…
Cross-stack (Node + Java) โœ… same wire format n/a Node only language-agnostic (HTTP) language-agnostic (HTTP) language-agnostic (HTTP) Java only
No external service required โœ… โœ… โœ… โŒ paid SaaS โŒ self-hosted server โŒ AWS โœ…
TOTP unseal at deploy time โœ… โŒ โŒ โŒ โš ๏ธ via plugin โŒ โŒ
Replay protection (deploy-bound tokens) โœ… โŒ โŒ โŒ โš ๏ธ partial โŒ โŒ
Public threat model โœ… n/a partial NDA only โœ… โœ… โŒ
Zero runtime dependencies (Node) โœ… โœ… โŒ (8+ deps) โŒ SDK โŒ SDK โŒ SDK n/a
Spring Boot autoconfiguration โœ… n/a n/a community community community manual
Memory wipe after key derivation โœ… n/a โŒ โŒ โŒ โŒ โŒ
License MIT MIT MIT proprietary MPL 2.0 proprietary Apache 2.0
Cost free free free $0โ€“$15/user/mo free / Enterprise $ $0.40/secret/mo free

When to pick which

  • dotenv โ€” solo dev, dev environment only, never production. Fine.
  • dotenvx โ€” Node-only project, encryption at rest is enough, you trust your CI keystore. Fine.
  • Doppler / AWS Secrets Manager โ€” you already pay for the platform, comfortable with vendor lock-in, want centralized rotation across many services. Good.
  • HashiCorp Vault โ€” you have ops capacity to run a Vault cluster, need fine-grained policies, and dynamic secrets (DB credentials per session). Heavy but powerful.
  • jasypt โ€” Java-only project, encryption at rest is enough, you don't need cross-stack. Fine.
  • sealed-env โ€” you want encryption at rest + a hard floor against compromised CI/CD (TOTP-bound deploys), no external service, and your stack is Node, Java/Spring Boot, or both. The defense ceiling is higher than dotenvx/jasypt; the operational cost is lower than Vault.

What sealed-env is not

  • Not a centralized secret manager (no rotation API, no audit log, no team policies).
  • Not a substitute for HashiCorp Vault when you need dynamic per-session credentials.
  • Not a fit if you want a SaaS dashboard.

If your team needs the Doppler/Vault feature set, use them. sealed-env is the right pick when you want a static, file-based, version-controllable encrypted secret with a higher security floor than dotenvx.

Runnable examples

Pre-sealed apps you can clone and run in 60 seconds:

The demo master key is checked in alongside each example so the apps work out of the box. It's public โ€” never use it in real projects.

Companion: sealed-env Studio (pre-alpha)

A desktop GUI on top of sealed-env, for the people who don't live in the terminal. Built with Tauri 2 + React + TypeScript, with its own Rust implementation of SEALED-ENV-V1 โ€” the third stack alongside Node and Java, validated against the same cross-stack test vectors.

What works today:

  • Viewer โ€” open a .env.sealed file, unlock with master / signing / TOTP, browse and mask values.
  • Init wizard โ€” 5-step flow (folder โ†’ mode โ†’ source โ†’ keys โ†’ review) for basic, team, and enterprise. Auto-detects .env, .env.example, .env.sample, .env.template, .env.dist. QR code for enterprise authenticator pairing. Auto-appends .env to .gitignore.
  • Recent projects + settings panel (default mode, gitignore toggle, value masking, Argon2id parameter tuning).

Still pre-alpha โ€” looking for testers and contributors. The Rust core reads files sealed by the Node CLI and Java library byte-for-byte (validated by decrypts_node_enterprise_vector and friends in CI).

โ†’ github.com/davidalmeidac/sealed-env-studio

Documentation

โ†’ Full documentation index โ€” start here if you're new.

Getting started

Operations

  • ๐Ÿ› ๏ธ Operational guide โ€” for sysadmins, managers, and founders (no code)
  • โ˜๏ธ CI/CD + cloud recipes โ€” GitHub Actions, GitLab, Bitbucket, CircleCI, Jenkins, Azure, AWS, GCP, Vercel, Railway, Docker, K8s
  • ๐Ÿ”„ Project lifecycle โ€” init โ†’ onboarding โ†’ deploy as one narrative
  • ๐ŸŽฏ Decrypt strategies โ€” host-side vs in-process trade-off
  • ๐Ÿšจ Incident response โ€” playbook for a compromised host (โš  deadman switch warning)

Reference

Threat research

Independent security coverage

CVE-2026-45091 was responsibly self-disclosed and patched in 0.1.0-alpha.4. The disclosure has been independently indexed and analyzed by:

Source What it is
NIST NVD Official US National Vulnerability Database entry (CVSS 9.1, CWE-200 + CWE-522)
CVE.org Canonical CVE record
GitHub Security Advisory GHSA-x3r2-fj3r-g5mv (our advisory)
CVEReports Independent technical analysis by Alon Barad (Software Engineer)
DailyCVE Independent technical writeup
CIRCL Vulnerability-Lookup European tracking (Luxembourg CERT)
Sploitus Exploit feed aggregator entry
HORKimhab/CVE-2026-45091 Third-party reproducible PoC published for research

We list these because verifiable third-party coverage is part of a healthy disclosure track-record. The CVE itself is a fixed bug, not a current defect โ€” see the advisory for the full timeline and remediation steps.

Project status

v0.1.0 โ€” stable. The wire format (SEALED-ENV-V1) is frozen and will remain readable forever. The public API is stable. Bug-fix and non-breaking feature releases land as 0.1.x; breaking changes wait for 0.2.0.

What's in 0.1.0:

  • Three modes: basic, team, enterprise (TOTP-bound deploys)
  • Node CLI (init, encrypt, decrypt, get/set/edit/diff, exec, deploy, keychain)
  • deploy --remote for Model A host-side decrypt deploys
  • Cross-stack: Node + Java libraries reading the same wire format
  • Spring Boot 3 starter (auto-config + @Value support)
  • OS keychain backend (Windows DPAPI, macOS Keychain, Linux secret-tool)
  • 17 platform CI/CD recipes including OIDC federation
  • Cryptographic test vectors validated cross-stack in CI

Roadmap:

  • v0.1.x โ€” sealed-env doctor + install-hooks + library-side .env.local autoload (non-breaking)
  • v0.2.0 โ€” Java CLI (Maven-distributed) ยท Shamir Secret Sharing ยท sidecar pattern
  • v0.3.0 โ€” memfd_secret Linux memory protection ยท heap-dump filter
  • v1.0 โ€” Hardware-backed wrapping (TPM / Secure Enclave / YubiKey)

Companion projects:

  • sealed-env-studio โ€” desktop GUI (Tauri + React + Rust), Phase 1 viewer + Phase 2 init wizard implemented, cross-stack interop validated, pre-alpha

Contributing

This is a security-sensitive project. Contributions are very welcome but please read SECURITY.md first. Crypto changes require explicit discussion.

License

MIT โ€” David Almeida, 2026.


Built openly in Bucaramanga, Colombia.
"Encrypt at rest. Authenticate at deploy. Wipe on read."

About

Encrypted .env files with TOTP unsealing for production deploys. Cross-stack (Node + Java). Zero deps. Defends against npm supply-chain attacks.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors

โšก