> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Network Packet Flow

> How network packets travel from sandbox workload to the internet through iptables, the TCP proxy, and the TLS layer.

This page traces the path of a network packet from code running inside a sandbox to the internet and back, covering both HTTP and HTTPS flows with and without security scanning.

## Physical network layout

```mermaid theme={null}
graph TB
    subgraph host [Host Machine]
        subgraph rootNS [Root Network Namespace]
            Orch["Orchestrator"]
            HostVeth["veth0-host\n172.20.0.1/30"]
        end
        subgraph sandboxNS [Sandbox Namespace: ns-sbx-abc123 — host-side]
            TAPDev["tap0\n172.16.0.1/24"]
            IPT["iptables\nPREROUTING REDIRECT :80/:443\n+ FORWARD allow/deny"]
            NSProxy["Namespace Proxy\n(HTTP + TLS + other)"]
            NsVeth["veth0-ns\n172.20.0.2/30"]
        end
    end

    subgraph vm [sandbox MicroVM — guest]
        Workload["Agent Workload"]
        GuestNIC["eth0\n172.16.0.2/24"]
        Envd["envd :49983"]
    end

    Internet["Internet"]

    Workload --> GuestNIC
    GuestNIC -->|"L2 via TAP"| TAPDev
    TAPDev --> IPT
    IPT -->|"REDIRECT :80/:443"| NSProxy
    NSProxy --> NsVeth
    NsVeth <--> HostVeth
    HostVeth --> Internet
    Orch <-->|"HTTP/REST"| Envd
```

## Flow 1: HTTPS with no security scanning

When only a domain allowlist (no PII, no injection) is configured, the proxy uses **TLS passthrough** — it inspects the SNI without decrypting.

```mermaid theme={null}
sequenceDiagram
    participant Code as Workload Code
    participant SandboxIPT as Sandbox iptables
    participant NSProxy as Namespace Proxy
    participant Dest as api.openai.com

    Code->>SandboxIPT: TCP SYN to 104.18.x.x:443
    SandboxIPT->>NSProxy: REDIRECT to proxy TLS port
    NSProxy->>NSProxy: Read TLS ClientHello\n(peek first ~300 bytes)
    NSProxy->>NSProxy: Extract SNI: "api.openai.com"
    NSProxy->>NSProxy: Check domain policy\n-> ALLOWED
    NSProxy->>Dest: Forward raw TCP stream\n(no decrypt)
    Dest-->>NSProxy: TLS ServerHello + data
    NSProxy-->>Code: Forward raw TCP response
```

The workload negotiates TLS directly with the destination — the proxy is invisible.

## Flow 2: HTTPS with PII scanning (edge proxy active)

When `PIIConfig.enabled=True`, the proxy performs full TLS interception.

```mermaid theme={null}
sequenceDiagram
    participant Code as Workload Code
    participant SandboxIPT as Sandbox iptables
    participant NSProxy as Namespace Proxy
    participant GS as Guardrails Service
    participant Dest as api.openai.com

    Code->>SandboxIPT: TCP SYN to 104.18.x.x:443
    SandboxIPT->>NSProxy: REDIRECT to proxy TLS port
    NSProxy->>NSProxy: Extract SNI: "api.openai.com"
    NSProxy->>NSProxy: Domain check -> ALLOWED, PII active
    NSProxy->>Code: TLS handshake using\nsandbox-CA-signed cert
    Code->>NSProxy: HTTPS POST /v1/chat/completions\n{messages: [{content: "Name: John Smith, SSN: 123-45-6789"}]}
    NSProxy->>GS: POST /analyze {text: body, scanners: ["pii"]}
    GS-->>NSProxy: {entities: [{type: SSN, start: 34, end: 45}]}
    NSProxy->>NSProxy: Replace SSN with [SSN_9f2a3b]\nStore in session map
    NSProxy->>Dest: HTTPS POST with redacted body
    Dest-->>NSProxy: HTTPS 200 {content: "Summarized [SSN_9f2a3b]..."}
    NSProxy->>NSProxy: Rehydrate [SSN_9f2a3b] -> 123-45-6789
    NSProxy-->>Code: HTTPS 200 {content: "Summarized 123-45-6789..."}
```

## Flow 3: Domain blocked

```mermaid theme={null}
sequenceDiagram
    participant Code as Workload Code
    participant SandboxIPT as Sandbox iptables
    participant NSProxy as Namespace Proxy

    Code->>SandboxIPT: TCP SYN to evil.com:443
    SandboxIPT->>NSProxy: REDIRECT to proxy TLS port
    NSProxy->>NSProxy: Extract SNI: "evil.com"
    NSProxy->>NSProxy: Domain check -> BLOCKED\nWrite audit entry
    NSProxy-->>Code: TCP RST
    Code->>Code: Connection refused error
```

## Flow 4: IP blocked by iptables (CIDR rule)

IP and CIDR rules bypass the userspace proxy entirely — they are kernel-level DROP rules.

```mermaid theme={null}
sequenceDiagram
    participant Code as Workload Code
    participant SandboxIPT as Sandbox iptables\n(in sandbox namespace)

    Code->>SandboxIPT: TCP SYN to 1.2.3.4:443
    SandboxIPT->>SandboxIPT: Match DROP rule\n(1.2.3.4 in deny CIDR)
    SandboxIPT-->>Code: Packet dropped silently
    Code->>Code: Connection timeout
```

## Flow 5: Metadata service block (always-on)

The cloud metadata endpoint `169.254.169.254` is blocked by a hardcoded DROP rule regardless of network policy:

```mermaid theme={null}
sequenceDiagram
    participant Code as Workload Code
    participant SandboxIPT as Sandbox iptables

    Code->>SandboxIPT: TCP SYN to 169.254.169.254:80
    SandboxIPT->>SandboxIPT: Hardcoded DROP rule\n(metadata service protection)
    SandboxIPT-->>Code: Packet dropped
```

## Flow 6: envd traffic (API-to-sandbox)

SDK calls go through the orchestrator to envd via the private veth pair — this traffic never crosses the public network:

```mermaid theme={null}
sequenceDiagram
    participant SDK as Python SDK
    participant Orch as Orchestrator
    participant Veth as Private veth pair\n(172.20.0.x/30)
    participant Envd as envd :49983

    SDK->>Orch: POST /sandboxes/{id}/commands {cmd}
    Orch->>Veth: HTTP ProcessStart(cmd)
    Veth->>Envd: (via TAP bridge into VM)
    Envd->>Envd: exec process
    Envd-->>Orch: Stream stdout/stderr
    Orch-->>SDK: CommandResult
```

## iptables rule structure

All rules live host-side in the sandbox's network namespace — the guest VM has no iptables rules of its own. The orchestrator installs two rule sets per sandbox, both keyed on the TAP interface that carries VM-originated traffic:

### nat table — PREROUTING REDIRECT (on the TAP interface)

Redirects VM-originated TCP onto the namespace proxy's local listeners:

```bash theme={null}
# Redirect HTTP to proxy
iptables -t nat -A PREROUTING -i tap0 -p tcp --dport 80 -j REDIRECT --to-port <proxy_http_port>

# Redirect HTTPS to proxy
iptables -t nat -A PREROUTING -i tap0 -p tcp --dport 443 -j REDIRECT --to-port <proxy_tls_port>

# Redirect other TCP (non-80/443) for domain checking
iptables -t nat -A PREROUTING -i tap0 -p tcp -m multiport ! --dports 80,443 -j REDIRECT --to-port <proxy_other_port>
```

### filter table — FORWARD allow/deny

```bash theme={null}
# Block metadata service (always)
iptables -A FORWARD -d 169.254.169.254 -j DROP

# Allow rules (higher priority)
iptables -A FORWARD -d 1.1.1.1 -j ACCEPT

# Deny rules
iptables -A FORWARD -d 0.0.0.0/0 -j DROP
```

## Summary of interception points

| Traffic type                         | Intercepted by               | What happens                     |
| ------------------------------------ | ---------------------------- | -------------------------------- |
| HTTP to blocked IP                   | Sandbox iptables (kernel)    | DROP — no proxy involved         |
| HTTP to blocked domain               | Namespace proxy (userspace)  | RST after Host header read       |
| HTTP to allowed domain, no scan      | Namespace proxy              | Forward raw TCP                  |
| HTTPS to blocked IP                  | Sandbox iptables (kernel)    | DROP — no proxy involved         |
| HTTPS to blocked domain              | Namespace proxy              | RST after SNI peek               |
| HTTPS to allowed domain, no scan     | Namespace proxy              | TLS passthrough                  |
| HTTPS to allowed domain, scan active | Namespace proxy (edge proxy) | Decrypt, scan, re-encrypt        |
| API-to-envd traffic                  | Private veth pair            | No interception, private network |
| Cloud metadata (169.254.169.254)     | Sandbox iptables (hardcoded) | DROP always                      |
