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

# Secrets

> TypeScript SDK - Secret injection API reference

Inject credentials into outbound HTTP without ever exposing the real value to the guest. The guest only ever sees a placeholder; microsandbox's TLS proxy swaps in the real secret on connections to allowed hosts and blocks everything else. See [Secrets](/sandboxes/secrets) for how placeholder substitution works and usage examples.

<p className="msb-label" id="typical-flow">Typical flow</p>

```typescript theme={null}
import { Sandbox } from "microsandbox";

await using sb = await Sandbox.builder("agent")
  .image("python")
  .secret((s) =>
    s.env("OPENAI_API_KEY")              // guest sees $MSB_OPENAI_API_KEY
      .value(process.env.OPENAI_API_KEY!)
      .allowHost("api.openai.com"),      // real value only reaches this host
  )
  .create();

// In the guest, the placeholder is swapped for the real key
// only on TLS connections to api.openai.com.
const out = await sb.exec("python", ["agent.py"]);
```

## SecretBuilder

Fluent builder for one secret's placeholder, allowed hosts, and injection scopes. Obtained through [`SandboxBuilder.secret(s => ...)`](#sandboxbuilder-secret) or [`NetworkBuilder.secret(s => ...)`](#networkbuilder-secret); each secret maps an environment variable to a real value that is only revealed when traffic reaches an allowed host through the TLS proxy. Every setter returns the same builder so calls can be chained. [`env()`](#env), [`value()`](#value), and at least one allowed host are required; [`build()`](#build) throws otherwise. Adding any secret automatically enables TLS interception.

#### <span className="msb-recv">.</span><span className="msb-hn">env()</span>

```typescript theme={null}
env(varName: string): this
```

Set the environment variable name that holds the placeholder inside the guest. The guest sees `$MSB_<varName>` (or a custom [`placeholder`](#placeholder)), never the real value. Names must be non-empty and cannot contain `=` or NUL; shell-identifier syntax is not required. **Required.**

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>varName</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Environment variable name (non-empty, no <code>=</code> or NUL).</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">value()</span>

```typescript theme={null}
value(value: string): this
```

Set the real secret value. This is the string that replaces the placeholder when a request reaches an allowed host. It never enters the guest VM. **Required.**

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">The actual credential or token.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">placeholder()</span>

```typescript theme={null}
placeholder(placeholder: string): this
```

Override the auto-generated placeholder string. By default microsandbox generates `$MSB_<envVar>`. Use this when you need a specific format or when the placeholder must match a particular byte length. Placeholders must be non-empty, at most 1024 bytes, and cannot contain NUL, CR, or LF.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>placeholder</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Custom placeholder string: non-empty, up to 1024 bytes, no NUL/CR/LF.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">allowHost()</span>

```typescript theme={null}
allowHost(host: string): this
```

<Accordion title="Example">
  ```typescript theme={null}
  .secret((s) =>
    s.env("STRIPE_KEY")
      .value(process.env.STRIPE_KEY!)
      .allowHost("api.stripe.com")
      .allowHost("files.stripe.com"),
  )
  ```
</Accordion>

Add an exact host allowed to receive the real secret value. The proxy checks the host against the connection's verified TLS identity and observed DNS history. Can be called multiple times to allow several hosts. At least one allowed host (exact, pattern, or any) is required.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Exact hostname, e.g. <code>"api.example.com"</code> (ASCII case-insensitive).</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">allowHostPattern()</span>

```typescript theme={null}
allowHostPattern(pattern: string): this
```

Add a wildcard host pattern. A `*.suffix` pattern matches the suffix itself and any single-or-multi label subdomain of it.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>pattern</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Wildcard pattern, e.g. <code>"\*.googleapis.com"</code>.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">allowAnyHostDangerous()</span>

```typescript theme={null}
allowAnyHostDangerous(iUnderstand: boolean): this
```

Allow substitution on **any** host. Every server the guest connects to can then receive the real secret, which effectively disables host-based protection. The call is a no-op unless `iUnderstand` is `true`. Only use this when the secret is not sensitive or the sandbox network is fully locked down. This is the one allow-list pattern that skips DNS and TLS-identity pinning.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>iUnderstand</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Must be <code>true</code> to take effect.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">requireTlsIdentity()</span>

```typescript theme={null}
requireTlsIdentity(enabled: boolean): this
```

When `true`, the secret is only substituted on TLS-intercepted connections where the proxy has verified it is performing MITM and the SNI matches an allowed host. Bypassed TLS is opaque and never receives substitution. Disable only when you know the traffic path is safe and explicitly supports non-TLS substitution. Default: `true`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>enabled</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Require verified TLS identity. Default: <code>true</code>.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">injectHeaders()</span>

```typescript theme={null}
injectHeaders(enabled: boolean): this
```

Control whether the placeholder is replaced anywhere in HTTP headers. This is the most common injection scope, covering `Authorization: Bearer $MSB_...` and similar patterns. Default: `true`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>enabled</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Substitute in headers. Default: <code>true</code>.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">injectBasicAuth()</span>

```typescript theme={null}
injectBasicAuth(enabled: boolean): this
```

Control whether `Authorization: Basic <base64>` credentials are decoded, substituted in the decoded `user:password`, then re-encoded. Orthogonal to [`injectHeaders`](#injectheaders): this flag handles the encoded-credentials case for the Basic scheme; `injectHeaders` handles literal substitution in any header line, including non-Basic Authorization schemes (`Bearer`, `Digest`). Default: `true`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>enabled</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Substitute inside Basic Auth credentials. Default: <code>true</code>.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">injectQuery()</span>

```typescript theme={null}
injectQuery(enabled: boolean): this
```

Control whether the placeholder is replaced in the URL query string (the `?key=value` portion of the request line). Default: `false`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>enabled</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Substitute in query parameters. Default: <code>false</code>.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">injectBody()</span>

```typescript theme={null}
injectBody(enabled: boolean): this
```

Control whether the placeholder is replaced in request bodies when microsandbox can inspect and rewrite them safely. Encoded bodies are forwarded unchanged, and body placeholders in unsupported body formats are blocked rather than leaked. Default: `false`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>enabled</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Substitute in request bodies. Default: <code>false</code>.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">onViolation()</span>

```typescript theme={null}
onViolation(configure: (b: ViolationActionBuilder) => ViolationActionBuilder): this
```

<Accordion title="Example">
  ```typescript theme={null}
  .secret((s) =>
    s.env("API_KEY")
      .value(process.env.API_KEY!)
      .allowHost("api.github.com")
      .onViolation((v) =>
        v.blockAndLog().passthroughHost("api.anthropic.com"),
      ),
  )
  ```
</Accordion>

Configure violation behavior for this secret. Overrides the sandbox-wide secret violation policy and can let selected hosts receive the placeholder unchanged. See [`ViolationActionBuilder`](#violationactionbuilder) for the full set of `block*` and `passthrough*` methods.

Passthrough hosts do **not** receive the real secret value; substitution still only happens for hosts configured with [`allowHost()`](#allowhost) or [`allowHostPattern()`](#allowhostpattern). When a per-secret passthrough policy does not match the request host, microsandbox falls back to the sandbox-wide secret violation action.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="#violationactionbuilder">(b: ViolationActionBuilder) => ViolationActionBuilder</a></div>
    <div className="msb-param-desc">Configure the per-secret violation action.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">build()</span>

```typescript theme={null}
build(): SecretEntry
```

Materialize the [`SecretEntry`](#secretentry). Called for you by [`SandboxBuilder.secret`](#sandboxbuilder-secret), so you rarely call it directly. If [`placeholder`](#placeholder) was not set, it defaults to `$MSB_<envVar>`. Throws a `MicrosandboxError` if `env` or `value` was not set, or if the allow-list is empty.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#secretentry">SecretEntry</a></div>
    <div className="msb-param-desc">The materialized secret entry.</div>
  </div>
</div>

## ViolationActionBuilder

Fluent builder for the action taken when a secret placeholder is sent to a disallowed host. Obtained through the closure passed to [`SecretBuilder.onViolation(v => ...)`](#onviolation) (per-secret) or [`NetworkBuilder.onSecretViolation(v => ...)`](#networkbuilder-onsecretviolation) (sandbox-wide). The terminal `block*` methods set the base action; the `passthrough*` methods carve out hosts that get the placeholder forwarded unchanged.

#### <span className="msb-recv">.</span><span className="msb-hn">block()</span>

```typescript theme={null}
block(): this
```

Silently drop a violating request. The guest sees a connection reset. This is the default.

#### <span className="msb-recv">.</span><span className="msb-hn">blockAndLog()</span>

```typescript theme={null}
blockAndLog(): this
```

Drop the request and emit a warning log on the host side.

#### <span className="msb-recv">.</span><span className="msb-hn">blockAndTerminate()</span>

```typescript theme={null}
blockAndTerminate(): this
```

Drop the request, log an error, and shut down the entire sandbox.

#### <span className="msb-recv">.</span><span className="msb-hn">passthroughHost()</span>

```typescript theme={null}
passthroughHost(host: string): this
```

Forward requests to an exact host with the placeholder unchanged, instead of blocking. The host does **not** receive the real value. Non-matching hosts fall back to the base `block*` action.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Exact hostname to forward unchanged.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">passthroughHostPattern()</span>

```typescript theme={null}
passthroughHostPattern(pattern: string): this
```

Forward requests to any host matching a wildcard pattern with the placeholder unchanged.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>pattern</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Wildcard pattern, e.g. <code>"\*.internal.example.com"</code>.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">passthroughAllHosts()</span>

```typescript theme={null}
passthroughAllHosts(iUnderstand: boolean): this
```

Forward the placeholder unchanged to **every** host instead of blocking. The call is a no-op unless `iUnderstand` is `true`. The real value is still never substituted on these hosts; this only stops the request from being dropped.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>iUnderstand</code><span className="msb-type">boolean</span></div>
    <div className="msb-param-desc">Must be <code>true</code> to take effect.</div>
  </div>
</div>

## SandboxBuilder shorthand

Two methods on [`SandboxBuilder`](/sdk/typescript/sandbox) for adding secrets without reaching into a [`NetworkBuilder`](/sdk/typescript/networking). Both automatically enable TLS interception.

#### <span className="msb-recv">.</span><span className="msb-hn" id="sandboxbuilder-secret">secret()</span>

```typescript theme={null}
secret(configure: (s: SecretBuilder) => SecretBuilder): this
```

<Accordion title="Example">
  ```typescript theme={null}
  await using sb = await Sandbox.builder("payments-worker")
    .image("python")
    .secret((s) =>
      s.env("STRIPE_KEY")
        .value(process.env.STRIPE_KEY!)
        .allowHost("api.stripe.com")
        .allowHostPattern("*.stripe.com")
        .injectHeaders(true)
        .injectQuery(false),
    )
    .create();
  ```
</Accordion>

Add a secret with full configuration via a [`SecretBuilder`](#secretbuilder) closure. The builder's [`build()`](#build) is called for you.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="#secretbuilder">(s: SecretBuilder) => SecretBuilder</a></div>
    <div className="msb-param-desc">Configure the secret.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn" id="sandboxbuilder-secretenv">secretEnv()</span>

```typescript theme={null}
secretEnv(envVar: string, value: string, allowedHost: string): this
```

<Accordion title="Example">
  ```typescript theme={null}
  await using sb = await Sandbox.builder("agent")
    .image("python")
    .secretEnv("OPENAI_API_KEY", process.env.OPENAI_API_KEY!, "api.openai.com")
    .create();
  ```
</Accordion>

Three-argument shorthand. Auto-generates the placeholder as `$MSB_<envVar>` and allows substitution only on `allowedHost`. The default injection scopes apply (headers and Basic Auth enabled, query and body disabled).

<Warning>
  **Plaintext at rest.** The value is persisted verbatim in the durable sandbox config until a later modify rotate migrates the entry to a source reference. Use this path when you hold only a value; a future host-side secret store will switch it to import-then-reference with no signature change.
</Warning>

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>envVar</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Environment variable name (non-empty, no <code>=</code> or NUL).</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Secret value.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>allowedHost</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Allowed destination host (exact match).</div>
  </div>
</div>

## NetworkBuilder shorthand

The same secret configuration is available inside [`SandboxBuilder.network(n => ...)`](/sdk/typescript/networking) for callers who are already configuring networking. These methods set the secrets and the sandbox-wide violation policy directly on the network.

#### <span className="msb-recv">.</span><span className="msb-hn" id="networkbuilder-secret">secret()</span>

```typescript theme={null}
secret(configure: (s: SecretBuilder) => SecretBuilder): this
```

<Accordion title="Example">
  ```typescript theme={null}
  await using sb = await Sandbox.builder("agent")
    .image("python")
    .network((n) =>
      n.secret((s) =>
        s.env("OPENAI_API_KEY")
          .value(process.env.OPENAI_API_KEY!)
          .allowHost("api.openai.com"),
      ),
    )
    .create();
  ```
</Accordion>

Add a secret with full configuration via a [`SecretBuilder`](#secretbuilder) closure. Identical in behavior to [`SandboxBuilder.secret`](#sandboxbuilder-secret).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="#secretbuilder">(s: SecretBuilder) => SecretBuilder</a></div>
    <div className="msb-param-desc">Configure the secret.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn" id="networkbuilder-secretenv">secretEnv()</span>

```typescript theme={null}
secretEnv(envVar: string, value: string, placeholder: string, allowedHost: string): this
```

Four-argument shorthand. Same as the `SandboxBuilder` form but lets you provide the placeholder explicitly instead of auto-generating `$MSB_<envVar>`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>envVar</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Environment variable name (non-empty, no <code>=</code> or NUL).</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Secret value.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>placeholder</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Explicit placeholder: non-empty, up to 1024 bytes, no NUL/CR/LF.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>allowedHost</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Allowed destination host (exact match).</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn" id="networkbuilder-secretenvsimple">secretEnvSimple()</span>

```typescript theme={null}
secretEnvSimple(envVar: string, value: string, allowedHost: string): this
```

Three-argument shorthand on `NetworkBuilder`. Auto-generates the placeholder as `$MSB_<envVar>`, matching [`SandboxBuilder.secretEnv`](#sandboxbuilder-secretenv).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>envVar</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Environment variable name (non-empty, no <code>=</code> or NUL).</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Secret value.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>allowedHost</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Allowed destination host (exact match).</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn" id="networkbuilder-onsecretviolation">onSecretViolation()</span>

```typescript theme={null}
onSecretViolation(configure: (b: ViolationActionBuilder) => ViolationActionBuilder): this
```

<Accordion title="Example">
  ```typescript theme={null}
  await using sb = await Sandbox.builder("agent")
    .image("python")
    .network((n) =>
      n.secretEnvSimple("OPENAI_API_KEY", process.env.OPENAI_API_KEY!, "api.openai.com")
        .onSecretViolation((v) => v.blockAndLog()),
    )
    .create();
  ```
</Accordion>

Set the sandbox-wide secret violation policy: what happens when any secret's placeholder is sent to a host outside that secret's allow-list. Per-secret [`SecretBuilder.onViolation`](#onviolation) overrides this for the secret it is set on. See [`ViolationActionBuilder`](#violationactionbuilder) for the available actions.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>configure</code><a className="msb-type" href="#violationactionbuilder">(b: ViolationActionBuilder) => ViolationActionBuilder</a></div>
    <div className="msb-param-desc">Configure the sandbox-wide violation action.</div>
  </div>
</div>

## Types

### SecretEntry

<p className="msb-backref">Returned by <a href="#build">SecretBuilder.build()</a></p>

The object produced by [`SecretBuilder.build()`](#build). You normally construct one with the builder, but the shape is available for callers that prefer plain objects.

| Field                 | Type                                  | Description                                                                                            |
| --------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `envVar`              | `string`                              | Environment variable name (non-empty, no `=` or NUL)                                                   |
| `value`               | `string`                              | Real secret value (stays on the host)                                                                  |
| `placeholder`         | `string \| null`                      | Custom placeholder: non-empty, up to 1024 bytes, no NUL/CR/LF; defaults to `$MSB_<envVar>` when `null` |
| `allowedHosts`        | `readonly string[]`                   | Allowed hosts (exact match)                                                                            |
| `allowedHostPatterns` | `readonly string[]`                   | Wildcard host patterns                                                                                 |
| `allowAnyHost`        | `boolean`                             | Permit substitution to any host                                                                        |
| `requireTlsIdentity`  | `boolean`                             | Require verified TLS identity before substituting                                                      |
| `injection`           | [`SecretInjection`](#secretinjection) | Where in the request the value may be substituted                                                      |

### SecretInjection

<p className="msb-backref">Used by <a href="#secretentry">SecretEntry.injection</a></p>

Controls where the TLS proxy substitutes the placeholder with the real value. Each field is optional; omitted fields use the default. Set through the [`inject*`](#injectheaders) methods on [`SecretBuilder`](#secretbuilder).

| Field          | Type      | Default | Description                                                                                                                                                                                                                     |
| -------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `headers?`     | `boolean` | `true`  | Replace the placeholder anywhere in HTTP headers.                                                                                                                                                                               |
| `basicAuth?`   | `boolean` | `true`  | Decode `Authorization: Basic <base64>` credentials, substitute in the decoded `user:password`, and re-encode. Other schemes (`Bearer`, `Digest`) are handled by `headers`.                                                      |
| `queryParams?` | `boolean` | `false` | Replace the placeholder in URL query parameters.                                                                                                                                                                                |
| `body?`        | `boolean` | `false` | Replace the placeholder in request bodies when microsandbox can inspect and rewrite them safely. Encoded bodies are forwarded unchanged, and body placeholders in unsupported body formats are blocked instead of being leaked. |

### ViolationAction

<p className="msb-backref">Built by <a href="#violationactionbuilder">ViolationActionBuilder</a></p>

The string identifier for the base action taken when a secret placeholder is sent to a disallowed host. Configured through [`ViolationActionBuilder`](#violationactionbuilder) (via [`SecretBuilder.onViolation`](#onviolation) or [`NetworkBuilder.onSecretViolation`](#networkbuilder-onsecretviolation)). The `ViolationActions` array enumerates all values.

```typescript theme={null}
type ViolationAction = "block" | "block-and-log" | "block-and-terminate" | "passthrough";
```

| Value                   | Builder method                                                                                                                                    | Description                                                                                          |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `'block'`               | [`block()`](#block)                                                                                                                               | Silently drop the request. The guest sees a connection reset. This is the default.                   |
| `'block-and-log'`       | [`blockAndLog()`](#blockandlog)                                                                                                                   | Drop the request and emit a warning log on the host side.                                            |
| `'block-and-terminate'` | [`blockAndTerminate()`](#blockandterminate)                                                                                                       | Drop the request, log an error, and shut down the entire sandbox.                                    |
| `'passthrough'`         | [`passthroughHost()`](#passthroughhost) / [`passthroughHostPattern()`](#passthroughhostpattern) / [`passthroughAllHosts()`](#passthroughallhosts) | Forward matching hosts with the placeholder unchanged. Non-matching hosts use the base block action. |
