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

# Networking

> Expose ports dynamically for services running inside your sandbox

The Sandbox provides some basic network tools. You can run web services and expose them to the internet behind SSL-terminated endpoints. This is useful for web development, API testing, and running interactive applications with LLMs (think v0, reflex.build, etc).

## Exposing Ports

You can expose ports from your Sandbox in two ways: statically at creation time, or dynamically at runtime.

### Static Port Exposure

Specify ports when creating the sandbox to have them exposed immediately with public URLs:

```python theme={null}
from beam import Sandbox, Image, PythonVersion

# Create a sandbox with pre-exposed ports
sandbox = Sandbox(
    image=Image(python_version=PythonVersion.Python311),
    ports=[8000, 8080, 3000]  # Ports exposed at creation
)

sb = sandbox.create()

# URLs are immediately available
urls = sb.list_urls()
for port, url in urls.items():
    print(f"Port {port} exposed at: {url}")
```

### Dynamic Port Exposure

You can also expose ports dynamically after the sandbox is created using the `expose_port()` method.

#### Expose a port

```python theme={null}
from beam import Sandbox, Image, PythonVersion

sandbox = Sandbox(image=Image(python_version=PythonVersion.Python311))
sb = sandbox.create()

# Expose port 8000
url = sb.expose_port(8000)
print(f"Port 8000 exposed at: {url}")

# The URL will be something like:
# https://384ced3c-f837-4429-bada-39e0b965c9f4-8000.app.beam.cloud
```

#### Expose multiple ports

```python theme={null}
# Expose multiple ports
ports = [8000, 8080, 3000]
urls = {}

for port in ports:
    url = sb.expose_port(port)
    urls[port] = url
    print(f"Port {port} exposed at: {url}")

# Access different services
print(f"Main app: {urls[8000]}")
print(f"Admin panel: {urls[8080]}")
print(f"API server: {urls[3000]}")
```

#### List exposed ports/preview URLs

```python theme={null}
# List exposed ports & preview URLs
urls = sb.list_urls()
for port, url in urls.items():
    print(f"Port {port} exposed at: {url}")
```

## Network Security

### Blocking Outbound Traffic

You can block all outbound network access from your Sandbox while still allowing inbound connections to exposed ports. This is useful for security-sensitive workloads or when executing untrusted code.

```python theme={null}
from beam import Sandbox, Image, PythonVersion

# Create a sandbox with blocked outbound network
sandbox = Sandbox(
    image=Image(python_version=PythonVersion.Python311),
    block_network=True,  # Block all outbound traffic
)

sb = sandbox.create()

# The sandbox can still receive requests on exposed ports
url = sb.expose_port(8000)
print(f"Port 8000 exposed at: {url}")

# But it cannot make outbound connections to external services
```

With `block_network=True`, the Sandbox can receive requests on exposed ports but cannot initiate outbound connections to external services.

### Allow Lists (CIDR Ranges)

For more fine-grained control, you can specify an allow list of CIDR ranges that your Sandbox is permitted to connect to. All other outbound traffic will be blocked.

```python theme={null}
from beam import Sandbox, Image, PythonVersion

# Create a sandbox with an allow list
sandbox = Sandbox(
    image=Image(python_version=PythonVersion.Python311),
    allow_list=[
        "8.8.8.8/32",      # Allow Google DNS
        "10.0.0.0/8",      # Allow private network range
        "2001:db8::/32",   # Allow IPv6 range
    ],
)

sb = sandbox.create()

# The sandbox can only connect to addresses in the allow list
# All other outbound traffic is blocked
```

**Important Notes:**

* Maximum of 10 CIDR entries per Sandbox
* Supports both IPv4 and IPv6 addresses
* Must use proper CIDR notation (e.g., `"8.8.8.8/32"` for a single IP, `"10.0.0.0/8"` for a range)
* Cannot use `allow_list` and `block_network` together - they are mutually exclusive
* Invalid CIDR values will trigger an error at creation time

### Updating Network Permissions at Runtime

You can dynamically update the network permissions of a running Sandbox without restarting it. This allows you to change access policies during the sandbox's lifetime.

```python theme={null}
from beam import Sandbox, Image, PythonVersion

# Create a sandbox with no network restrictions
sandbox = Sandbox(image=Image(python_version=PythonVersion.Python311))
sb = sandbox.create()

# Later, block all outbound traffic
sb.update_network_permissions(block_network=True)

# Or update to use an allowlist instead
sb.update_network_permissions(
    allow_list=[
        "8.8.8.8/32",      # Allow Google DNS
        "10.0.0.0/8",      # Allow private network range
    ]
)

# Remove all restrictions
sb.update_network_permissions(block_network=False, allow_list=[])
```

**Important Notes:**

* Cannot use `block_network=True` and `allow_list` together - they are mutually exclusive
* Exposed ports remain accessible regardless of network restrictions
* Changes take effect immediately without requiring a restart
