---
title: "Replace a project’s egress policy (creates a new immutable version)"
method: PUT
path: "/v1/projects/{project_id}/egress-policy"
tags: ["Egress policy"]
---

# Replace a project’s egress policy (creates a new immutable version)

`PUT /v1/projects/{project_id}/egress-policy`

## Request

- Base URL: `https://api.shardflux.dev`
- URL: `https://api.shardflux.dev/v1/projects/{project_id}/egress-policy`
- Auth: HTTP bearer

mode allow_all | allowlist | deny_all; rules/cidrs only with allowlist. Hosts: exact FQDN or `*.` single-label wildcard (IDNA-normalized, lower-case); IP literals and localhost-like names are rejected. Ports 1-65535 (default [443]); protocols tcp only. cidrs: public ranges only. Optional If-Match: <version> (409 conflict with details.reason version_mismatch). Owner/admin or an API key of this project with tool permissions.

## Path parameters

- `project_id` string, uuid, required

## Headers

- `if-match` string

## Request body

- object
  - `mode` 'allow_all' | 'allowlist' | 'deny_all', required
  - `rules` object[]: allowlist only; at most 256.
    - `host` string, required
    - `ports` integer[]: Default [443].
    - `protocols` string[]: Only "tcp" (default); udp/quic are rejected.
  - `cidrs` string[]: allowlist only; public ranges; at most 64.

## Response `200`

Default Response

- object
  - `organization_id` string, uuid, required: UUIDv7, lowercase canonical form.
  - `project_id` string, uuid, required: UUIDv7, lowercase canonical form.
  - `version` integer, required: Current version number of the project policy (0 = none); send as If-Match.
  - `policy` object, nullable, required
    - `id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `scope` union, required
      - 'project'
      - 'workspace'
    - `project_id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `workspace_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
    - `version` integer, required
    - `kind` union, required: cleared: the workspace override was removed (falls back to the project policy).
      - 'policy'
      - 'cleared'
    - `mode` 'allow_all' | 'allowlist' | 'deny_all', nullable, required
    - `rules` object[], required
      - `host` string, required: Lower-case IDNA A-label FQDN, or `*.` + FQDN (matches exactly one extra label).
      - `ports` integer[], required
      - `protocols` string[], required
    - `cidrs` string[], required
    - `policy_sha256` string, nullable, required
    - `created_by` object, required
      - `type` union, required
        - 'user'
        - 'api_key'
      - `id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `created_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
  - `effective` object, required
    - `source` union, required: organization: an organization egress override (deny_all, e.g. outbound transfer allowance used up;) wins over every policy until it lifts.
      - 'organization'
      - 'workspace'
      - 'project'
      - 'platform_default'
    - `policy_version_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
    - `policy_version` integer, nullable, required
    - `mode` 'allow_all' | 'allowlist' | 'deny_all', required
    - `rules` object[], required
      - `host` string, required: Lower-case IDNA A-label FQDN, or `*.` + FQDN (matches exactly one extra label).
      - `ports` integer[], required
      - `protocols` string[], required
    - `cidrs` string[], required
    - `policy_sha256` string, required: SHA-256 of the canonical policy document; what the host acknowledges.
  - `organization_override` object, nullable, required: Active organization egress override; policies stay stored and apply again when it lifts.
    - `mode` 'deny_all', required
    - `reason` 'transfer_allowance_exhausted', required
    - `set_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
    - `lifts_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
  - `propagation` object, required: Where the cell stands applying the current project policy (from its acknowledgements).
    - `workspaces` integer, required: Live workspaces (not deleted, with a VM or starting) whose effective policy is this project policy.
    - `enforced` integer, required
    - `pending` integer, required
    - `failed` integer, required
    - `not_enforced` integer, required: Not yet acknowledged for the current version and ownership epoch.
    - `truncated` boolean, required: Counted over at most 5000 workspaces.

## Other responses

- `4XX`: Default Response
- `5XX`: Default Response

---

[API](https://skmtc.dev/shardflux/apis/shardflux-api.md) · [All operations](https://skmtc.dev/shardflux/apis/shardflux-api/llms.txt) · [OpenAPI document](https://skmtc.dev/shardflux/apis/shardflux-api/revisions/ea685f7b39c4?raw)
