> ## Documentation Index
> Fetch the complete documentation index at: https://envtrap.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Channels

> Detailed reference for each of the five monitoring channels and their enforcement modes.

## What Is a Channel?

A **channel** is a distinct path through which secrets can leave your Node.js process. envtrap monitors five channels, each independently configurable.

Each channel is set to one of three modes in `envtrap.json`:

| Mode      | Effect                                                                  |
| --------- | ----------------------------------------------------------------------- |
| `"block"` | Prevents the operation and throws an error or kills the process         |
| `"warn"`  | Logs the detection and redacts output, but allows execution to continue |
| `"off"`   | Disables all monitoring for this channel                                |

***

## `network` — Outbound HTTP/HTTPS

**Default mode**: `"block"`

envtrap starts a local **MITM TLS proxy** on `127.0.0.1` at a random port and routes all child process HTTP/HTTPS traffic through it. This allows envtrap to decrypt, inspect, and optionally block outbound requests.

**What is scanned**:

* Request URL/path
* All request headers
* Request body (up to 1 MB)
* Response data (scanned inline, upstream connection dropped on block)

**Domain exclusions** — bypass scanning for specific trusted hosts:

```json theme={null}
{
  "channels": { "network": "block" },
  "exclusions": { "domains": ["api.stripe.com", "api.openai.com"] }
}
```

**Block behaviour**:

* Plain HTTP: `403 Forbidden` response
* HTTPS CONNECT: socket is destroyed, client receives connection error

**Disable MITM entirely** (fastest startup, no network scanning):

```bash theme={null}
envtrap run --no-mitm node app.js
```

or set in config:

```json theme={null}
{ "channels": { "network": "off" } }
```

***

## `stdout` — Standard Output

**Default mode**: `"warn"`

envtrap reads every chunk written to `process.stdout` by the child process (the child is spawned with `stdio: ['inherit', 'pipe', 'pipe']`) and scans it for active secrets.

**`warn` mode behaviour**:

1. Secrets are redacted in the output: `Bearer [REDACTED: SHA256:f23831a9]`
2. A leak alert is printed to envtrap's own stderr
3. The child process continues running normally

**`block` mode behaviour**:

1. Child process receives `SIGTERM` immediately
2. No further stdout output is forwarded

**Path exclusions**: If the code writing to stdout comes from a file matching `exclusions.paths`, the `hooks.mjs` preRedact function replaces the secret with `[REDACTED: PATH_EXCLUDED]` **inside the child**, so the parent scanner sees only the sanitised value and emits no alert.

***

## `stderr` — Standard Error

**Default mode**: `"warn"`

Identical behaviour to the `stdout` channel, but for `process.stderr`. envtrap reads stderr line by line, filtering internal envtrap protocol messages (prefixed with `[envtrap]`) from normal application error output.

Internal messages like `[envtrap] Child process leak: secret "KEY" passed to: COMMAND` are parsed from the child's stderr stream and used to trigger `child_process` channel alerts in the parent.

***

## `child_process` — Subprocess Spawning

**Default mode**: `"warn"`

envtrap intercepts all Node.js subprocess APIs by wrapping the `node:child_process` module — for both ESM imports and CommonJS `require()` calls.

**Intercepted APIs**:

* `spawn(command, args, options)` — checks `options.env`
* `spawnSync(command, args, options)` — checks `options.env`
* `exec(command, options, callback)` — checks `options.env`
* `execSync(command, options)` — checks `options.env`
* `execFile(file, args, options, callback)` — checks `options.env`
* `execFileSync(file, args, options)` — checks `options.env`
* `fork(modulePath, args, options)` — checks `options.env`

**Detection logic**: For each intercepted call, if `options.env` is provided, envtrap checks whether any **key name** in `options.env` matches a registered secret key **AND** the corresponding value matches exactly. If both match, the leak is reported.

**`warn` mode**: Reports the leak via stderr, subprocess is allowed to proceed.\
**`block` mode**: Throws a synchronous `Error` before any OS fork — the subprocess never executes.

**Path exclusions**: Checked via call stack — if the calling file matches `exclusions.paths`, the check is skipped.

***

## `dns` — Hostname Resolution

**Default mode**: `"block"`

envtrap intercepts all DNS resolution calls by wrapping `node:dns`, for both ESM and CommonJS.

**Intercepted APIs (callback style)**:
`lookup`, `resolve`, `resolve4`, `resolve6`, `resolveAny`, `resolveCname`, `resolveMx`, `resolveNaptr`, `resolveNs`, `resolvePtr`, `resolveSoa`, `resolveSrv`, `resolveTxt`

**Intercepted APIs (promise style — `dns.promises.*`)**:
All of the above, plus `lookup`

**Two detection mechanisms**:

1. **Secret match**: If the target hostname contains any registered secret value as a substring, the leak is reported
2. **High-entropy subdomain warning**: The hostname is split on `.` and each label is evaluated — if any label has:

   * Length ≥ `entropy.minLength` (default `12`)
   * Shannon entropy ≥ `entropy.threshold` (default `3.5`)

   ...a DNS tunneling warning is emitted regardless of whether an exact secret was matched. This catches base64/hex-encoded payloads.

**`warn` mode**: Logs the detection, allows the DNS lookup to proceed.\
**`block` mode**: Throws a synchronous `Error`, preventing any DNS packet from being sent.

**Path exclusions**: Checked via call stack — if the calling file matches `exclusions.paths`, the entire check is skipped.
