---
title: TLS interception
description: Inspect HTTPS traffic and manage certificate trust
icon: "lock"
---

<Tooltip tip="TLS interception and host CA trust are not available on Microsandbox Cloud."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

TLS interception lets Microsandbox inspect HTTPS traffic. This enables URL policy checks, request logging, and secure secret injection for matching hosts.

## How it works

When interception is enabled, Microsandbox:

1. Loads an interception certificate authority, or CA.
2. Adds that CA to the guest's trust store.
3. Creates a certificate for each intercepted host.
4. Opens a separate verified TLS connection to the upstream server.

The default CA is stored at `~/.microsandbox/tls/ca.{crt,key}` and reused by local sandboxes. Delete both files to generate a new CA. Use the intercept CA certificate and key settings when sandboxes should use a CA that you provide.

## Enabling interception

<CodeGroup>
```rust Rust
use microsandbox::Sandbox;

let sb = Sandbox::builder("worker")
    .image("python")
    .network(|n| n.tls(|t| t
        .bypass("pinned-api.example.com")
        .bypass("*.gov")
    ))
    .create()
    .await?;
```

```typescript TypeScript
import { Sandbox } from "microsandbox";

await using sb = await Sandbox.builder("worker")
  .image("python")
  .network((n) => n.tls((t) =>
    t.bypass("pinned-api.example.com").bypass("*.gov"),
  ))
  .create();
```

```python Python
from microsandbox import Network, Sandbox, TlsConfig

sb = await Sandbox.create(
    "worker",
    image="python",
    network=Network(
        tls=TlsConfig(bypass=("pinned-api.example.com", "*.gov")),
    ),
)
```

```go Go
sb, err := m.CreateSandbox(ctx, "worker",
    m.WithImage("python"),
    m.WithNetwork(&m.NetworkConfig{
        TLS: &m.TLSConfig{
            Bypass: []string{"pinned-api.example.com", "*.gov"},
        },
    }),
)
```

```bash CLI
msb create python --name worker \
  --tls-intercept \
  --tls-bypass "pinned-api.example.com" \
  --tls-bypass "*.gov"
```
</CodeGroup>

## Bypass patterns

Some clients trust a specific certificate or public key instead of the guest's trust store. Interception will fail for these clients.

Add their hosts to the bypass list. Exact domains such as `api.example.com` and wildcards such as `*.apple.com` are supported. Bypassed traffic stays encrypted between the guest and upstream server, so content-based policy checks and secret injection do not apply.

## Upstream CA trust

The proxy verifies upstream certificates with the host's root store by default. You can add:

- a CA trusted for every intercepted host
- a CA trusted only for matching hosts
- a host pattern that skips upstream verification

<CodeGroup>
```rust Rust
let sb = Sandbox::builder("agent")
    .image("python")
    .network(|n| n.tls(|t| t
        .upstream_ca_cert("/etc/ssl/corp-root.pem")
        .upstream_ca_cert_for("api.internal.example.com", "./certs/api-ca.pem")
        .verify_upstream_for("*.preview.internal", false)
    ))
    .create()
    .await?;
```

```bash CLI
msb create python --name agent \
  --tls-intercept \
  --tls-upstream-ca-cert /etc/ssl/corp-root.pem \
  --tls-upstream-ca-cert-for 'api.internal.example.com=./certs/api-ca.pem' \
  --tls-no-verify-upstream-for '*.preview.internal'
```
</CodeGroup>

Skipping verification is similar to using `curl -k`. Use it only for hosts you control and only when a trusted CA is not available.

## Limits

- Clients that pin certificates or public keys must be bypassed.
- Bypassed traffic cannot use content-based policy checks or secret injection.
- Guest client certificates are not proxied. Bypass hosts that require guest mTLS.
- QUIC and HTTP/3 traffic are not intercepted.

## Trusting host CAs

Corporate proxies often replace server certificates with certificates signed by a company CA. The host trusts that CA, but a sandbox normally does not. Commands such as `apk update`, `pip install`, and `curl` can then fail with a certificate error.

Enable host CA trust to copy trusted host roots into the guest when it starts:

<CodeGroup>
```rust Rust
let sb = Sandbox::builder("devbox")
    .image("alpine")
    .network(|n| n.trust_host_cas(true))
    .create()
    .await?;
```

```typescript TypeScript
await using sb = await Sandbox.builder("devbox")
  .image("alpine")
  .network((n) => n.trustHostCAs(true))
  .create();
```

```python Python
sb = await Sandbox.create(
    "devbox",
    image="alpine",
    network=Network(trust_host_cas=True),
)
```

```go Go
trustHostCAs := true
sb, err := m.CreateSandbox(ctx, "devbox",
    m.WithImage("alpine"),
    m.WithNetwork(&m.NetworkConfig{
        TrustHostCAs: &trustHostCAs,
    }),
)
```

```bash CLI
msb run alpine --trust-host-cas -- apk update
```
</CodeGroup>

<Note>
Host CA trust gives the guest every root certificate trusted by the host. Enable it only when you trust the host's CA store.
</Note>

## Interaction with TLS interception

TLS interception covers configured ports, with port `443` enabled by default. TLS interception and host CA trust solve different problems:

| Feature | Covers |
| --- | --- |
| TLS interception | Configured TLS ports and hosts that are not bypassed |
| Host CA trust | Any guest connection that uses the guest's system trust store |

Use both when you need HTTPS inspection and also need raw TLS connections to trust corporate certificates. Raw TLS includes bypassed hosts, custom TLS ports, and protocols such as Postgres or Redis over TLS.

## See also

- [DNS](/networking/dns) explains DNS policy and DNS over TLS.
- [Network defenses](/security/network) explains SSRF protection.
- [Secret handling](/security/secrets) explains credential injection.
