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
| Mode | Description |
|---|---|
allow-all | Default. No outbound restrictions. |
deny-all | Block all outbound network access. |
custom | Allow 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
allowedDomainssupports exact matches such asapi.github.com- wildcard domains must use
*.suffixform, for example*.githubusercontent.com allowedCidrsanddeniedCidrsuse standard CIDR notation- in
custommode,deniedCidrstakes 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"],})