Skip to main content
This page shows how to author the policy that governs sandboxes on a cluster: bounding compute, images, network access, and security posture, and setting the defaults every sandbox inherits. It is written for administrators who manage runners. A policy is carried on the runner, so you author it by updating the runner. There is no separate policy resource and no policy endpoint. For how a sandbox resolves against a policy, see Policies overview.
CoreWeave sandboxes are in public preview. For access, contact your CoreWeave account team, CoreWeave Support, or email support@coreweave.com.

Before you begin

You need the sandbox_admin role in your organization. Reading or writing a policy without it returns PermissionDenied. To use the CLI examples, install and authenticate the CoreWeave Intelligent CLI. To use the REST examples, you need a CoreWeave API token. Examples use $TOKEN for that token and prod-us-east-1 for the runner. Every runner carries exactly one policy, and the policy is required. A policy with no base and no constraints is valid and declares a fully permissive posture, so an operator always states the posture explicitly rather than inheriting one by accident.

Read the current policy

Start from what the runner has now, rather than from an empty document.
Add describe for a detailed view, which names the not-configured state explicitly when a runner has no policy:
With -o json, a runner that has never been configured returns null rather than {}, so automation can tell “never configured” apart from “configured and permissive”.

Update a policy

A policy is a field on the runner, so you set it by updating the runner with an update mask of policy. A policy update always replaces the entire document. Only policy is implemented as an update mask path, so you cannot patch one constraint group and leave the rest untouched. Read the current policy, change what you need, and send the whole document back.
Edit the policy in $EDITOR, seeded with the runner’s current document:
Apply a document from a file, or from stdin with -:
To start from a scaffold rather than the current document, print a template:
Check a document before sending it:
Three rules apply to every policy write:
  • A policy must bound sandbox lifetime. Set constraints.lifecycle.maxLifetimeSeconds to a value greater than zero, which guarantees that every sandbox on the runner self-terminates. cwic rejects a policy without one before it calls the API. Lifetime is the one constraint that clamps rather than rejects: a sandbox asking for longer receives the maximum.
  • A configured policy cannot be cleared. There is no delete operation, and the API rejects an update that sets the policy to null. To loosen a posture, replace the document with a more permissive one.
  • A policy document is capped at 256 KiB once encoded.
Because every write replaces the whole document, two administrators editing the same runner can overwrite each other. Read immediately before you write.
Policy changes apply to sandboxes created after the update. Running sandboxes keep the policy they resolved against at launch, and the gateway’s cached copy can lag briefly, so a placement made moments after a write may still resolve against the previous policy.
Policy commands read and write the v1 API, while the other cwic sandbox runner and cwic sandbox profile commands still use v1beta2. Both are reached through the same --api-url.

Set a default policy for new runners

A runner that has never been used has no policy, and a sandbox that lands on it is rejected with CWSANDBOX_POOL_POLICY_NOT_CONFIGURED. To avoid configuring every runner by hand, a deployment can define a default that is written to a runner the first time v1 placement selects it. The default lives in the gateway infrastructure configuration at gateway.infraConfig.default_runner_policy, and changing it requires a gateway restart. There is no built-in default. When the setting is absent or null, nothing is written and the sandbox is still rejected with CWSANDBOX_POOL_POLICY_NOT_CONFIGURED. Two behaviors are worth knowing before you rely on it:
  • The default is a snapshot, not a link. Once materialized onto a runner, the policy is an ordinary runner policy. Later changes to default_runner_policy do not reach runners that already have one. Update those with UpdateManagedRunner.
  • An invalid default degrades creation. The gateway validates the configured policy at startup. If it does not validate, the gateway still starts, but sandbox creation fails with CWSANDBOX_SERVERLESS_MISCONFIGURED.

Constrain compute

resources bounds what a container may request, and supplies the values used when a sandbox asks for nothing.
Set requireLimits to true to reject sandboxes that do not declare both CPU and memory limits. Use cpuCeiling and memoryCeiling to cap the resolved total for a sandbox, which matters when the base layer contributes containers of its own.

Constrain images

image restricts where sandbox images may come from. An empty group permits any image.

Constrain network access

Network constraints work as an envelope. A sandbox declares the access it needs, and the policy decides whether that request fits. The policy never adds access a sandbox did not ask for. Two settings do separate jobs:
  • allowedEgress is the entitlement envelope, checked when a sandbox is created. When it is non-empty, every rule the sandbox declares must fit inside it, and a rule outside it is rejected rather than narrowed. Empty means anything is declarable.
  • defaultEgress is what an absent request means. It applies only when the sandbox declares no egress of its own, and any declaration displaces it entirely.
A rule names one destination. Use cidr with optional except carve-outs, tenant for a relationship to other sandboxes, or any. Optional ports narrow the rule further.
The example permits the public internet while carving out private space and the instance metadata address, and permits sandboxes to reach other sandboxes in the same organization. A sandbox that declares nothing gets same-organization access only. Tenant scopes are TENANT_SCOPE_SAME_USER and TENANT_SCOPE_SAME_ORG. A third value, TENANT_SCOPE_SANDBOX_NETWORK, is not supported yet and an egress rule using it is rejected. Ingress follows the same shape through allowedIngress and defaultIngress, for ports the sandbox exposes. Ingress rules accept cidr, tenant, or any, and never name-based sources, because inbound packets carry no name.
Ingress is not enforced yet. A sandbox that declares ingress rules is rejected, so setting allowedIngress or defaultIngress has no effect today.
DNS-name destinations are not enforced yet. A sandbox that declares one is rejected, so grant access by address range instead.

Constrain security posture

security governs in-guest privilege and the isolation the sandbox runs under.
allowedRuntimeClasses fails closed. An empty or absent list permits no runtime class pin at all, so a sandbox can only select a class when you list one explicitly. Set defaultCpuRuntimeClass and defaultGpuRuntimeClass to choose what a sandbox gets when it pins nothing.

Constrain instances, lifetime, metadata, and volumes

The remaining groups are small.

The base layer

Constraints bound what a sandbox may ask for. The base layer is intended to supply what every sandbox gets without asking: defaults and attachments such as the scheduler, node selectors, tolerations, service accounts, and image pull secrets. Its shape depends on the runner runtime, and on a Kubernetes runner it is a pod specification fragment.
base is not applied today. The policy engine passes it through untouched and leaves enforcement to the runtime, so a base fragment you set has no effect on the sandboxes a runner places.To pin a scheduler, node selectors, or tolerations now, use a profile template on the v1beta2 surface. See SUNK Pod Scheduler integration for a worked example.

Next steps

Last modified on August 14, 2026