Skip to content

Commit 79fbd48

Browse files
committed
docs(sandbox-envs): document per-env egress policy UI
1 parent 20c2933 commit 79fbd48

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12-
- Added per-environment network egress policy for sandbox environments. A `SandboxEnvironment` can now carry an `egress_policy` (default/intercept + per-host rules) and encrypted `egress_secrets` (named header credentials); when set, the agent provisions them onto the daiv-sandbox MITM egress proxy at session start so credentials are injected by the sidecar and never enter the sandbox container. The egress proxy is mandatory for network-enabled sessions: if the sandbox deployment has no egress proxy configured, a network-enabled run is rejected rather than falling back to unrestricted network. Note: a network-enabled environment **without** an egress policy receives the sidecar's default deny-all (no connectivity) — configure an egress policy on those environments. Set programmatically via the ORM for now (admin/API/form UI to follow).
12+
- Added per-environment network egress policy for sandbox environments. A `SandboxEnvironment` can now carry an `egress_policy` (default/intercept + per-host rules) and encrypted `egress_secrets` (named header credentials); when set, the agent provisions them onto the daiv-sandbox MITM egress proxy at session start so credentials are injected by the sidecar and never enter the sandbox container. The egress proxy is mandatory for network-enabled sessions: if the sandbox deployment has no egress proxy configured, a network-enabled run is rejected rather than falling back to unrestricted network. Note: a network-enabled environment **without** an egress policy receives the sidecar's default deny-all (no connectivity) — configure an egress policy on those environments. The egress policy is now configurable from the sandbox-environment form UI (shown only when **Network** is enabled): define allowed hosts (glob patterns), inject per-host credentials (HTTP header name + value, encrypted at rest and never rendered back), and set the `default` (deny/allow) and `intercept` (all/credentialed) modes. Fail-closed: an environment with no allowed hosts has no outbound access.
1313
- Added `release_orphan_queued_threads` management command to recover `QUEUED` activities left behind on threads with no active sibling (rare TOCTOU loss).
1414
- Added per-domain auth headers for the `web_fetch` tool to the configuration UI under **Web Fetch → Per-domain auth headers**. Each row pairs a domain (exact match) with an HTTP header name and a header value (encrypted at rest). Replaces the previous env-only `AUTOMATION_WEB_FETCH_AUTH_HEADERS` setting; the new env override is `DAIV_WEB_FETCH_AUTH_HEADERS` (same JSON shape). Operators using the old name must rename it.
1515
- Added a "Start a run" page at `/dashboard/runs/new/` for launching new agent runs from the UI, and a "Retry" button on terminal non-webhook activities that pre-fills the form with the original prompt, repository, ref, and max-mode flag.

docs/features/sandbox-environments.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Click **Create** on the list page to open the drawer (`/dashboard/sandbox-envs/c
3939
| **Memory** | Memory limit, entered as a value plus a **MiB** or **GiB** unit. Switch from *default* to *custom* to set it |
4040
| **Network** | **Use default**, **On**, or **Off**. Controls outbound network access (needed to reach package registries) |
4141
| **Environment variables** | Name/value pairs injected into the sandbox; mark any as secret (see below). Up to 100 entries |
42+
| **Egress policy** | Per-host outbound rules, injected credentials, and traffic mode. Shown only when **Network** is **On** or **Use default** with a default that enables networking (see [Network access and egress policy](#network-access-and-egress-policy)) |
4243
| **Repositories** | The repository IDs this environment is bound to, as slash-separated paths like `owner/repo` or `group/subgroup/repo` (see [Repository bindings](#repository-bindings)) |
4344

4445
Leaving **CPUs**, **Memory**, or **Network** on *default* means the field is unset, and the value falls back to the global default's value (or the built-in runtime default) at run time.
@@ -54,6 +55,40 @@ Environment-variable values are **Fernet-encrypted before they are stored** and
5455
!!! warning "Rotating the encryption key"
5556
If `DAIV_ENCRYPTION_KEY` changes and stored values can no longer be decrypted, the form blocks saving until you re-enter every secret value. Agent runs don't crash on this — they drop the unreadable variables and continue.
5657

58+
### Network access and egress policy
59+
60+
When **Network** is enabled, the **Egress** section appears at the bottom of the form. It lets you define exactly which outbound connections the sandbox container may make, with optional per-host credentials injected by the MITM proxy — credentials never enter the container.
61+
62+
!!! info "Requires the egress proxy"
63+
Egress policy is provisioned by the daiv-sandbox MITM egress proxy (`DAIV_SANDBOX_EGRESS_PROXY_ENABLED`). If the sandbox does not have the proxy enabled, starting a run that uses an egress-configured environment will **abort** (fail-closed) rather than fall back to unrestricted network.
64+
65+
#### Allowed hosts
66+
67+
Each row in the **Allowed hosts** table defines one outbound rule:
68+
69+
| Column | Description |
70+
|--------|-------------|
71+
| **Host** | A hostname or glob pattern (e.g. `pypi.org`, `*.github.com`). Requests to hosts not on this list are blocked |
72+
| **Methods** | HTTP methods this rule applies to (leave empty to match all methods) |
73+
| **Credential** | Optional: an HTTP header name and value injected by the proxy for every request to this host (see below) |
74+
75+
**Fail-closed:** if the allowed hosts list is empty, no outbound requests are permitted at all (equivalent to network off, even though networking is technically enabled).
76+
77+
#### Per-host credentials (encrypted at rest)
78+
79+
Each allowed host may carry an optional credential — an HTTP header name and value (for example, `Authorization` / `Bearer <token>`) that the proxy injects into matching requests. Credential values are **Fernet-encrypted before they are stored**, shown as `••••••` once saved, and never rendered back to the browser or returned by the API/MCP. Re-saving the form preserves a masked credential unchanged unless you explicitly type a new value.
80+
81+
Limits: at most **100** allowed-host rules and **100** credentials, and the encrypted secrets blob may not exceed **32 KiB**.
82+
83+
#### Traffic mode
84+
85+
Two toggles control how the MITM proxy handles traffic:
86+
87+
| Toggle | Options | Description |
88+
|--------|---------|-------------|
89+
| **Default** | `deny` / `allow` | What happens to requests that do not match any allowed-host rule. `deny` (the recommended default) blocks them; `allow` passes them through unrestricted |
90+
| **Intercept** | `all` / `credentialed` | Which connections the proxy performs TLS interception on. `all` intercepts every HTTPS request (needed to inject credentials into TLS traffic); `credentialed` intercepts only hosts that have a credential configured |
91+
5792
### Repository bindings
5893

5994
The **Repositories** field is a list of repository IDs (`owner/repo`, `group/subgroup/repo`, …) that this environment claims. Bindings drive [auto-resolution](#how-an-environment-is-resolved): when an agent runs in a bound repository and no environment is explicitly selected, this environment is chosen automatically.

0 commit comments

Comments
 (0)