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

> Configure destination-bound sandbox credentials with the Go SDK.

See [Secrets](/sandboxes/secrets) for usage examples and security boundaries.

## Functions

#### <span className="msb-hn">WithSecrets()</span>

```go theme={null}
func WithSecrets(secrets ...SecretEntry) SandboxOption
```

<Accordion title="Example">
  ```go theme={null}
  sb, err := m.CreateSandbox(ctx, "worker",
      m.WithImage("python:3.12"),
      m.WithSecrets(
          m.Secret.Env("STRIPE_KEY", os.Getenv("STRIPE_KEY"),
              m.SecretEnvOptions{Allow: []string{"api.stripe.com"}}),
          m.Secret.Env("OPENAI_API_KEY", os.Getenv("OPENAI_API_KEY"),
              m.SecretEnvOptions{Allow: []string{"*.openai.com"}}),
      ),
  )
  ```
</Accordion>

Append credential secrets to the sandbox. Each call appends, so multiple calls accumulate. Secrets never enter the VM; the network proxy substitutes them at the transport layer. Pass to [`CreateSandbox`](/sdk/go/sandbox#m-createsandbox) alongside the other options.

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>secrets</code><a className="msb-type" href="#secretentrystruct">...SecretEntry</a></div>
    <div className="msb-param-desc">Secret entries to attach, usually built with <a className="msb-type" href="#secret-env">Secret.Env</a>.</div>
  </div>
</div>

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">SandboxOption</span></div>
    <div className="msb-param-desc">Functional option for <a className="msb-type" href="/sdk/go/sandbox#m-createsandbox">CreateSandbox</a>.</div>
  </div>
</div>

## Secret

The [`Secret`](#secret-env) factory is a package-level value. Call its methods to build [`SecretEntry`](#secretentrystruct) values without populating struct literals by hand.

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

```go theme={null}
func (secretFactory) Env(envVar, value string, opts SecretEnvOptions) SecretEntry
```

<Accordion title="Example">
  ```go theme={null}
  m.Secret.Env("STRIPE_KEY", os.Getenv("STRIPE_KEY"),
      m.SecretEnvOptions{
          Allow:               []string{"api.stripe.com", "*.stripe.com"},
          AllowPlaceholderFor: []string{"api.anthropic.com"},
          Substitution:        m.SecretSubstitution{Body: true},
          Placeholder:         "$MSB_STRIPE",
      },
  )
  ```
</Accordion>

Build a [`SecretEntry`](#secretentrystruct) that maps an environment variable to a real value. The guest sees a placeholder; the real value is substituted by the TLS proxy only when traffic goes to an allowed host. Supply at least one exact or wildcard host in `Allow`; an empty allow-list is rejected when the sandbox configuration is validated.

<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 holding the placeholder inside the sandbox. Must be non-empty and cannot contain <code>=</code> or NUL; shell-identifier syntax is not required.</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">The real secret value. Passed to the native host runtime, never exposed inside the guest.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#secretenvoptionsstruct">SecretEnvOptions</a></div>
    <div className="msb-param-desc">Allowed hosts, placeholder override, TLS requirement, and violation action.</div>
  </div>
</div>

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

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#secretentrystruct">SecretEntry</a></div>
    <div className="msb-param-desc">Pass to <a className="msb-type" href="#withsecrets">WithSecrets</a>.</div>
  </div>
</div>

## Validation and lifecycle

Sandbox configuration validation rejects invalid environment names (empty or containing `=` or NUL), an empty allow-list, all substitution locations disabled, and invalid placeholders. `Secret.Env()` constructs a value; errors surface when the configuration is validated.

Raw values are persisted in the durable sandbox configuration. See [source references and live modification](/sandboxes/secrets#update-secrets) to rotate or remove secrets without restarting. Adding a secret or changing its guest-visible placeholder requires a restart. Live modification is local-only.

## Types

### SecretEntry<span className="msb-tag is-type" style={{marginLeft: "8px"}}>struct</span>

<p className="msb-backref">accepted by <a href="#withsecrets">WithSecrets()</a> · returned by <a href="#secret-env">Secret.Env()</a></p>

A single credential the network proxy substitutes at the transport layer. The value never reaches the guest VM. Usually produced by [`Secret.Env`](#secret-env); exported for callers that prefer struct literals.

| Field | Type | Description |
| - | - | - |
| `EnvVar` | `string` | Environment variable name holding the placeholder inside the sandbox. Must be non-empty and cannot contain `=` or NUL; shell-identifier syntax is not required |
| `Value` | `string` | Real secret value; stays on the host, including across the native FFI boundary |
| `Allow` | `[]string` | Exact hosts or wildcard patterns allowed to receive the real value |
| `Passthrough` | `[]string` | Exact hosts or wildcard patterns allowed to receive the unchanged placeholder |
| `Substitution` | [`SecretSubstitution`](#secretsubstitutionstruct) | Enabled request locations; zero value enables headers only |
| `Placeholder` | `string` | Custom placeholder shown inside the sandbox in place of the secret. Auto-generated from `EnvVar` when empty. Custom values must be non-empty, at most 1024 bytes, and cannot contain NUL, CR, or LF |
| `RequireTLSIdentity` | `*bool` | Require a verified TLS identity before substituting. Defaults to `true` when `nil` |
| `ViolationAction` | [`ViolationAction`](#violationactionstring-enum) | Override the sandbox-wide action when this secret is detected going to a disallowed host. This overrides the network default for this secret only |

### SecretEnvOptions<span className="msb-tag is-type" style={{marginLeft: "8px"}}>struct</span>

<p className="msb-backref">accepted by <a href="#secret-env">Secret.Env()</a></p>

Tunes [`Secret.Env`](#secret-env) beyond the required `envVar` and `value`.

| Field | Type | Description |
| - | - | - |
| `Allow` | `[]string` | Exact hosts or wildcard patterns allowed to receive the real value |
| `AllowPlaceholderFor` | `[]string` | Hosts allowed to receive the unchanged placeholder where substitution does not apply |
| `Passthrough` | `[]string` | Deprecated alias; combined with `AllowPlaceholderFor` when both are supplied |
| `Substitution` | [`SecretSubstitution`](#secretsubstitutionstruct) | Zero value enables headers only |
| `Placeholder` | `string` | Custom placeholder: non-empty, up to 1024 bytes, no NUL/CR/LF |
| `RequireTLSIdentity` | `*bool` | Require a verified TLS identity before substituting. Defaults to `true` when `nil` |
| `ViolationAction` | [`ViolationAction`](#violationactionstring-enum) | Per-secret violation action |

### SecretSubstitution<span className="msb-tag is-type" style={{marginLeft: "8px"}}>struct</span>

<p className="msb-backref">Used by <a href="#secretentrystruct">SecretEntry</a> · <a href="#secretenvoptionsstruct">SecretEnvOptions</a></p>

| Field | Type | Default | Description |
| - | - | - | - |
| `Headers` | `*bool` | `true` when `nil` | Substitute in headers, including decoded Basic authentication. |
| `Query` | `bool` | `false` | Substitute in URL query parameters. |
| `Body` | `bool` | `false` | Substitute in supported HTTP/1 request bodies. |

Use a pointer to distinguish an explicit false from the default:

```go theme={null}
headers := false
secret := m.Secret.Env("GH_TOKEN", os.Getenv("GH_TOKEN"), m.SecretEnvOptions{
    Allow:               []string{"github.com", "api.github.com"},
    AllowPlaceholderFor: []string{"api.anthropic.com"},
    Substitution:        m.SecretSubstitution{Headers: &headers, Body: true},
    ViolationAction:     m.ViolationActionBlockAndTerminate,
})
sb, err := m.CreateSandbox(ctx, "worker",
    m.WithImage("python"),
    m.WithSecrets(secret),
    m.WithNetwork(&m.NetworkConfig{
        SecretViolationAction: m.ViolationActionBlockAndLog,
    }),
)
```

At least one substitution location must remain enabled. On credential-allowed hosts that pass the secret's identity checks, disabled locations forward the placeholder unchanged. Other destinations must match `Passthrough` or follow the violation action. When body substitution is enabled, fixed-length HTTP/1 bodies up to 16 MiB update `Content-Length`; larger fixed-length bodies are blocked. Chunked bodies are decoded and re-encoded. Encoded bodies pass through unchanged. HTTP/2 DATA-frame body substitution is unsupported, and matching body placeholders are blocked.

### ViolationAction<span className="msb-tag is-type" style={{marginLeft: "8px"}}>string enum</span>

<p className="msb-backref">field of <a href="#secretentrystruct">SecretEntry</a> · <a href="/sdk/go/networking#networkconfig">NetworkConfig</a></p>

```go theme={null}
type ViolationAction string
```

What happens when a secret placeholder cannot be substituted or passed through. Passthrough is a separate per-secret host policy, not a violation action. Configure the sandbox-wide default on [`NetworkConfig.SecretViolationAction`](/sdk/go/networking#networkconfig); override per-secret with [`SecretEntry.ViolationAction`](#secretentrystruct).

| Constant | Value | Description |
| - | - | - |
| `ViolationActionDefault` | `""` | Leave the runtime default in place (currently `block-and-log`) |
| `ViolationActionBlock` | `"block"` | Silently drop the request. The guest sees a connection reset |
| `ViolationActionBlockAndLog` | `"block-and-log"` | Drop the request and emit a warning log on the host side |
| `ViolationActionBlockAndTerminate` | `"block-and-terminate"` | Drop the request, log an error, and shut down the entire sandbox |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.