Process Architecture
envtrap splits responsibilities across two Node.js process execution boundaries: the Parent CLI Process and the Monitored Child Process.
This strict separation ensures that security policies, decryption keys, and stream scanners remain isolated from untrusted application dependencies.
Process Boundary Division
Parent CLI Process
- Supervisor: Spawns and manages the lifetime of your application.
- In-Memory CA: Generates an ephemeral 2048-bit RSA Root Certificate Authority in RAM.
- MITM Proxy: Binds an HTTP server to
127.0.0.1and intercepts outbound HTTP/HTTPS connections. - Stream Redactor: Scans child
stdoutandstderrstreams, replacing secrets with SHA-256 hashes. - IPC Coordinator: Receives out-of-band IPC alerts from runtime hooks.
- Incident Reporting: Writes run summaries and
.envtrap-report.json.
Monitored Child Process
- Application Execution: Runs your code (
node app.js, Express, NestJS, Next.js). - Hook Injection: Loads
hooks.mjsbefore user code viaNODE_OPTIONS="--import hooks.mjs". - Virtual Modules: Intercepts
node:child_processandnode:dnsimports. - CJS Monkeypatching: Proxies CommonJS
require()calls to intercept legacy modules. - Runtime Proxy: Wraps
process.envin a JavaScript Proxy to catch rotated secrets. - MessagePort Sync: Communicates dynamic secret rotations back to the ESM loader thread.
Inter-Process Communication (IPC)
Because Node.js ESM customization hooks execute in an isolated loader thread and cannot block synchronous code, communicating alerts back to the parent CLI must occur out-of-band.envtrap establishes two communication paths:
1
Loader Thread to Main Thread (MessageChannel)
During startup,
hooks.mjs creates a Node.js MessageChannel and transfers one port to the loader thread via module.register(). When secrets are added to process.env at runtime, the main thread broadcasts updates to the loader thread over this channel.2
Child Process to Parent CLI (Stderr Protocol)
When a virtual hook (such as The parent CLI interceptor parses this line, triggers the configured policy (
node:dns or node:child_process) detects an exfiltration attempt, it writes a structured line to process.stderr:block or warn), records the incident, and removes the internal message so user-facing error logs remain clean.