Networking and security

Sandboxes are built to be secure-by-default, meaning that a default Sandbox has no ability to accept incoming network connections or access your Modal resources.

Networking

Since Sandboxes may run untrusted code, they have options to restrict their network access. To block all network access, set block_network=True on Sandbox.create.

For more fine-grained networking control, a Sandbox’s outbound network access can be restricted using the cidr_allowlist parameter. This parameter takes a list of CIDR ranges that the Sandbox is allowed to access, blocking all other outbound traffic.

Forwarding ports

Sandboxes can also expose TCP ports to the internet. This is useful if, for example, you want to connect to a web server running inside a Sandbox.

Use the encrypted_ports and unencrypted_ports parameters of Sandbox.create to specify which ports to forward. You can then access the public URL of a tunnel using the Sandbox.tunnels method:

import requests
import time

sb = modal.Sandbox.create(
    "python",
    "-m",
    "http.server",
    "12345",
    encrypted_ports=[12345],
    app=my_app,
)

tunnel = sb.tunnels()[12345]

time.sleep(1)  # Wait for server to start.

print(f"Connecting to {tunnel.url}...")
print(requests.get(tunnel.url, timeout=5).text)

For more details on how tunnels work, see the tunnels guide.

Security model

In a typical Modal Function, the Function code can call other Modal APIs allowing it to spawn containers, create and destroy Volumes, read from Dicts and Queues, etc. Sandboxes, by contrast, are isolated from the main Modal workspace. They have no API access, meaning the blast radius of any malicious code is limited to the Sandbox environment.

Sandboxes are built on top of gVisor, a container runtime by Google that provides strong isolation properties. gVisor has custom logic to prevent Sandboxes from making malicious system calls, giving you stronger isolation than standard runc containers.