Security

Network Policy

Network policies control outbound network access from a box.

Use them when you want to:

  • block all outbound traffic
  • allow only specific public domains
  • restrict egress to specific CIDR ranges

By default, boxes use:

box.ts
{ mode: "allow-all" }
box.py
{"mode": "allow-all"}

Modes

ModeDescription
allow-allDefault. No outbound restrictions.
deny-allBlock all outbound network access.
customAllow or deny specific domains and CIDR ranges.

The SDK type is:

box.ts
type NetworkPolicy =  | { mode: "allow-all" | "deny-all" }  | {      mode: "custom"      allowedDomains?: string[]      allowedCidrs?: string[]      deniedCidrs?: string[]    }
box.py
from typing import Literal, TypedDict, Unionfrom typing_extensions import NotRequiredclass AllowDenyNetworkPolicy(TypedDict):    mode: Literal["allow-all", "deny-all"]class CustomNetworkPolicy(TypedDict):    mode: Literal["custom"]    allowed_domains: NotRequired[list[str]]    allowed_cidrs: NotRequired[list[str]]    denied_cidrs: NotRequired[list[str]]NetworkPolicy = Union[AllowDenyNetworkPolicy, CustomNetworkPolicy]

Create a box with a policy

Pass networkPolicy when creating a box:

box.ts
import { Box } from "@upstash/box"const box = await Box.create({  runtime: "node",  networkPolicy: {    mode: "custom",    allowedDomains: ["api.github.com", "registry.npmjs.org"],  },})
box.py
from upstash_box import Boxbox = Box.create(    runtime="node",    network_policy={        "mode": "custom",        "allowed_domains": ["api.github.com", "registry.npmjs.org"],    },)

You can also combine domain and CIDR rules:

box.ts
const box = await Box.create({  runtime: "node",  networkPolicy: {    mode: "custom",    allowedDomains: ["api.github.com", "*.githubusercontent.com"],    allowedCidrs: ["104.16.0.0/12"],  },})
box.py
box = Box.create(    runtime="node",    network_policy={        "mode": "custom",        "allowed_domains": ["api.github.com", "*.githubusercontent.com"],        "allowed_cidrs": ["104.16.0.0/12"],    },)

networkPolicy is also supported in Box.fromSnapshot() and EphemeralBox.


Read the current policy

Use the networkPolicy getter:

box.ts
console.log(box.networkPolicy) // { mode: "allow-all" }
box.py
print(box.network_policy)  # {"mode": "allow-all"}

Update a running box

Update the policy after creation:

box.ts
await box.updateNetworkPolicy({ mode: "deny-all" })
box.py
box.update_network_policy({"mode": "deny-all"})

Switch back to unrestricted outbound access:

box.ts
await box.updateNetworkPolicy({ mode: "allow-all" })
box.py
box.update_network_policy({"mode": "allow-all"})

Changes take effect immediately. You do not need to recreate the box.


Matching rules

  • allowedDomains supports exact matches such as api.github.com
  • wildcard domains must use *.suffix form, for example *.githubusercontent.com
  • allowedCidrs and deniedCidrs use standard CIDR notation
  • in custom mode, deniedCidrs takes precedence over allowed CIDRs
  • private IP ranges are always blocked even if you try to allow them explicitly

Example patterns

Allow only GitHub and npm:

box.ts
await box.updateNetworkPolicy({  mode: "custom",  allowedDomains: ["github.com", "*.github.com", "registry.npmjs.org"],})
box.py
box.update_network_policy({    "mode": "custom",    "allowed_domains": ["github.com", "*.github.com", "registry.npmjs.org"],})

Block all outbound traffic:

box.ts
await box.updateNetworkPolicy({ mode: "deny-all" })
box.py
box.update_network_policy({"mode": "deny-all"})

Allow a specific public CIDR:

box.ts
await box.updateNetworkPolicy({  mode: "custom",  allowedCidrs: ["104.16.0.0/12"],})
box.py
box.update_network_policy({    "mode": "custom",    "allowed_cidrs": ["104.16.0.0/12"],})

Block a specific CIDR range:

box.ts
await box.updateNetworkPolicy({  mode: "custom",  deniedCidrs: ["104.16.120.0/24"],})
box.py
box.update_network_policy({    "mode": "custom",    "denied_cidrs": ["104.16.120.0/24"],})

Loading search…