Proxy Mode¶
Network isolation, traffic inspection, and HTTP filtering.
Proxy mode routes all HTTP/HTTPS traffic through a local MITM (Man-in-the-Middle) proxy for inspection and logging. The sections below describe bwrap backend behavior by default. The Docker backend achieves the same goal with different mechanisms - see Backend-Specific Behavior for details.
Why Use Proxy Mode?¶
- Audit AI agent activity - See exactly what API calls your AI coding assistant makes
- Debug network issues - Inspect request/response headers and bodies
- Security monitoring - Detect unexpected network connections
- Compliance - Log all external communications for review
When to Enable Proxy Mode¶
| Enable proxy when | Skip proxy when |
|---|---|
| You want to monitor AI agent network activity | You trust the code and don't need traffic visibility |
| You need credential injection (GitHub tokens) | Tools use certificate pinning that breaks MITM |
| You need port forwarding (requires network isolation) | You want the fastest possible startup |
| You need content redaction (secret scanning) | You only need filesystem isolation |
| You need HTTP filtering (domain whitelist/blacklist) |
Requirements (bwrap backend)¶
Proxy mode on the bwrap backend requires passt/pasta for network namespace creation. This is the only feature that requires passt-basic sandboxing works without it.
devsandbox includes an embedded pasta binary - no system packages required. To use a system-installed pasta instead, set use_embedded = false in configuration.
Docker backend: The Docker backend does NOT require pasta. It uses per-session Docker networks for isolation instead. See Backend-Specific Behavior.
Optionally install the system package as a fallback:
# Arch Linux
sudo pacman -S passt
# Debian/Ubuntu
sudo apt install passt
# Fedora
sudo dnf install passt
Verify installation:
The doctor output shows whether each binary is embedded or system-installed.
Enabling Proxy Mode¶
Command Line¶
# Enable proxy mode for this session
devsandbox --proxy
# With custom port
devsandbox --proxy --proxy-port 9090
# Run a command with proxy
devsandbox --proxy npm install
Configuration File¶
Enable proxy mode by default in ~/.config/devsandbox/config.toml:
Transparent Proxy Mode (No MITM)¶
By default, the proxy performs MITM (Man-in-the-Middle) interception on HTTPS connections, using a generated CA certificate. This enables full traffic inspection, credential injection, and content redaction for HTTPS.
If you don't need HTTPS inspection - for example, when tools have certificate pinning or you only need network isolation with HTTP logging - you can disable MITM:
Command Line¶
Configuration File¶
What Changes¶
| Feature | MITM enabled (default) | MITM disabled |
|---|---|---|
| HTTP filtering/logging | Full | Full |
| HTTPS body/header inspection | Full | None |
| HTTPS credential injection | Works | Does not work |
| HTTPS content redaction | Works | Does not work |
| HTTPS request logging | Full request/response | CONNECT hostname only |
| CA certificate injection | Yes | Skipped |
| Network isolation | Yes | Yes |
When MITM is disabled, the proxy logs warnings at startup if credential injectors, redaction rules, or filter rules are configured - since these features cannot inspect encrypted HTTPS traffic.
When to disable MITM:
- Tools with certificate pinning that reject the proxy CA
- You only need network isolation and HTTP (not HTTPS) logging
- You don't need credential injection, content redaction, or HTTPS filtering
If you're running AI coding assistants (Claude Code, aider, etc.), keep MITM enabled - it's required for credential injection and secret scanning.
Backend-Specific Behavior¶
The proxy achieves the same goal on both backends - intercept and log HTTP/HTTPS traffic - but the underlying mechanisms differ.
bwrap backend¶
- Network isolation: pasta creates a new network namespace with its own network stack
- Gateway address: Traffic is routed through
10.0.2.2(pasta virtual gateway) - CA certificate path (inside sandbox):
/tmp/devsandbox-ca.crt - Requirement: passt/pasta must be installed
Docker backend¶
- Network isolation: A per-session Docker network is created (no pasta required)
- Gateway address:
host.docker.internal(Docker's built-in host access) - CA certificate path (inside container):
/etc/ssl/certs/devsandbox-ca.crt - Requirement: Docker daemon running (no additional dependencies)
| Aspect | bwrap | Docker |
|---|---|---|
| Network isolation | pasta namespace | Per-session Docker network |
| Gateway IP | 10.0.2.2 |
host.docker.internal |
| CA cert location | /tmp/devsandbox-ca.crt |
/etc/ssl/certs/devsandbox-ca.crt |
| Extra dependency | passt/pasta | None (Docker only) |
How It Works (bwrap)¶
- Network Isolation - pasta creates a new network namespace with its own network stack
- Gateway Setup - Traffic is routed through a virtual gateway (10.0.2.2)
- Proxy Server - A local HTTP/HTTPS proxy runs on the host
- Traffic Enforcement - All HTTP(S) traffic must go through the proxy
- TLS Interception - A generated CA certificate enables HTTPS inspection
Network Architecture¶
flowchart TB
subgraph host["Host System"]
proxy["Proxy Server<br/>127.0.0.1:8080"]
internet(["Internet"])
proxy --> internet
end
subgraph sandbox["Sandbox (netns)"]
app["Application<br/>HTTP_PROXY=10.0.2.2:8080"]
gateway["Gateway<br/>10.0.2.2"]
app --> gateway
end
gateway -. "pasta NAT<br/>10.0.2.2 → 127.0.0.1" .-> proxy
CA Certificate¶
A CA certificate is automatically generated for HTTPS interception and stored at:
Inside the sandbox, the certificate is available at /tmp/devsandbox-ca.crt (bwrap backend) or /etc/ssl/certs/devsandbox-ca.crt (Docker backend) and automatically configured via
environment variables:
| Variable | Purpose |
|---|---|
NODE_EXTRA_CA_CERTS |
Node.js |
REQUESTS_CA_BUNDLE |
Python requests |
CURL_CA_BUNDLE |
curl |
GIT_SSL_CAINFO |
Git HTTPS |
SSL_CERT_FILE |
General SSL/TLS |
Tools with Certificate Pinning¶
Some tools implement certificate pinning and won't work with the MITM proxy:
- Mobile app backends
- Some cloud SDKs
- Security-focused applications
Viewing Logs¶
Proxy Request Logs¶
View HTTP/HTTPS traffic captured in proxy mode:
# View all proxy logs for current project
devsandbox logs proxy
# View last 50 requests
devsandbox logs proxy --last 50
# Follow/tail logs in real-time
devsandbox logs proxy -f
Filtering Logs¶
# Filter by time
devsandbox logs proxy --since 1h # Last hour
devsandbox logs proxy --since today # Since midnight
devsandbox logs proxy --since 2024-01-15 # Since specific date
devsandbox logs proxy --until 2024-01-15T12:00:00
# Filter by content
devsandbox logs proxy --url /api # URL contains "/api"
devsandbox logs proxy --method POST # Only POST requests
devsandbox logs proxy --status 200 # Specific status code
devsandbox logs proxy --status 400-599 # Status code range
devsandbox logs proxy --status ">=400" # Comparison
devsandbox logs proxy --errors # All errors (status >= 400)
# Combine filters
devsandbox logs proxy --method POST --url /api --since 1h
Output Formats¶
# Table format (default)
devsandbox logs proxy
# Compact one-line format
devsandbox logs proxy --compact
# JSON output (for scripting)
devsandbox logs proxy --json
# Include request/response bodies
devsandbox logs proxy --body
# Show summary statistics
devsandbox logs proxy --stats
# Disable colors (for piping)
devsandbox logs proxy --no-color
Example Output¶
Table format:
┌──────────┬────────┬────────┬──────────┬────────────────────────┐
│ TIME │ METHOD │ STATUS │ DURATION │ URL │
├──────────┼────────┼────────┼──────────┼────────────────────────┤
│ 10:30:05 │ GET │ 200 │ 150ms │ https://api.example.com│
│ 10:30:06 │ POST │ 201 │ 89ms │ https://api.example.com│
└──────────┴────────┴────────┴──────────┴────────────────────────┘
Compact format:
10:30:05 GET 200 150ms https://api.example.com/users
10:30:06 POST 201 89ms https://api.example.com/orders
Stats output:
Summary:
Total requests: 150
Success (2xx): 120 (80.0%)
Redirect (3xx): 10 (6.7%)
Client err (4xx): 15 (10.0%)
Server err (5xx): 5 (3.3%)
Avg duration: 245ms
Log Storage¶
Logs are stored as gzip-compressed JSONL files:
~/.local/share/devsandbox/<project>/logs/
├── proxy/
│ ├── requests_20240115_0000.jsonl.gz
│ ├── requests_20240115_0001.jsonl.gz
│ └── ...
└── internal/
├── proxy_20240115_0000.log.gz
└── logging-errors.log
Log Rotation¶
- Files rotate when they reach 50MB
- Maximum 5 files kept per type
- Older files are automatically pruned
Log Entry Format¶
Each log entry contains:
{
"ts": "2024-01-15T10:30:05.123Z",
"method": "POST",
"url": "https://api.example.com/users",
"req_headers": {
"Content-Type": [
"application/json"
],
"Authorization": [
"Bearer ..."
]
},
"req_body": "eyJ1c2VyIjogImpvaG4ifQ==",
"status": 201,
"resp_headers": {
"Content-Type": [
"application/json"
]
},
"resp_body": "eyJpZCI6IDEyM30=",
"duration_ns": 89000000,
"error": ""
}
Note: Request/response bodies are base64-encoded.
Internal Logs¶
View proxy server errors and warnings:
# View all internal logs
devsandbox logs internal
# Filter by log type
devsandbox logs internal --type proxy # Proxy server logs
devsandbox logs internal --type logging # Remote logging errors
# Follow internal logs
devsandbox logs internal -f
# Show last N lines
devsandbox logs internal --last 100
Remote Logging¶
Proxy logs can be forwarded to remote destinations. See Configuration - Remote Logging for setup instructions.
HTTP Filtering¶
HTTP filtering allows you to control which requests are allowed, blocked, or require user approval.
How It Works¶
Filtering is enabled by setting default_action which determines what happens to requests that don't match any rule:
| Default Action | Behavior |
|---|---|
block |
Block unmatched requests (whitelist behavior) |
allow |
Allow unmatched requests (blacklist behavior) |
ask |
Prompt user for each unmatched request |
Quick Start¶
# Whitelist behavior - only allow specific domains, block everything else
devsandbox --proxy --filter-default=block \
--allow-domain="*.github.com" \
--allow-domain="api.anthropic.com"
# Blacklist behavior - block specific domains, allow everything else
devsandbox --proxy --filter-default=allow \
--block-domain="*.tracking.io" \
--block-domain="ads.example.com"
# Ask mode - interactive approval for unmatched requests
devsandbox --proxy --filter-default=ask
Configuration File¶
Add filter rules to ~/.config/devsandbox/config.toml:
[proxy.filter]
# Enable filtering with default action for unmatched requests
default_action = "block" # whitelist behavior
ask_timeout = 30
cache_decisions = true
[[proxy.filter.rules]]
pattern = "*.github.com"
action = "allow"
scope = "host"
[[proxy.filter.rules]]
pattern = "api.anthropic.com"
action = "allow"
scope = "host"
[[proxy.filter.rules]]
pattern = "*.internal.corp"
action = "block"
scope = "host"
reason = "Internal network blocked"
AI Agent Filtering Example¶
Lock down an AI coding assistant to only communicate with known services:
[proxy.filter]
default_action = "block"
[[proxy.filter.rules]]
pattern = "api.anthropic.com"
action = "allow"
scope = "host"
[[proxy.filter.rules]]
pattern = "*.github.com"
action = "allow"
scope = "host"
[[proxy.filter.rules]]
pattern = "registry.npmjs.org"
action = "allow"
scope = "host"
You can generate filter rules from a "known good" session using devsandbox proxy filter generate (see Generate Filter Rules).
Pattern Types¶
Default is glob. Patterns containing regex characters (^$|()[]{}\+) are auto-detected as regex.
| Type | Example | Description |
|---|---|---|
glob |
*.example.com |
Glob patterns ( and ?) - default* |
exact |
api.example.com |
Exact string match |
regex |
^api\.(dev\|prod)\.com$ |
Regular expressions |
Scopes¶
Default is host.
| Scope | Description | Example Match |
|---|---|---|
host |
Request host only - default | api.example.com |
path |
Request path only | /api/v1/users |
url |
Full URL | https://api.example.com/v1/users |
Ask Mode¶
In ask mode, unmatched requests require user approval via a separate monitor terminal. This is particularly useful when running AI agents autonomously - you can approve or block each network request the agent makes, giving you real-time control over what data leaves your machine.
Step 1: Start the sandbox with ask mode:
The sandbox will display:
Filter: ask mode (default action for unmatched requests)
Run in another terminal to approve/deny requests:
devsandbox proxy monitor
Requests without response within 30s will be rejected.
Step 2: Open another terminal (in the same project directory) and run the monitor:
The socket path is auto-detected from the current directory's sandbox. You can also specify it explicitly:
The monitor displays incoming requests:
┌──────────────────────────────────────────────────────────────────┐
│ Request #1 │
├──────────────────────────────────────────────────────────────────┤
│ Method: GET │
│ Host: api.example.com │
│ Path: /v1/users │
├──────────────────────────────────────────────────────────────────┤
│ [A]llow [B]lock Allow [S]ession Block [N]ever │
└──────────────────────────────────────────────────────────────────┘
Decision:
Keys (instant response, no Enter needed):
a- Allow this requestb- Block this requests- Allow and remember for sessionn- Block and remember for session
Timeout: Requests that don't receive a response within 30 seconds are automatically rejected and logged to internal logs as unanswered.
Generate Filter Rules from Logs¶
Analyze existing proxy logs to generate filter configuration:
# Generate whitelist rules from current project's logs (default: block unmatched)
devsandbox proxy filter generate
# Generate from specific log directory
devsandbox proxy filter generate --from-logs ~/.local/share/devsandbox/myproject/logs/proxy/
# Generate blacklist rules (allow unmatched)
devsandbox proxy filter generate --default-action allow
# Save to file
devsandbox proxy filter generate -o filter-rules.toml
# Only include domains with 5+ requests
devsandbox proxy filter generate --min-requests 5
Show Current Configuration¶
Filter Logs¶
Filter decisions are logged with requests:
{
"ts": "2024-01-15T10:30:05Z",
"method": "GET",
"url": "https://blocked.example.com/",
"status": 403,
"filter_action": "block",
"filter_reason": "matched rule: *.blocked.com"
}
Credential Injection¶
The proxy can inject authentication credentials into requests for specific domains, keeping tokens completely out of the sandbox environment. The sandboxed process never sees the token - it stays on the host side.
How It Works¶
- Intercept - The proxy intercepts outgoing requests from the sandbox.
- Match - For each configured credential injector, it checks whether the request host matches the injector's
host(exact match or glob). - Inject - If matched, the injector sets the configured
headerto the renderedvalue_formatwith{token}substituted from the resolvedsource. The existing header is preserved unlessoverwrite = true. - Isolate - The sandbox process never sees the token. It is read from the host environment and added transparently.
sequenceDiagram
autonumber
participant App as Sandboxed app
participant Proxy as devsandbox proxy
participant Source as Host token source
participant Upstream as Upstream API
App->>Proxy: HTTPS request, no Authorization
Note over Proxy: MITM decrypt, match host<br/>against injector globs
alt host matches an injector
Proxy->>Source: Resolve credential<br/>from env, file, or value
Source-->>Proxy: token
Note over Proxy: Render value_format,<br/>set header unless already set<br/>or overwrite = true
Proxy->>Upstream: HTTPS request + Authorization
Upstream-->>Proxy: response
Proxy-->>App: response, token never returns
else no injector matches
Proxy->>Upstream: HTTPS request, unchanged
Upstream-->>Proxy: response
Proxy-->>App: response
end
Universal Schema¶
Every injector is defined by the same set of fields under [proxy.credentials.<name>]:
| Field | Purpose |
|---|---|
enabled |
Master switch. Injector is inert unless enabled = true. |
host |
Hostname to match. Exact (api.github.com) or glob (*.example.com). |
header |
HTTP header to set on matching requests. Canonicalized at load (authorization → Authorization). |
value_format |
Template for the header value. {token} is replaced with the resolved source value. Defaults to "{token}". |
overwrite |
When true, replaces any existing value for the configured header. Default false. |
preset |
Optional name of a built-in preset whose defaults are used as the base for this injector. |
[...source] sub-table |
Where the token comes from: env, file, or value. |
A custom non-GitHub injector - no Go code required:
[proxy.credentials.gitlab]
enabled = true
host = "gitlab.com"
header = "PRIVATE-TOKEN"
value_format = "{token}"
[proxy.credentials.gitlab.source]
env = "GITLAB_TOKEN"
Built-in Presets¶
Built-in preset names are reserved - using one as the section name (e.g. [proxy.credentials.github]) automatically applies the preset's defaults. User fields override preset defaults; [...source] overrides the preset's default source.
| Preset | host |
header |
value_format |
Default source |
|---|---|---|---|---|
github |
api.github.com |
Authorization |
Bearer {token} |
env = "GITHUB_TOKEN" (with GH_TOKEN fallback when no explicit source is set) |
Minimal GitHub configuration - the preset supplies everything else:
Source Types¶
| Field | Description | Example |
|---|---|---|
env |
Read from an environment variable | env = "DEVSANDBOX_GITHUB_TOKEN" |
file |
Read from a file (supports ~ expansion, whitespace trimmed) |
file = "~/.config/devsandbox/github-token" |
value |
Static value in config | value = "github_pat_..." |
When multiple fields are set, priority is: value > env > file. Set exactly one for clarity.
Specificity Ordering¶
When more than one configured injector could match the same request host, the most-specific one wins:
- Exact host beats any glob.
- Among globs, the longer literal portion (
len(host) - count('*')) wins. - Ties are broken by injector name in alphabetical order.
So an exact api.github.com injector wins over a *.github.com injector for api.github.com, and the proxy injects exactly one credential per request.
A glob that doesn't match any actual request is not an error - host coverage is enforced lazily at request time, not at config load.
Overwriting Existing Authorization Headers¶
By default the injector never replaces an existing value for its configured header - the sandboxed tool wins. That's safe, but breaks the pattern where a CLI inside the sandbox needs a token set in its environment to start (e.g. gh CLI refuses to run without GH_TOKEN).
To handle this, set overwrite = true and inject a placeholder env var into the sandbox so the CLI starts:
[sandbox.environment.GH_TOKEN]
value = "placeholder"
[proxy.credentials.github]
enabled = true
overwrite = true
[proxy.credentials.github.source]
env = "GH_RO_TOKEN" # real read-only token on the host
Export GH_RO_TOKEN on the host only. The sandbox sees GH_TOKEN=placeholder; gh adds Authorization: Bearer placeholder to its requests; the proxy replaces the header with the real token from GH_RO_TOKEN before forwarding to api.github.com.
Security trade-off: the sandbox sees a non-functional placeholder, not the real token - leaking the placeholder is harmless. This preserves the core guarantee: the real credential never enters the sandbox.
AI agent workflow: Credential injection is particularly useful for AI coding assistants like Claude Code that need GitHub API access. The token stays on the host - the AI agent never sees it, but its API requests to github.com are automatically authenticated.
Notes:
- Credential injection requires proxy mode (
--proxy) with MITM enabled (the default). - Injectors are only active when explicitly
enabled = trueand the credential source resolves to a non-empty value. An empty source silently disables the injector - it is not a config error. - By default the injector never overwrites an existing value for its configured header. Set
overwrite = trueto change this. - Invalid configuration fails fast at load time: unknown
preset, missinghost/headerwhenenabled = true, invalid glob, or unreadable sourcefile.
See Configuration: Proxy Credentials for the complete TOML reference.
Content Redaction¶
Content redaction scans outgoing requests for secrets before they leave your machine. It checks request bodies, headers, and URLs against configured rules.
Actions¶
| Action | What happens |
|---|---|
| Block | Request rejected with HTTP 403. Secret never leaves your machine. |
| Redact | Secret replaced with [REDACTED:<rule-name>] in body, headers, and URL. Modified request forwarded to destination. |
| Log | Request forwarded unmodified. Match recorded in proxy logs as a warning. |
Quick Start¶
# ~/.config/devsandbox/config.toml or .devsandbox.toml
[proxy.redaction]
enabled = true
default_action = "block"
[[proxy.redaction.rules]]
name = "api-key"
[proxy.redaction.rules.source]
env = "API_SECRET_KEY"
Any outgoing request containing the value of $API_SECRET_KEY is blocked with HTTP 403.
Source Types¶
Rules detect secrets using either a source (exact value lookup) or a pattern (regex match).
| Field | Description | Example |
|---|---|---|
env |
Environment variable on the host | env = "API_SECRET_KEY" |
file |
File path (supports ~, whitespace trimmed) |
file = "~/.secrets/token" |
env_file_key |
Key in project .env file |
env_file_key = "DB_PASSWORD" |
value |
Static value in config | value = "literal-secret" |
Choosing an action:
- Block when the secret must never leave your machine (most secure, may break the tool's request)
- Redact when the request should proceed but without the secret (destination sees
[REDACTED:rule-name]) - Log when you want visibility without enforcement (monitoring only)
Log Entries¶
Redaction events appear in proxy logs with additional fields:
{
"ts": "2026-02-23T10:30:05Z",
"method": "POST",
"url": "https://api.example.com/v1/chat",
"status": 403,
"redaction_action": "block",
"redaction_matches": ["api-key"]
}
For the redact action, the logged URL and body contain the replacement placeholders - the original secret never appears in logs.
View redaction events:
Important Behavior¶
- Content redaction requires proxy mode (
--proxy) with MITM enabled. - All source values must resolve at startup. If an environment variable is missing or a file is unreadable, devsandbox exits with an error (fail-closed).
- Log entries for blocked and redacted requests have secrets replaced - secrets never appear in proxy logs.
- Redaction rules are always additive when merging configs. The default action uses most-restrictive-wins.
- Redaction rules must not match values used by credential injectors. If a redaction rule (source or pattern) would match an injected credential, devsandbox exits with an error at startup. This prevents the confusing situation where credential injection adds a token and redaction immediately blocks it.
- When multiple rules match, the most severe action wins: block > redact > log.
Configuration Reference¶
See Configuration: Content Redaction for the full TOML reference, pattern rules, and merge behavior.
Skipping Log Entries¶
Log-skip rules drop matching requests from the proxy log entirely. This is for noise reduction, not for security: matched requests still pass through (filtering, redaction, and credential injection still apply); they simply never appear in logs/proxy/requests.jsonl and are never forwarded to remote log dispatchers (syslog/OTLP).
The intended use case is endpoints you'd otherwise see hundreds of times per session and don't care about - for example, telemetry traffic that an agent sends to your own observability infrastructure, where the data is already captured upstream.
How It Works¶
Each rule has a pattern and an optional scope (default host) and type (default glob, regex auto-detected on metacharacters). Matching reuses the same engine as filter rules: host matches the request hostname (port stripped), path matches the URL path, url matches the full URL string. Rules are evaluated in order, first match wins. Skip is absolute - a matched entry is never logged, even if the request errored, was blocked by the security filter, or triggered a redaction rule.
Configuration¶
[[proxy.log_skip.rules]]
pattern = "telemetry.example.com"
# scope defaults to "host", type auto-detects glob
[[proxy.log_skip.rules]]
pattern = "*/v1/traces"
scope = "url"
type = "glob"
[[proxy.log_skip.rules]]
pattern = "/v1/metrics"
scope = "path"
type = "exact"
Interaction With Other Features¶
- Filter (allow/block): independent. A request blocked by the filter is still skipped from logs if it also matches a
log_skiprule. If you want to keep a record of blocked attempts, do not log-skip the same hosts you block. - Redaction: independent. Redaction still scrubs request/response bodies in flight; log-skip just decides whether the (already-redacted) entry gets persisted.
- Credential injection: independent. Tokens are still injected on outbound requests; log-skip only affects the local log artifact.
Configuration Reference¶
See Configuration: Log Skip for the full TOML reference.
Troubleshooting¶
"proxy mode requires pasta"¶
devsandbox includes an embedded pasta binary. If you see this error, extraction failed and no system package is installed:
# Check doctor for details (shows embedded vs system source)
devsandbox doctor
# Install system package as fallback (see Requirements above)
Requests timing out¶
- Check if the target allows proxy connections
- Some services block known proxy IPs
- Try accessing the URL directly to verify it's reachable
Certificate errors¶
- Ensure the CA environment variables are set correctly
- Some tools require manual CA configuration
- Certificate pinning may prevent interception
No logs appearing¶
- Verify proxy mode is enabled:
devsandbox --proxy --info - Check the log directory exists
- Make HTTP requests (not just TCP connections)
See Also¶
- Sandboxing - filesystem and process isolation, security model
- Configuration: Remote Logging - send proxy logs to syslog or OTLP
- Configuration: Credential Injection - inject tokens into requests without exposing them to the sandbox
- Configuration: Port Forwarding - forward ports between host and sandbox (requires proxy mode)
- Use Cases: Security Monitoring - real-time monitoring and post-session audit scripts