---
title: Secrets
description: 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.

<div className="msb-glance">

  <p className="msb-gl"><span className="msb-dot builder"></span>Builder · SecretBuilder<span className="msb-ct">13</span></p>
  <div className="msb-chiprow">
    <a className="msb-chip" href="#env">.env()</a>
    <a className="msb-chip" href="#value">.value()</a>
    <a className="msb-chip" href="#placeholder">.placeholder()</a>
    <a className="msb-chip" href="#allowhost">.allowHost()</a>
    <a className="msb-chip" href="#allowhostpattern">.allowHostPattern()</a>
    <a className="msb-chip" href="#allowanyhostdangerous">.allowAnyHostDangerous()</a>
    <a className="msb-chip" href="#requiretlsidentity">.requireTlsIdentity()</a>
    <a className="msb-chip" href="#injectheaders">.injectHeaders()</a>
    <a className="msb-chip" href="#injectbasicauth">.injectBasicAuth()</a>
    <a className="msb-chip" href="#injectquery">.injectQuery()</a>
    <a className="msb-chip" href="#injectbody">.injectBody()</a>
    <a className="msb-chip" href="#onviolation">.onViolation()</a>
    <a className="msb-chip" href="#build">.build()</a>
  </div>

  <p className="msb-gl"><span className="msb-dot builder"></span>Builder · ViolationActionBuilder<span className="msb-ct">6</span></p>
  <div className="msb-chiprow">
    <a className="msb-chip" href="#block">.block()</a>
    <a className="msb-chip" href="#blockandlog">.blockAndLog()</a>
    <a className="msb-chip" href="#blockandterminate">.blockAndTerminate()</a>
    <a className="msb-chip" href="#passthroughhost">.passthroughHost()</a>
    <a className="msb-chip" href="#passthroughhostpattern">.passthroughHostPattern()</a>
    <a className="msb-chip" href="#passthroughallhosts">.passthroughAllHosts()</a>
  </div>

  <p className="msb-gl"><span className="msb-dot builder"></span>Shorthand · SandboxBuilder<span className="msb-ct">2</span></p>
  <a className="msb-row" href="#sandboxbuilder-secret"><span className="msb-rn">.secret()</span><span className="msb-rg">configure a secret with a closure</span></a>
  <a className="msb-row" href="#sandboxbuilder-secretenv"><span className="msb-rn">.secretEnv()</span><span className="msb-rg">one-line header-injected secret</span></a>

  <p className="msb-gl"><span className="msb-dot builder"></span>Shorthand · NetworkBuilder<span className="msb-ct">4</span></p>
  <a className="msb-row" href="#networkbuilder-secret"><span className="msb-rn">.secret()</span><span className="msb-rg">configure a secret with a closure</span></a>
  <a className="msb-row" href="#networkbuilder-secretenv"><span className="msb-rn">.secretEnv()</span><span className="msb-rg">secret with explicit placeholder</span></a>
  <a className="msb-row" href="#networkbuilder-secretenvsimple"><span className="msb-rn">.secretEnvSimple()</span><span className="msb-rg">auto-placeholder secret</span></a>
  <a className="msb-row" href="#networkbuilder-onsecretviolation"><span className="msb-rn">.onSecretViolation()</span><span className="msb-rg">sandbox-wide violation policy</span></a>

  <p className="msb-gl"><span className="msb-dot type"></span>Types</p>
  <div className="msb-chiprow">
    <a className="msb-typepill" href="#secretentry">SecretEntry</a>
    <a className="msb-typepill" href="#secretinjection">SecretInjection</a>
    <a className="msb-typepill" href="#violationaction">ViolationAction</a>
  </div>

</div>

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

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
allowHost(host: string): this
```

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>

<Accordion title="Example">

```typescript
.secret((s) =>
  s.env("STRIPE_KEY")
    .value(process.env.STRIPE_KEY!)
    .allowHost("api.stripe.com")
    .allowHost("files.stripe.com"),
)
```

</Accordion>

---

#### <span className="msb-recv">.</span><span className="msb-hn">allowHostPattern()</span>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
onViolation(configure: (b: ViolationActionBuilder) => ViolationActionBuilder): this
```

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) =&gt; ViolationActionBuilder</a></div>
    <div className="msb-param-desc">Configure the per-secret violation action.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
.secret((s) =>
  s.env("API_KEY")
    .value(process.env.API_KEY!)
    .allowHost("api.github.com")
    .onViolation((v) =>
      v.blockAndLog().passthroughHost("api.anthropic.com"),
    ),
)
```

</Accordion>

---

#### <span className="msb-recv">.</span><span className="msb-hn">build()</span>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
secret(configure: (s: SecretBuilder) => SecretBuilder): this
```

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) =&gt; SecretBuilder</a></div>
    <div className="msb-param-desc">Configure the secret.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
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>

---

#### <span className="msb-recv">.</span><span className="msb-hn" id="sandboxbuilder-secretenv">secretEnv()</span>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
secretEnv(envVar: string, value: string, allowedHost: string): this
```

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).

<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>

<Accordion title="Example">

```typescript
await using sb = await Sandbox.builder("agent")
  .image("python")
  .secretEnv("OPENAI_API_KEY", process.env.OPENAI_API_KEY!, "api.openai.com")
  .create();
```

</Accordion>

---

## 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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
secret(configure: (s: SecretBuilder) => SecretBuilder): this
```

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) =&gt; SecretBuilder</a></div>
    <div className="msb-param-desc">Configure the secret.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
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>

---

#### <span className="msb-recv">.</span><span className="msb-hn" id="networkbuilder-secretenv">secretEnv()</span>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
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>
<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```typescript
onSecretViolation(configure: (b: ViolationActionBuilder) => ViolationActionBuilder): this
```

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) =&gt; ViolationActionBuilder</a></div>
    <div className="msb-param-desc">Configure the sandbox-wide violation action.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
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>

---

## Types

### SecretEntry
<div className="msb-tags"><span className="msb-tag is-type">interface</span></div>

<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
<div className="msb-tags"><span className="msb-tag is-type">interface</span></div>

<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
<div className="msb-tags"><span className="msb-tag is-type">type</span></div>

<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
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. |
