docs/sdk/python/secrets.mdx
Bind a credential to an environment variable so the guest only ever sees a placeholder: the real value is substituted by the TLS proxy when traffic reaches an allowed host, and blocked everywhere else. See Secrets for how placeholder substitution works and usage examples.
<div className="msb-glance"> <p className="msb-gl"><span className="msb-dot static"></span>Factory · 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">map an env var to a secret value</span></a> <p className="msb-gl"><span className="msb-dot static"></span>Violation policy · ViolationPolicy<span className="msb-ct">4</span></p> <a className="msb-row" href="#violationpolicy-block"><span className="msb-rn">ViolationPolicy.block()</span><span className="msb-rg">silently drop on violation</span></a> <a className="msb-row" href="#violationpolicy-block_and_log"><span className="msb-rn">ViolationPolicy.block_and_log()</span><span className="msb-rg">drop and warn</span></a> <a className="msb-row" href="#violationpolicy-block_and_terminate"><span className="msb-rn">ViolationPolicy.block_and_terminate()</span><span className="msb-rg">drop, log, shut down</span></a> <a className="msb-row" href="#violationpolicy-passthrough"><span className="msb-rn">ViolationPolicy.passthrough()</span><span className="msb-rg">forward placeholder to hosts</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> <a className="msb-typepill" href="#violationpolicy">ViolationPolicy</a> <a className="msb-typepill" href="#secretviolationerror">SecretViolationError</a> </div> </div> <p className="msb-label" id="typical-flow">Typical flow</p>import os
from microsandbox import Sandbox, Secret
sb = await Sandbox.create(
"worker",
image="python",
secrets=[
Secret.env(
"GITHUB_TOKEN",
value=os.environ["GITHUB_TOKEN"],
allow_hosts=["api.github.com"],
allow_host_patterns=["*.githubusercontent.com"],
),
],
)
@staticmethod
def env(
env_var: str,
*,
value: str,
allow_hosts: Sequence[str] = (),
allow_host_patterns: Sequence[str] = (),
placeholder: str | None = None,
require_tls: bool = True,
on_violation: ViolationAction | ViolationPolicy = ViolationAction.BLOCK_AND_LOG,
injection: SecretInjection | None = None,
) -> SecretEntry
Create a secret entry that maps an environment variable to a real value. The guest sees a placeholder; the real value is only substituted by the TLS proxy when traffic goes to an allowed host. Pass the returned entry to Sandbox.create(..., secrets=[...]).
from microsandbox import Secret, SecretInjection
secret = Secret.env(
"SERVICE_API_KEY",
value=os.environ["SERVICE_API_KEY"],
allow_hosts=["api.example.com"],
injection=SecretInjection(query_params=True),
)
on_violation (per secret) and Network.on_secret_violation (sandbox-wide default) both accept a bare ViolationAction or a ViolationPolicy. The classmethods below construct a policy. Use passthrough() when selected hosts should receive the placeholder unchanged; the other three mirror the plain ViolationAction values.
@classmethod
def block(cls) -> ViolationPolicy
Silently drop the request when the placeholder is sent to a disallowed host. The guest sees a connection reset. Equivalent to ViolationAction.BLOCK.
@classmethod
def block_and_log(cls) -> ViolationPolicy
Drop the request and emit a warning log on the host side. This is the default. Equivalent to ViolationAction.BLOCK_AND_LOG.
@classmethod
def block_and_terminate(cls) -> ViolationPolicy
Drop the request, log an error, and shut down the entire sandbox. Equivalent to ViolationAction.BLOCK_AND_TERMINATE.
@classmethod
def passthrough(
cls,
*,
hosts: Sequence[str] = (),
host_patterns: Sequence[str] = (),
all_hosts: bool = False,
) -> ViolationPolicy
Forward the placeholder unchanged to matching hosts instead of blocking. Passthrough hosts do not make a secret eligible for substitution; they only prevent blocking when the guest sends the placeholder to a matching host, so the request is forwarded with the placeholder intact. Hosts outside the passthrough set fall back to BLOCK_AND_LOG.
from microsandbox import Secret, ViolationPolicy
secret = Secret.env(
"API_KEY",
value=os.environ["API_KEY"],
allow_hosts=["api.github.com"],
on_violation=ViolationPolicy.passthrough(
hosts=["api.anthropic.com"],
host_patterns=["*.anthropic.com"],
),
)
A single secret entry, used in Sandbox.create(secrets=[...]). Construct it with Secret.env() rather than directly.
| Field | Type | Default | Description |
|---|---|---|---|
| env_var | str | required | Environment variable name (non-empty, no = or NUL) |
| value | str | required | Secret value. Never enters the guest |
| allow_hosts | tuple[str, ...] | () | Allowed hosts (exact match) |
| allow_host_patterns | tuple[str, ...] | () | Wildcard patterns |
| placeholder | str | None | None | Placeholder string: non-empty, up to 1024 bytes, no NUL/CR/LF. Auto-generated as $MSB_<env_var> when None |
| require_tls | bool | True | Only substitute on TLS-intercepted connections |
| on_violation | ViolationAction | ViolationPolicy | BLOCK_AND_LOG | Per-secret violation behavior |
| injection | SecretInjection | SecretInjection() | Per-request injection scopes |
Controls where in the HTTP request the secret value can be substituted.
| Field | Type | Default | Description |
|---|---|---|---|
| headers | bool | True | Substitute the placeholder anywhere it appears in the headers. |
| basic_auth | bool | True | Decode Authorization: Basic <base64> credentials, substitute the placeholder in the decoded user:password, and re-encode. Other schemes (Bearer, Digest) are handled by headers. |
| query_params | bool | False | Substitute in the request line's query string. |
| body | bool | False | Substitute 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. |
String enum (StrEnum) defining the action taken when a secret placeholder is sent to a disallowed host.
| Member | Value | Description |
|---|---|---|
BLOCK | "block" | Silently drop the request. The guest sees a connection reset. |
BLOCK_AND_LOG | "block-and-log" | Drop the request and emit a warning log on the host side. This is the default. |
BLOCK_AND_TERMINATE | "block-and-terminate" | Drop the request, log an error, and shut down the entire sandbox. |
PASSTHROUGH | "passthrough" | Forward matching hosts with the placeholder unchanged. Non-matching hosts use the default secret violation action. |
Secret violation behavior, including optional passthrough hosts. Construct it with the classmethods (block(), block_and_log(), block_and_terminate(), passthrough()) rather than setting fields directly.
| Field | Type | Default | Description |
|---|---|---|---|
| fallback | ViolationAction | BLOCK_AND_LOG | Action for hosts not covered by the passthrough set |
| passthrough_hosts | tuple[str, ...] | () | Exact hosts forwarded with the placeholder unchanged |
| passthrough_host_patterns | tuple[str, ...] | () | Wildcard patterns forwarded with the placeholder unchanged |
| passthrough_all_hosts | bool | False | Forward the placeholder unchanged to every host |
Raised when a secret placeholder was sent to a disallowed host. Carries code = "secret-violation".