Back to Microsandbox

Secrets

docs/sdk/go/secrets.mdx

0.5.109.9 KB
Original Source

See Secrets for how placeholder substitution works and usage examples.

Secrets never enter the VM. The Go SDK passes each SecretEntry 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.

<div className="msb-glance"> <p className="msb-gl"><span className="msb-dot static"></span>Functions<span className="msb-ct">1</span></p> <a className="msb-row" href="#withsecrets"><span className="msb-rn">WithSecrets()</span><span className="msb-rg">attach secrets to a sandbox</span></a> <p className="msb-gl"><span className="msb-dot instance"></span>Methods · Secret<span className="msb-ct">1</span></p> <a className="msb-row" href="#secret-env"><span className="msb-rn">Secret.Env()</span><span className="msb-rg">build a SecretEntry from an env var</span></a> <p className="msb-gl"><span className="msb-dot type"></span>Types</p> <div className="msb-chiprow"> <a className="msb-typepill" href="#secretentrystruct">SecretEntry</a> <a className="msb-typepill" href="#secretenvoptionsstruct">SecretEnvOptions</a> <a className="msb-typepill" href="#violationactionstring-enum">ViolationAction</a> </div> </div> <p className="msb-label" id="typical-flow">Typical flow</p>
go
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 and SecretEnvOptions.

Runtime patternGo APIMatches
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. 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>

<div className="msb-tags"><span className="msb-tag is-static">func</span></div>
go
func WithSecrets(secrets ...SecretEntry) SandboxOption

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 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> <Accordion title="Example">
go
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>

Methods

The Secret factory is a package-level value. Call its methods to build SecretEntry values without populating struct literals by hand.


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

<div className="msb-tags"><span className="msb-tag is-instance">method</span></div>
go
func (secretFactory) Env(envVar, value string, opts SecretEnvOptions) SecretEntry

Build a SecretEntry 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{} 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> <Accordion title="Example">
go
m.Secret.Env("STRIPE_KEY", os.Getenv("STRIPE_KEY"),
    m.SecretEnvOptions{
        AllowHosts:        []string{"api.stripe.com"},
        AllowHostPatterns: []string{"*.stripe.com"},
        Placeholder:       "$MSB_STRIPE",
    },
)
</Accordion>

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; exported for callers that prefer struct literals.

FieldTypeDescription
EnvVarstringEnvironment variable name holding the placeholder inside the sandbox. Must be non-empty and cannot contain = or NUL; shell-identifier syntax is not required
ValuestringReal secret value; never crosses the FFI into the guest
AllowHosts[]stringHosts allowed to receive the real value (exact match)
AllowHostPatterns[]stringWildcard host patterns, e.g. "*.openai.com"
PlaceholderstringCustom 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*boolRequire a verified TLS identity before substituting. Defaults to true when nil
OnViolationViolationActionOverride 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 beyond the required envVar and value.

FieldTypeDescription
AllowHosts[]stringAllowed hosts (exact match)
AllowHostPatterns[]stringWildcard host patterns
PlaceholderstringCustom placeholder: non-empty, up to 1024 bytes, no NUL/CR/LF
RequireTLS*boolRequire a verified TLS identity before substituting. Defaults to true when nil
OnViolationViolationActionPer-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
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; override per-secret with SecretEntry.OnViolation.

ConstantValueDescription
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