docs/networking/outbound-proxy.mdx
Configure one SOCKS4 or SOCKS5 proxy for outbound sandbox traffic. The guest connects to its normal destination; microsandbox routes eligible traffic through the proxy on the host.
<Note>Outbound proxies are local-only. Cloud sandbox creation rejects this setting.</Note>
| Proxy | Authentication | Traffic | Availability |
|---|---|---|---|
| SOCKS4 | None | TCP | SDKs and CLI |
| SOCKS4 | Optional user ID | TCP | SDKs and CLI |
| SOCKS5 | None | TCP and non-DNS UDP | SDKs and CLI |
| SOCKS5 | Optional username and password | TCP and non-DNS UDP | SDKs and CLI |
Only one proxy can be configured for a sandbox. A SOCKS4 user ID identifies the caller; it is not a password.
await using sb = await Sandbox.builder("proxied") .image("python") .proxy((p) => p.socks5("127.0.0.1:1080")) .create();
```rust Rust
use microsandbox::Sandbox;
let sb = Sandbox::builder("proxied")
.image("python")
.proxy(|p| p.socks5("127.0.0.1:1080"))
.create()
.await?;
from microsandbox import OutboundProxy, Sandbox
sb = await Sandbox.create(
"proxied",
image="python",
proxy=OutboundProxy.socks5("127.0.0.1:1080"),
)
sb, err := m.CreateSandbox(ctx, "proxied",
m.WithImage("python"),
m.WithProxy(m.SOCKS5Proxy("127.0.0.1:1080")),
)
# Choose one:
msb create python --name proxied --proxy socks4://127.0.0.1:1080
msb create python --name proxied --proxy socks5://127.0.0.1:1080
SDK addresses use IP:port. The msb run and msb create commands accept --proxy socks4://IP:port or --proxy socks5://IP:port. Proxy URIs reject user information, paths, query parameters, and fragments; protocol-specific authentication uses separate CLI flags.
Add an optional user ID through an SDK or --socks4-user-id in the CLI.
.proxy(|p| p.socks4("127.0.0.1:1080").user_id("sandbox"))
proxy=OutboundProxy.socks4("127.0.0.1:1080", user_id="sandbox")
m.WithProxy(m.SOCKS4Proxy(
"127.0.0.1:1080",
m.SOCKS4ProxyOptions{UserID: "sandbox"},
))
msb run alpine \
--proxy socks4://127.0.0.1:1080 \
--socks4-user-id sandbox
The user ID must contain 1–255 bytes and cannot contain a null byte. Omit it to use SOCKS4 without a user ID.
SOCKS5 supports optional username/password authentication. Passwords are loaded from a host environment variable rather than placed directly in configuration.
<CodeGroup> ```typescript TypeScript .proxy((proxy) => proxy.socks5("127.0.0.1:1080").credentials( "sandbox", SecretSource.env("SOCKS5_PASSWORD"), ), ) ```.proxy(|proxy| {
proxy.socks5("127.0.0.1:1080").credentials(
"sandbox",
SecretSource::env("SOCKS5_PASSWORD"),
)
})
proxy = OutboundProxy.socks5("127.0.0.1:1080").credentials(
"sandbox",
SecretSource.env("SOCKS5_PASSWORD"),
)
proxy := m.SOCKS5Proxy("127.0.0.1:1080").Credentials(
"sandbox",
m.SecretSourceEnv("SOCKS5_PASSWORD"),
)
m.WithProxy(proxy)
msb run alpine \
--proxy socks5://127.0.0.1:1080 \
--socks5-username sandbox \
--socks5-password-env SOCKS5_PASSWORD
Environment variables are currently the only supported password source. The password is read from the host environment once each time the sandbox starts and reused for that run. Changing the environment variable affects the next start, not a sandbox that is already running. The username and resolved password must each contain 1–255 bytes; startup fails if the environment variable is missing, empty, or invalid.
Durable configuration and the database store the environment-variable reference, such as SOCKS5_PASSWORD, but never the resolved password.
SOCKS5 authentication does not encrypt credentials on the wire. Use a trusted local or private proxy, or protect the connection at the transport layer.
CONNECT for TCP and UDP ASSOCIATE for non-DNS UDP.host.microsandbox.internal bypass the proxy and continue to target the microsandbox host.For exact proxy APIs, see TypeScript, Rust, Python, or Go. For CLI flags, see Sandbox commands.