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

# 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:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  { mode: "allow-all" }
  ```

  ```python box.py theme={"system"}
  {"mode": "allow-all"}
  ```
</CodeGroup>

***

## 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:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  type NetworkPolicy =
    | { mode: "allow-all" | "deny-all" }
    | {
        mode: "custom"
        allowedDomains?: string[]
        allowedCidrs?: string[]
        deniedCidrs?: string[]
      }
  ```

  ```python box.py theme={"system"}
  from typing import Literal, TypedDict, Union
  from typing_extensions import NotRequired

  class 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]
  ```
</CodeGroup>

***

## Create a box with a policy

Pass `networkPolicy` when creating a box:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  import { Box } from "@upstash/box"

  const box = await Box.create({
    runtime: "node",
    networkPolicy: {
      mode: "custom",
      allowedDomains: ["api.github.com", "registry.npmjs.org"],
    },
  })
  ```

  ```python box.py theme={"system"}
  from upstash_box import Box

  box = Box.create(
      runtime="node",
      network_policy={
          "mode": "custom",
          "allowed_domains": ["api.github.com", "registry.npmjs.org"],
      },
  )
  ```
</CodeGroup>

You can also combine domain and CIDR rules:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  const box = await Box.create({
    runtime: "node",
    networkPolicy: {
      mode: "custom",
      allowedDomains: ["api.github.com", "*.githubusercontent.com"],
      allowedCidrs: ["104.16.0.0/12"],
    },
  })
  ```

  ```python box.py theme={"system"}
  box = Box.create(
      runtime="node",
      network_policy={
          "mode": "custom",
          "allowed_domains": ["api.github.com", "*.githubusercontent.com"],
          "allowed_cidrs": ["104.16.0.0/12"],
      },
  )
  ```
</CodeGroup>

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

***

## Read the current policy

Use the `networkPolicy` getter:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  console.log(box.networkPolicy) // { mode: "allow-all" }
  ```

  ```python box.py theme={"system"}
  print(box.network_policy)  # {"mode": "allow-all"}
  ```
</CodeGroup>

***

## Update a running box

Update the policy after creation:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  await box.updateNetworkPolicy({ mode: "deny-all" })
  ```

  ```python box.py theme={"system"}
  box.update_network_policy({"mode": "deny-all"})
  ```
</CodeGroup>

Switch back to unrestricted outbound access:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  await box.updateNetworkPolicy({ mode: "allow-all" })
  ```

  ```python box.py theme={"system"}
  box.update_network_policy({"mode": "allow-all"})
  ```
</CodeGroup>

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:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  await box.updateNetworkPolicy({
    mode: "custom",
    allowedDomains: ["github.com", "*.github.com", "registry.npmjs.org"],
  })
  ```

  ```python box.py theme={"system"}
  box.update_network_policy({
      "mode": "custom",
      "allowed_domains": ["github.com", "*.github.com", "registry.npmjs.org"],
  })
  ```
</CodeGroup>

Block all outbound traffic:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  await box.updateNetworkPolicy({ mode: "deny-all" })
  ```

  ```python box.py theme={"system"}
  box.update_network_policy({"mode": "deny-all"})
  ```
</CodeGroup>

Allow a specific public CIDR:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  await box.updateNetworkPolicy({
    mode: "custom",
    allowedCidrs: ["104.16.0.0/12"],
  })
  ```

  ```python box.py theme={"system"}
  box.update_network_policy({
      "mode": "custom",
      "allowed_cidrs": ["104.16.0.0/12"],
  })
  ```
</CodeGroup>

Block a specific CIDR range:

<CodeGroup>
  ```typescript box.ts theme={"system"}
  await box.updateNetworkPolicy({
    mode: "custom",
    deniedCidrs: ["104.16.120.0/24"],
  })
  ```

  ```python box.py theme={"system"}
  box.update_network_policy({
      "mode": "custom",
      "denied_cidrs": ["104.16.120.0/24"],
  })
  ```
</CodeGroup>

***

## Related

* [Security](/box/overall/security)
* [Shell](/box/overall/shell)
* [How It Works](/box/overall/how-it-works)
