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

# Sandbox Networking

> Control outbound network access from a sandbox

Sandbox network policies control connections initiated by workloads inside a
sandbox. Outbound internet access is allowed by default. Add a policy at
creation time or update a running sandbox when you need to restrict its access.

Network policies affect outbound traffic only. They do not change inbound
access through [exposed ports](/docs/sandboxes/runtime).

## Policy Fields

<ParamField path="allowInternetAccess" type="boolean" default={true}>
  Controls outbound internet access for destinations not covered by
  `allowOut` or `denyOut`. Set it to `false` for a default-deny policy.
</ParamField>

<ParamField path="allowOut" type="string[]">
  Outbound destinations to allow. Entries can be IPv4 addresses, IPv4 CIDR
  ranges, exact domains, or wildcard domains such as `*.example.com`.
</ParamField>

<ParamField path="denyOut" type="string[]">
  Outbound destinations to deny. Entries can be IPv4 addresses or IPv4 CIDR
  ranges. Domain entries are not supported in `denyOut`.
</ParamField>

An empty policy is equivalent to:

```json theme={null}
{
  "allowInternetAccess": true,
  "allowOut": [],
  "denyOut": []
}
```

### Rule Precedence

When `allowOut` and `denyOut` both match the same destination, `allowOut` takes
precedence.

For example:

```json theme={null}
{
  "allowInternetAccess": true,
  "allowOut": ["203.0.113.10"],
  "denyOut": ["203.0.113.0/24"]
}
```

* `203.0.113.10` is allowed because it matches both rules and `allowOut` wins.
* Other addresses in `203.0.113.0/24` are blocked.
* Destinations outside that range are allowed because
  `allowInternetAccess` is `true`.

<Warning>
  A domain in `allowOut` requires a default-deny boundary: set
  `allowInternetAccess` to `false` or include `0.0.0.0/0` in `denyOut`.
  Hyperbrowser rejects the policy otherwise.
</Warning>

<Note>
  IPv4 addresses are normalized to `/32` CIDRs, CIDRs are normalized to their
  network address, domains are lowercased, and duplicate entries are removed.
  IPv4 and CIDR rules match the destination across all ports and protocols.
  IPv6 policy targets are not currently supported.
</Note>

## Create With a Network Policy

The following policy blocks outbound internet access except for the exact
domain `api.github.com` and the IPv4 address `1.1.1.1`.

<CodeGroup>
  ```python Python 1.0+ theme={null}
  from hyperbrowser import Hyperbrowser

  client = Hyperbrowser(api_key="YOUR_API_KEY")

  sandbox = client.sandboxes.create(
      {
          "image_name": "python",
          "allow_internet_access": False,
          "allow_out": ["api.github.com", "1.1.1.1"],
      }
  )
  ```

  ```python Python (legacy) theme={null}
  from hyperbrowser import Hyperbrowser
  from hyperbrowser.models import CreateSandboxParams

  client = Hyperbrowser(api_key="YOUR_API_KEY")

  sandbox = client.sandboxes.create(
      CreateSandboxParams(
          image_name="python",
          allow_internet_access=False,
          allow_out=["api.github.com", "1.1.1.1"],
      )
  )
  ```

  ```bash CLI theme={null}
  hx vm create python \
    --allow-internet=false \
    --allow-out api.github.com \
    --allow-out 1.1.1.1
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.hyperbrowser.ai/api/sandbox \
    -H "x-api-key: $HYPERBROWSER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "imageName": "python",
      "allowInternetAccess": false,
      "allowOut": ["api.github.com", "1.1.1.1"]
    }'
  ```
</CodeGroup>

To allow internet access by default while blocking selected networks, leave
`allowInternetAccess` as `true` and add IPv4 or CIDR entries to `denyOut`.

## Update a Running Sandbox

Update the policy without restarting the sandbox:

<CodeGroup>
  ```python Python 1.0+ theme={null}
  result = sandbox.update_network(
      {
          "allow_internet_access": False,
          "allow_out": ["api.github.com"],
          "deny_out": [],
      }
  )

  print(result.network)
  ```

  ```python Python (legacy) theme={null}
  from hyperbrowser.models import SandboxNetworkPolicy

  result = sandbox.update_network(
      SandboxNetworkPolicy(
          allow_internet_access=False,
          allow_out=["api.github.com"],
          deny_out=[],
      )
  )

  print(result.network)
  ```

  ```bash CLI theme={null}
  hx vm network set "$sandbox_id" \
    --allow-internet=false \
    --allow-out api.github.com
  ```

  ```bash cURL theme={null}
  curl -X PUT \
    "https://api.hyperbrowser.ai/api/sandbox/$sandbox_id/network" \
    -H "x-api-key: $HYPERBROWSER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "allowInternetAccess": false,
      "allowOut": ["api.github.com"],
      "denyOut": []
    }'
  ```
</CodeGroup>

The update endpoint uses patch semantics:

* Omitted fields keep their current values.
* A supplied `allowOut` or `denyOut` array replaces that entire list.
* Supply an empty array to clear one list.

The Python SDK sends only fields supplied in the request.
The CLI sends only the flags provided to `hx vm network set`.

<Warning>
  Policy changes apply to new connections. Established connections may
  continue until they close.
</Warning>

## Clear a Network Policy

Restore the default outbound policy and remove all allow and deny entries.

<CodeGroup>
  ```python Python theme={null}
  sandbox.clear_network()
  ```

  ```bash CLI theme={null}
  hx vm network clear "$sandbox_id"
  ```

  ```bash cURL theme={null}
  curl -X PUT \
    "https://api.hyperbrowser.ai/api/sandbox/$sandbox_id/network" \
    -H "x-api-key: $HYPERBROWSER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "allowInternetAccess": true,
      "allowOut": [],
      "denyOut": []
    }'
  ```
</CodeGroup>

Sandbox create, get, and network-update responses include the effective policy
under the `network` field.

## Domain Rules

Domain entries are supported only in `allowOut`, and a policy containing one
must have a default-deny boundary. Set `allowInternetAccess` to `false` or add
`0.0.0.0/0` to `denyOut`.

* `example.com` matches only `example.com`, not its subdomains.
* `*.example.com` matches subdomains such as `api.example.com`, but not the
  apex `example.com`. Add both entries when you need both forms.
* Domain rules apply to HTTP on port `80` and HTTPS on port `443`. HTTPS
  matching uses the TLS server name. For other ports or protocols, allow the
  destination with an IPv4 or CIDR entry.
* While domain rules are active, DNS permits `A`, `AAAA`, `SVCB`, and `HTTPS`
  lookups for allowed names and refuses lookups for other names.
* Domain-based connections reject hostnames that resolve to loopback, private,
  carrier-grade NAT, or link-local addresses.

<Note>
  Domain rules require the application to send a hostname in the HTTP `Host`
  header or HTTPS TLS server name. Connections that do not expose a matching
  hostname need an IPv4 or CIDR allow entry.
</Note>

## Common Patterns

### Block All Outbound Access

```json theme={null}
{
  "allowInternetAccess": false,
  "allowOut": [],
  "denyOut": []
}
```

### Allow Only Selected Web Domains

```json theme={null}
{
  "allowInternetAccess": false,
  "allowOut": ["example.com", "*.example.com"],
  "denyOut": []
}
```

### Block a Network With One Exception

Because allow rules take precedence, a narrow allow can override a broader
deny:

```json theme={null}
{
  "allowInternetAccess": true,
  "allowOut": ["203.0.113.10"],
  "denyOut": ["203.0.113.0/24"]
}
```
