From 2af82573e5e7b709a7f904102a54ade2c5398c79 Mon Sep 17 00:00:00 2001 From: Craig Osterhout Date: Fri, 25 Sep 2026 21:33:41 +0000 Subject: [PATCH] ai-gov: approval-required network access Co-Authored-By: Claude Opus 5.5 Signed-off-by: Craig Osterhout --- .../governance/access-controls/local.md | 26 +++- .../governance/access-controls/network.md | 118 ++++++++++++++++++ .../access-controls/organization.md | 41 +++++- .../ai/sandboxes/governance/concepts.md | 27 ++++ .../monitor-and-enforce/monitoring.md | 15 ++- 5 files changed, 218 insertions(+), 9 deletions(-) diff --git a/content/manuals/ai/sandboxes/governance/access-controls/local.md b/content/manuals/ai/sandboxes/governance/access-controls/local.md index 883d9cd3a9c..0013e75b1f9 100644 --- a/content/manuals/ai/sandboxes/governance/access-controls/local.md +++ b/content/manuals/ai/sandboxes/governance/access-controls/local.md @@ -63,8 +63,14 @@ Initialize the global network policy for your sandboxes: Presets initialize the global policy. Built-in agent kits and other kits can add per-sandbox allow rules, including under **Locked Down** (`deny-all`). The -preset isn't an explicit deny rule that overrides those allowances. To inspect -the rules a kit adds to a sandbox, run: +preset isn't an explicit deny rule that overrides those allowances. + +Under **Balanced** and **Locked Down**, a sandbox request that no rule matches +is blocked and asks for your approval instead of being denied outright, so you +can open access to each destination as a sandbox needs it. See +[Approval-required access](network.md#approval-required-access). + +To inspect the rules a kit adds to a sandbox, run: ```console $ sbx policy ls my-sandbox --source kit --type network --wide @@ -288,6 +294,11 @@ Bare hostnames and IP addresses are evaluated against port 443. This is useful for verifying custom rules or checking what the Locked Down preset blocks before you start an agent. +A check never creates an approval request. A destination that a sandbox would +ask you to approve shows as `Denied:`, with a `Reason:` line of +`no matching allow rule (default deny)`, or `approval required by policy` under +organization governance. + To check policy in the context of a specific sandbox: ```console @@ -347,3 +358,14 @@ denied by an HTTP rule. Run `sbx policy ls --type http` to see which HTTP rules apply. `sbx policy check network` reports the decision for the host only, so it shows a host as allowed even when the specific request is denied. See [HTTP method and path rules](#http-method-and-path-rules). + +### A request is blocked with "Approval required" + +The destination needs your confirmation. Either no allow or deny rule matches +it and your machine isn't under organization governance, or an organization +policy allows it but requires approval first. + +Run `sbx policy approval ls` to see the pending request and respond to it with +`sbx policy approval respond`. Approving applies to later requests, not the one +that was blocked, so run the operation again afterward. See +[Respond to an approval request](network.md#respond-to-an-approval-request). diff --git a/content/manuals/ai/sandboxes/governance/access-controls/network.md b/content/manuals/ai/sandboxes/governance/access-controls/network.md index 2c33d1aa0bd..6b792afdd46 100644 --- a/content/manuals/ai/sandboxes/governance/access-controls/network.md +++ b/content/manuals/ai/sandboxes/governance/access-controls/network.md @@ -83,6 +83,124 @@ organization or to selected teams. For setup steps and team scoping, see Use [Monitoring policies](../monitor-and-enforce/monitoring.md) to inspect which network rules are active on a developer machine. +## Approval-required access + +An organization network policy can require approval instead of granting access +outright. Destinations the policy allows aren't reachable until the developer +confirms them, which keeps an allowlist broad enough to be usable while still +putting a person in front of each destination an agent reaches for. + +Without organization governance, a request with no matching allow or deny rule +also asks for approval rather than being denied outright, so access opens up as +the developer approves each destination. + +Under organization governance, approval is a property of the policy rather +than of individual rules, so turning it on applies it to every allow rule in +that policy. A destination stays directly reachable only when no policy that +allows it requires approval. If a policy that requires approval also matches, +the request needs approval regardless of what the other policies allow. + +Only a destination the developer has already approved satisfies the +requirement. Preset rules, +[kit-defined rules](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/capabilities/com.docker.sandbox/network-policy@1.md), +and rules the developer added with `sbx policy allow network` don't answer it. +An approval also can't reach a destination the organization doesn't allow at +all, and it can't override a deny rule. To withdraw a destination, add a deny +rule, which takes precedence over any approval already recorded. + +To require approval on an organization policy, see +[Organization policies](organization.md#require-approval-for-a-network-policy). + +### Respond to an approval request + +When a destination needs approval, a sandbox can't reach it until you confirm +it. The request is blocked and the sandbox receives a message naming the +destination: + +```plaintext +Approval required for api.example.com. + +Review and respond with: + sbx policy approval ls +``` + +If your organization +[configures a support message](organization.md#configure-a-support-message), it +appears after the approval instructions. + +The request that triggers the prompt doesn't wait for an answer. It's denied, +and approving the destination affects later requests. Agents that retry a +failed request pick up the new access on their next attempt. For others, run +the operation again. + +List the destinations waiting for a response: + +```console +$ sbx policy approval ls +APPROVAL SANDBOX TITLE DETAIL OPTIONS +network:c2FuZGJveA my-sandbox api.example.com:443 Protocol: TCP Resource type: domain approval required by policy "default network" allow (Allow), dismiss (Dismiss) +``` + +Each entry names the destination, the sandbox that asked for it, and why it +needs approval. Under organization governance that reason names the policy, as +shown. Without it, the reason is that no matching allow rule covers the +destination. A request that an HTTP rule matches also shows the method and +path, such as `GET api.example.com:443/v1/data`. + +To inspect a single entry, pass its ID to `sbx policy approval inspect`: + +```console +$ sbx policy approval inspect network:c2FuZGJveA +APPROVAL network:c2FuZGJveA (sandbox: my-sandbox) + api.example.com:443 + Protocol: TCP + Resource type: domain + approval required by policy "default network" + + OPTION LABEL + allow Allow + dismiss Dismiss +``` + +Respond by selecting one of the options the entry offers: + +```console +$ sbx policy approval respond network:c2FuZGJveA --option allow +Recorded: Allow +``` + +Choosing `allow` grants access to that destination. Choosing `dismiss` leaves +it blocked, and the destination is requested again the next time the sandbox +tries to reach it. Repeated attempts collapse into a single entry, so a sandbox +retrying in a loop leaves one request to answer, not a queue of duplicates. + +#### What approving grants + +Approving records a rule that allows the destination the sandbox actually +asked for, scoped to the sandbox that asked. Three things follow from that: + +- The rule covers one destination, not the pattern the policy rule used. A + policy that allows `*.example.com` with approval asks about + `api.example.com` and `cdn.example.com` separately. +- A destination includes its port, so `api.example.com:443` and + `api.example.com:8443` are approved separately. +- Another sandbox reaching the same destination asks again. + +When an [HTTP rule](../concepts.md#http-method-and-path) in the policy matches +the request, approving covers the method and exact path the sandbox requested +rather than the whole destination. `GET /v1/data` and `POST /v1/data` on the +same host are approved separately. A request whose method or path can't be +recorded as a rule, such as a path with percent-encoding, is blocked without an +entry to respond to. + +Approved destinations stay allowed until the rule is removed. List them with +`sbx policy ls --wide --created-via approval`, and remove one the same way as +any other local rule, with [`sbx policy rm network`](local.md#managing-rules). + +Approvals live in the local policy store, so [`sbx policy reset`](local.md#resetting) +removes all of them along with your other local rules. Each destination is +requested again the next time a sandbox reaches it. + > [!NOTE] > To manage Model Context Protocol (MCP) server registration and requests > through Docker's MCP gateway, use [MCP access policies](mcp.md). These diff --git a/content/manuals/ai/sandboxes/governance/access-controls/organization.md b/content/manuals/ai/sandboxes/governance/access-controls/organization.md index 8007bf7890d..e58665e6c69 100644 --- a/content/manuals/ai/sandboxes/governance/access-controls/organization.md +++ b/content/manuals/ai/sandboxes/governance/access-controls/organization.md @@ -59,10 +59,34 @@ To create a policy: **Add rule** for each rule. For MCP policies, enter Cedar statements in the policy editor. For syntax and examples, use the relevant access-control page in [Choose a policy type](#choose-a-policy-type). +1. For a network policy, set **Require approval before access** if developers + should confirm each destination before a sandbox can reach it. See + [Require approval for a network policy](#require-approval-for-a-network-policy). Existing policies are listed with their name, scope, rule count, and last update. Use the action menu (⋮) to edit or delete a policy. +### Require approval for a network policy + +Turning on **Require approval before access** means the destinations a network +policy allows aren't reachable until the developer confirms each one. For how +approval behaves and what satisfies it, see +[Approval-required access](network.md#approval-required-access). + +To set it on an existing policy: + +1. Sign in to [Docker Home](https://app.docker.com) and select your + organization. +1. In the left-hand navigation, expand **AI Platform** and select + **Network access**. +1. Open the policy's action menu (⋮) and select **Edit**. +1. Turn on **Require approval before access**. +1. Select **Save changes**. + +The policy's detail page reports approval as **Required** or **Not required**. +Editing a policy replaces it in full, so turning the setting off removes the +requirement from every rule in that policy. + ## Configure a support message Admins can add an optional support message that appears after the policy denial @@ -78,8 +102,9 @@ To set the message: 1. Select **Save changes**. Docker shows the message only for denials caused by organization governance -policy. If you leave it blank, Docker shows the policy denial without additional -contact text. +policy and for requests an +[approval-required policy](network.md#approval-required-access) blocks. If you +leave it blank, Docker shows the policy denial without additional contact text. ## Choose a policy type @@ -147,8 +172,11 @@ propagate to developer machines. To apply changes immediately, users can run organization policies on the next `sbx` command. > [!WARNING] -> `sbx policy reset` deletes all locally configured policy rules. The command -> prompts for confirmation before proceeding. +> `sbx policy reset` deletes all locally configured policy rules, including any +> destinations the developer has approved under an +> [approval-required policy](network.md#approval-required-access). Those +> destinations are requested again the next time a sandbox reaches them. The +> command prompts for confirmation before proceeding. #### Enforcement timing by policy type @@ -159,6 +187,11 @@ developer machine: change has synced to the developer's machine (up to 5 minutes), it applies immediately to subsequent requests. +- An approval requirement applies from the point the policy change syncs. + Destinations a developer already approved stay reachable, because the + approval is recorded on the developer's machine. To withdraw one, add a deny + rule. A deny takes precedence over a recorded approval. + - Filesystem policy is only checked when a workspace is mounted — that is, when a sandbox is created. Once a sandbox is running, changing the filesystem policy has no effect on that sandbox. The sandbox continues to diff --git a/content/manuals/ai/sandboxes/governance/concepts.md b/content/manuals/ai/sandboxes/governance/concepts.md index 0e0fdcc7917..6da4acc059d 100644 --- a/content/manuals/ai/sandboxes/governance/concepts.md +++ b/content/manuals/ai/sandboxes/governance/concepts.md @@ -41,6 +41,19 @@ share the same domain, either `network` or `filesystem`. MCP policies use Cedar statements written in the `MCP` namespace instead of the network and filesystem rule format. +An organization network policy can also require approval, which turns every +allow in that policy into a request the developer must confirm before access is +granted. Approval is set on the policy rather than on individual rules, so it +applies to all of the policy's allow rules at once. Without organization +governance, a request with no matching allow or deny rule also asks for +approval. See +[Approval-required access](access-controls/network.md#approval-required-access). + +Network approval is separate from the MCP `@requireApproval` annotation. An MCP +approval confirms a single call within the session and records nothing, while +an approved network destination stays allowed until you remove the rule. See +[MCP access policies](access-controls/mcp.md). + ### Limits Organization policies have the following limits, which help ensure fair usage @@ -242,6 +255,13 @@ team-scoped policy, which makes org-wide deny rules useful as guardrails. Local and kit-defined allow rules take no part in this evaluation. Deny rules from those sources do still apply. See [Precedence](#precedence). +A request that an approval-required policy allows produces a third outcome. +Rather than being allowed outright, it's held back until the developer confirms +the destination, and the confirmation governs later requests to it. This holds +even when another policy allows the same request without requiring approval. A +matching deny still wins, so a denied destination is blocked without asking. +See [Approval-required access](access-controls/network.md#approval-required-access). + ## Precedence What applies depends on whether your organization has governance enabled: @@ -275,5 +295,12 @@ inactive rules by default. See [Monitoring](monitor-and-enforce/monitoring.md#showing-inactive-rules) for how to list them. +A local deny takes precedence over an organization approval requirement as +well, so the request is blocked and no approval is requested. Rules that a +developer gains by approving a request are the one exception to local allow +rules being inactive, because they record an answer to the organization's own +approval requirement rather than granting new access. See +[Approval-required access](access-controls/network.md#approval-required-access). + When organization governance is active, a user's organization policies are evaluated together, as described in [Rule evaluation](#rule-evaluation). diff --git a/content/manuals/ai/sandboxes/governance/monitor-and-enforce/monitoring.md b/content/manuals/ai/sandboxes/governance/monitor-and-enforce/monitoring.md index bc75018dc63..5e46ba7c931 100644 --- a/content/manuals/ai/sandboxes/governance/monitor-and-enforce/monitoring.md +++ b/content/manuals/ai/sandboxes/governance/monitor-and-enforce/monitoring.md @@ -50,9 +50,18 @@ $ sbx policy inspect Balanced Use `--source` to filter by origin (`local`, `org`, or `kit`) and `--decision` to filter by outcome (`allow` or `deny`). -Use `--protocol tcp` or `--protocol udp` to filter network rules. The -`--created-via` filter selects how a rule was created: `default`, `added`, -`provisioned`, or `approval`. +Use `--protocol tcp` or `--protocol udp` to filter network rules. + +Use `--created-via` to filter by how a rule was created. Pass `default` for +preset rules, `added` for rules you added yourself, `provisioned` for rules a +kit or application added, or `approval` for rules recorded when you approved a +destination. A wide listing shows the same information per rule: + +```console +$ sbx policy ls --wide --created-via approval +``` + +See [Approval-required access](../access-controls/network.md#approval-required-access). A `STATUS` column also appears when you pass `--include-inactive`; see [Showing inactive rules](#showing-inactive-rules).