Network Limits (Firewall) | Daytona

Network Limits (Firewall)

Network limits control outbound internet access from sandboxes. Each sandbox runs behind a firewall that restricts which external IP addresses and domains it can reach, preventing untrusted code from exfiltrating data or contacting arbitrary hosts.

Default network policies are applied automatically based on your organization’s tier. You can also configure access per sandbox using these parameters:

Set firewall parameters when creating a sandbox or update them while the sandbox is running.

Tier-based network restrictions

Network limits are automatically applied to sandboxes based on your organization’s billing tier. This provides secure and controlled internet access for development environments:

Create sandboxes with network restrictions

Create a sandbox with network restrictions.

Set networkAllowList, domainAllowList, or networkBlockAll when creating a sandbox to control which external hosts the sandbox can reach. The options are mutually exclusive. Set at most one non-empty value. Sending a conflicting combination returns a 400 error. Empty-string allow lists count as unset and never conflict.

On Tier 3 and Tier 4, setting an allow list or networkBlockAll at create time applies that policy for the sandbox. Destinations not on the allow list are blocked, including essential services such as GitHub, npm, and PyPI, unless you add those domains or CIDRs yourself.

from daytona import CreateSandboxFromSnapshotParams, Daytona

daytona = Daytona()

# Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
    network_allow_list='208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'
))

# Allow access to specific domains
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
    domain_allow_list='example.com,*.daytona.io'
))

# Or block all network access
sandbox = daytona.create(CreateSandboxFromSnapshotParams(
    network_block_all=True
))
import { Daytona } from '@daytona/sdk'

const daytona = new Daytona()

// Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)
const sandboxWithCidrAllowList = await daytona.create({
  networkAllowList: '208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'
})

// Allow access to specific domains
const sandboxWithDomainAllowList = await daytona.create({
  domainAllowList: 'example.com,*.daytona.io'
})

// Or block all network access
const blockedSandbox = await daytona.create({
  networkBlockAll: true
})
require 'daytona'

daytona = Daytona::Daytona.new

# Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)
sandbox = daytona.create(
  Daytona::CreateSandboxFromSnapshotParams.new(
    network_allow_list: '208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'
  )
)

# Allow access to specific domains
sandbox = daytona.create(
  Daytona::CreateSandboxFromSnapshotParams.new(
    domain_allow_list: 'example.com,*.daytona.io'
  )
)

# Or block all network access
sandbox = daytona.create(
  Daytona::CreateSandboxFromSnapshotParams.new(
    network_block_all: true
  )
)
package main

import (
  "context"
  "log"
  "github.com/daytona/clients/sdk-go/pkg/daytona"
  "github.com/daytona/clients/sdk-go/pkg/types"
)

func main() {
  client, err := daytona.NewClient()
  if err != nil {
    log.Fatal(err)
  }
  ctx := context.Background()

// Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)
  allowList := "208.80.154.232/32,199.16.156.103/32,192.168.1.0/24"
  _, err = client.Create(ctx, types.SnapshotParams{
    SandboxBaseParams: types.SandboxBaseParams{
      NetworkAllowList: &allowList,
    },
  })
  if err != nil {
    log.Fatal(err)
  }

// Allow access to specific domains
  domainAllowList := "example.com,*.daytona.io"
  _, err = client.Create(ctx, types.SnapshotParams{
    SandboxBaseParams: types.SandboxBaseParams{
      DomainAllowList: &domainAllowList,
    },
  })
  if err != nil {
    log.Fatal(err)
  }

// Or block all network access
  _, err = client.Create(ctx, types.SnapshotParams{
    SandboxBaseParams: types.SandboxBaseParams{
      NetworkBlockAll: true,
    },
  })
  if err != nil {
    log.Fatal(err)
  }
}
import io.daytona.sdk.Daytona;
import io.daytona.sdk.Sandbox;
import io.daytona.sdk.model.CreateSandboxFromSnapshotParams;

public class App {
    public static void main(String[] args) {
        try (Daytona daytona = new Daytona()) {
            // Allow access to specific domains
            CreateSandboxFromSnapshotParams domainParams = new CreateSandboxFromSnapshotParams();
            domainParams.setDomainAllowList("example.com,*.daytona.io");
            Sandbox domainRestrictedSandbox = daytona.create(domainParams);

// Or block all network access
            CreateSandboxFromSnapshotParams blockedParams = new CreateSandboxFromSnapshotParams();
            blockedParams.setNetworkBlockAll(true);
            Sandbox blockedSandbox = daytona.create(blockedParams);
        }
    }
}

Update network settings while a sandbox is running

Update network settings for running sandboxes.

This operation requires the WRITE_SANDBOXES permission. Organizations on Tier 3 and Tier 4 can change outbound firewall policy on a running sandbox. The API applies the new rules and persists them on the sandbox. The sandbox keeps running; stop or start are not required.

Organizations on Tier 1 or Tier 2 cannot override network policy at the sandbox level, and the API returns an error in that case.

When an allow list or networkBlockAll is applied, enforcement is strict for that sandbox: essential services are not auto-allowed.

# Block all outbound traffic (clears the CIDR allow list)
sandbox.update_network_settings(network_block_all=True)

# Remove the block-all rule and clear the CIDR allow list
sandbox.update_network_settings(network_block_all=False)

# Apply or replace a CIDR allow list (implies not blocking all)
sandbox.update_network_settings(
    network_allow_list='208.80.154.232/32,192.168.1.0/24'
)

# Apply or replace a domain allow list
sandbox.update_network_settings(
    domain_allow_list='example.com,*.daytona.io'
)

# Clear a stored CIDR allow list (empty string). Outbound traffic still follows `network_block_all`.
sandbox.update_network_settings(network_allow_list='')

# Clear a stored domain allow list
sandbox.update_network_settings(domain_allow_list='')
// Block all outbound traffic (clears the CIDR allow list)
await sandbox.updateNetworkSettings({ networkBlockAll: true })

// Remove the block-all rule and clear the CIDR allow list
await sandbox.updateNetworkSettings({ networkBlockAll: false })

// Apply or replace a CIDR allow list (implies not blocking all)
await sandbox.updateNetworkSettings({
  networkAllowList: '208.80.154.232/32,192.168.1.0/24',
})

// Apply or replace a domain allow list
await sandbox.updateNetworkSettings({
  domainAllowList: 'example.com,*.daytona.io',
})

// Clear a stored CIDR allow list (empty string). Outbound traffic still follows `networkBlockAll`.
await sandbox.updateNetworkSettings({ networkAllowList: '' })

// Clear a stored domain allow list
await sandbox.updateNetworkSettings({ domainAllowList: '' })
# Block all outbound traffic (clears the CIDR allow list)
sandbox.update_network_settings(network_block_all: true)

# Remove the block-all rule and clear the CIDR allow list
sandbox.update_network_settings(network_block_all: false)

# Apply or replace a CIDR allow list (implies not blocking all)
sandbox.update_network_settings(
  network_allow_list: '208.80.154.232/32,192.168.1.0/24'
)

# Apply or replace a domain allow list
sandbox.update_network_settings(
  domain_allow_list: 'example.com,*.daytona.io'
)

# Clear the CIDR allow list (empty string)
sandbox.update_network_settings(network_allow_list='')

# Clear the domain allow list
sandbox.update_network_settings(domain_allow_list='')
import apiclient "github.com/daytona/clients/api-client-go"

settings := apiclient.NewUpdateSandboxNetworkSettings()

settings.SetNetworkBlockAll(true)
if err := sandbox.UpdateNetworkSettings(ctx, *settings); err != nil {
  log.Fatal(err)
}

restore := apiclient.NewUpdateSandboxNetworkSettings()
restore.SetNetworkBlockAll(false)
if err := sandbox.UpdateNetworkSettings(ctx, *restore); err != nil {
  log.Fatal(err)
}

allow := apiclient.NewUpdateSandboxNetworkSettings()
allow.SetNetworkAllowList("208.80.154.232/32,192.168.1.0/24")
if err := sandbox.UpdateNetworkSettings(ctx, *allow); err != nil {
  log.Fatal(err)
}

domainAllow := apiclient.NewUpdateSandboxNetworkSettings()
domainAllow.SetDomainAllowList("example.com,*.daytona.io")
if err := sandbox.UpdateNetworkSettings(ctx, *domainAllow); err != nil {
  log.Fatal(err)
}

clearDomainAllow := apiclient.NewUpdateSandboxNetworkSettings()
clearDomainAllow.SetDomainAllowList("")
if err := sandbox.UpdateNetworkSettings(ctx, *clearDomainAllow); err != nil {
  log.Fatal(err)
}
}

Outbound proxy

Create a sandbox with an outbound proxy.

An outbound proxy sends a sandbox’s HTTP(S) egress through a proxy you control. You can set the outboundProxyUrl parameter when creating a sandbox to specify the upstream proxy URL Daytona should chain to. Daytona routes matching traffic through its egress proxy to that upstream instead of dialing destinations directly.

  1. Daytona stores the proxy URL on the sandbox (encrypted at rest) and sets HTTP_PROXY (and HTTPS_PROXY) inside the sandbox.
  2. HTTP(S) clients that respect those variables send traffic through Daytona’s egress proxy, which chains to your upstream.
  3. To prevent clients that do not respect HTTP_PROXY from bypassing your upstream proxy, also configure Daytona’s domainAllowList.

Platform telemetry to the Daytona-managed collector is not routed through your outbound proxy.

The URL may use http or https and may include credentials in the userinfo, for example http://user:pass@proxy.example.com:3128. Implement domain allow listing on your own proxy to control which destinations the sandbox can reach.

Constraint Value
Schemes http, https
Max length 2048 characters
Host Must not be localhost or a private, loopback, or link-local IP literal
from daytona import CreateSandboxFromSnapshotParams, Daytona

daytona = Daytona()

sandbox = daytona.create(CreateSandboxFromSnapshotParams(
    outbound_proxy_url='http://user:pass@proxy.example.com:3128',
))

# Returned on single-sandbox reads
sandbox = daytona.get(sandbox.id)
print(sandbox.outbound_proxy_url)
import { Daytona } from '@daytona/sdk'

const daytona = new Daytona()

const sandbox = await daytona.create({
  outboundProxyUrl: 'http://user:pass@proxy.example.com:3128',
})

// Returned on single-sandbox reads
const fetched = await daytona.get(sandbox.id)
console.log(fetched.outboundProxyUrl)
require 'daytona'

daytona = Daytona::Daytona.new

sandbox = daytona.create(
  Daytona::CreateSandboxFromSnapshotParams.new(
    outbound_proxy_url: 'http://user:pass@proxy.example.com:3128'
  )
)

# Returned on single-sandbox reads
sandbox = daytona.get(sandbox.id)
puts sandbox.outbound_proxy_url
package main

import (
  "context"
  "fmt"
  "log"
  "github.com/daytona/clients/sdk-go/pkg/daytona"
  "github.com/daytona/clients/sdk-go/pkg/types"
)

func main() {
  client, err := daytona.NewClient()
  if err != nil {
    log.Fatal(err)
  }
  ctx := context.Background()

proxyURL := "http://user:pass@proxy.example.com:3128"
  sandbox, err := client.Create(ctx, types.SnapshotParams{
    SandboxBaseParams: types.SandboxBaseParams{
      OutboundProxyUrl: &proxyURL,
    },
  })
  if err != nil {
    log.Fatal(err)
  }

// Returned on single-sandbox reads
  fetched, err := client.Get(ctx, sandbox.ID)
  if err != nil {
    log.Fatal(err)
  }

if fetched.OutboundProxyUrl != nil {
    fmt.Println(*fetched.OutboundProxyUrl)
  }
}

Network allow list format

The network allow list is a comma-separated list of IPv4 CIDR blocks. When a CIDR allow list is set, outbound traffic is limited to the listed ranges. Other destinations are blocked, including essential services whose resolved addresses are not covered by the list.

Examples:

Domain allow list format

The domain allow list is a comma-separated list of DNS domains. When a domain allow list is set, outbound traffic is limited to the listed domains. Other external domains are blocked, including essential services that are not on the list.

Examples:

Test network access

To test network connectivity from your sandbox:

# Test HTTP connectivity to allowed addresses
curl -I https://208.80.154.232

# Test HTTP connectivity to allowed domains
curl -I https://example.com

# Package managers reach registries only when those hosts are allowed
# (default tier policy includes essential services; a sandbox allow list does not)
apt update  # For Ubuntu/Debian
npm ping    # For Node.js
pip install --dry-run requests  # For Python

Security benefits

Network limits provide several security advantages:

Essential services

Essential services are package registries, git hosts, model providers, and related hosts that remain reachable under the default tier-based network policy on all tiers. They do not apply when a sandbox has a custom networkAllowList, domainAllowList, or networkBlockAll on Tier 3 or Tier 4. In those modes, only the destinations you configure are allowed (or none). To keep an essential service reachable under an allow list, include its domains or CIDRs in that list.