docs/sdk/python/secrets.mdx
See Secrets for how placeholder substitution works and usage examples.
Static factory for creating secret entries used in SandboxConfig.secrets.
@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.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| env_var | str | - | Environment variable name. Must be non-empty and cannot contain = or NUL; shell-identifier syntax is not required. |
| value | str | - | The real secret value. Never enters the guest VM. Required. |
| allow_hosts | Sequence[str] | () | Hosts allowed to receive the real value (exact match). At least one exact or wildcard host is required. The TLS proxy matches against the SNI and the sandbox DNS pin set. |
| allow_host_patterns | Sequence[str] | () | Wildcard host patterns (e.g. "*.googleapis.com") |
| placeholder | str | None | None | Custom placeholder string: non-empty, up to 1024 bytes, no NUL/CR/LF. Auto-generated as $MSB_<env_var> if not set. |
| require_tls | bool | True | Only substitute on TLS-intercepted connections. Disable only if you know the traffic is safe. |
| on_violation | ViolationAction | ViolationPolicy | BLOCK_AND_LOG | Per-secret violation behavior |
| injection | SecretInjection | None | None | Where in the HTTP request to substitute. None uses the defaults. |
Returns
| Type | Description |
|---|---|
SecretEntry | Secret entry for SandboxConfig.secrets |
Python host settings map to the runtime HostPattern model. Allow-list fields decide where the real secret value may be substituted; passthrough fields decide where the placeholder may be forwarded unchanged.
| Pattern kind | Python API | Matches |
|---|---|---|
| Exact host | allow_hosts=("api.example.com",), ViolationPolicy.passthrough(hosts=("api.example.com",)) | That exact SNI host |
| Wildcard host | allow_host_patterns=("*.example.com",), ViolationPolicy.passthrough(host_patterns=("*.example.com",)) | Hosts matching the wildcard pattern |
| Any host | ViolationPolicy.passthrough(all_hosts=True) | Every host for passthrough |
Passthrough host patterns 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 unchanged.
Exact and wildcard allow-list entries require both a matching TLS SNI and an observed DNS answer tying the original guest destination IP to that host. Empty allow-lists are rejected when the sandbox configuration is materialized. Intercepted HTTP requests must also have an authority matching the TLS SNI, ignoring case and an optional port: Host for HTTP/1 and :authority for observed HTTP/2.
Frozen dataclass returned by Secret.env() and used in SandboxConfig.secrets.
| Field | Type | Description |
|---|---|---|
| env_var | str | Environment variable name (non-empty, no = or NUL) |
| value | str | Secret value |
| allow_hosts | tuple[str, ...] | Allowed hosts (exact match) |
| allow_host_patterns | tuple[str, ...] | Wildcard patterns |
| placeholder | str | None | Placeholder string: non-empty, up to 1024 bytes, no NUL/CR/LF |
| require_tls | bool | TLS requirement |
| on_violation | ViolationAction | ViolationPolicy | Per-secret violation behavior |
| injection | SecretInjection | Per-request injection scopes |
Frozen dataclass controlling where in the HTTP request the secret value is 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 HTTP/1 request bodies with no body content encoding. Adjusts Content-Length for fixed-length bodies up to 16 MiB and blocks larger fixed-length bodies; chunked bodies are decoded and re-encoded with fresh chunk sizes. Chunk trailers are preserved; original chunk boundaries and extensions are not. Encoded bodies are forwarded unchanged. HTTP/2 DATA-frame body substitution is not supported yet; matching body placeholders are blocked. |
String enum (StrEnum) defining the action taken when a secret placeholder is sent to a disallowed host.
| Value | Description |
|---|---|
"block" | Silently drop the request. The guest sees a connection reset. |
"block-and-log" | Drop the request and emit a warning log on the host side. This is the default. |
"block-and-terminate" | Drop the request, log an error, and shut down the entire sandbox. |
"passthrough" | Forward matching hosts with the placeholder unchanged. Non-matching hosts use the default secret violation action. |
Frozen dataclass for passthrough host policies. Use ViolationPolicy.passthrough(...) when selected hosts should receive placeholders unchanged.
ViolationPolicy.passthrough(
hosts=("api.anthropic.com",),
host_patterns=("*.example.com",),
all_hosts=False,
)