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

> Go SDK - Secret injection API reference

See [Secrets](/sandboxes/secrets) for how placeholder substitution works and usage examples.

Secrets never enter the VM. The Go SDK passes each [`SecretEntry`](#secretentrystruct) to the runtime, which exposes a placeholder string inside the guest (e.g. `$MSB_SERVICE_API_KEY`) and substitutes the real value at the network layer only when traffic reaches an allowed host.

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

```go theme={null}
import m "github.com/superradcompany/microsandbox/sdk/go"

sb, err := m.CreateSandbox(ctx, "worker",
    m.WithImage("python:3.12"),
    m.WithSecrets(m.Secret.Env(
        "SERVICE_API_KEY",
        os.Getenv("SERVICE_API_KEY"),
        m.SecretEnvOptions{
            AllowHosts: []string{"api.example.com"},
        },
    )),
)
```

## Host matching

Go does not expose the Rust `HostPattern` enum directly. Exact and wildcard host patterns are represented with the `AllowHosts` and `AllowHostPatterns` fields on [`SecretEntry`](#secretentrystruct) and [`SecretEnvOptions`](#secretenvoptionsstruct).

| Runtime pattern                          | Go API                                         | Matches                             |
| ---------------------------------------- | ---------------------------------------------- | ----------------------------------- |
| `HostPattern::Exact("api.example.com")`  | `AllowHosts: []string{"api.example.com"}`      | That exact SNI host                 |
| `HostPattern::Wildcard("*.example.com")` | `AllowHostPatterns: []string{"*.example.com"}` | Hosts matching the wildcard pattern |

These fields decide where the real secret value may be substituted. A host that is not matched by either field is disallowed for that secret, so sending its placeholder there triggers the configured [`ViolationAction`](#violationactionstring-enum). Allow-list entries are pinned to observed DNS answers and TLS identity. At least one exact or wildcard host is required.

## 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{AllowHosts: []string{"api.stripe.com"}}),
          m.Secret.Env("OPENAI_API_KEY", os.Getenv("OPENAI_API_KEY"),
              m.SecretEnvOptions{AllowHostPatterns: []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#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#createsandbox">CreateSandbox</a>.</div>
  </div>
</div>

## Methods

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{
          AllowHosts:        []string{"api.stripe.com"},
          AllowHostPatterns: []string{"*.stripe.com"},
          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. Pass an empty [`SecretEnvOptions`](#secretenvoptionsstruct)`{}` when no extra tuning is needed.

<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. Never crosses the FFI into 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>

## 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; never crosses the FFI into the guest                                                                                                                                             |
| `AllowHosts`        | `[]string`                                       | Hosts allowed to receive the real value (exact match)                                                                                                                                               |
| `AllowHostPatterns` | `[]string`                                       | Wildcard host patterns, e.g. `"*.openai.com"`                                                                                                                                                       |
| `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 |
| `RequireTLS`        | `*bool`                                          | Require a verified TLS identity before substituting. Defaults to `true` when `nil`                                                                                                                  |
| `OnViolation`       | [`ViolationAction`](#violationactionstring-enum) | Override the sandbox-wide action when this secret is detected going to a disallowed host. The last non-empty value across all secrets wins, since the runtime applies it network-wide               |

### 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                                                                        |
| ------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `AllowHosts`        | `[]string`                                       | Allowed hosts (exact match)                                                        |
| `AllowHostPatterns` | `[]string`                                       | Wildcard host patterns                                                             |
| `Placeholder`       | `string`                                         | Custom placeholder: non-empty, up to 1024 bytes, no NUL/CR/LF                      |
| `RequireTLS`        | `*bool`                                          | Require a verified TLS identity before substituting. Defaults to `true` when `nil` |
| `OnViolation`       | [`ViolationAction`](#violationactionstring-enum) | Per-secret violation action                                                        |

### 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 is detected going to a host the secret isn't allowed to talk to. Configure the sandbox-wide default on [`NetworkConfig.OnSecretViolation`](/sdk/go/networking#networkconfig); override per-secret with [`SecretEntry.OnViolation`](#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 |
