sbx: local mcp gateway and mcp governance#25559
Conversation
✅ Deploy Preview for docsdocker ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
This PR reorganizes the Docker Sandboxes governance documentation IA and adds new MCP policy governance pages. The changes are well-executed:
- Redirects/aliases: All moved pages carry appropriate
aliases:entries for their old URLs (local.md→/ai/sandboxes/governance/local/,audit.md→/ai/sandboxes/governance/audit/,monitoring.md→/ai/sandboxes/governance/monitoring/,sign-in-enforcement.md→/ai/sandboxes/governance/sign-in-enforcement/,organization.mdcarries both/ai/sandboxes/security/governance/and/ai/sandboxes/governance/org/). - Front matter: All new files have complete
title,description, andkeywordsfields. - Style: No hedge words, AI-isms, or style violations found in the new content.
- Cross-references: Relative links updated correctly throughout to reflect the new subdirectory structure.
- Vendored content: No vendored files were edited.
No issues found. The reorganization is clean and the new MCP governance content follows established patterns.
00c9d5f to
5146542
Compare
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
32 files reviewed. The PR adds substantial new documentation for the Docker Sandboxes MCP gateway and reorganizes governance pages into a cleaner IA. One minor style issue found.
Redirect coverage: All moved files correctly include aliases: entries. Verified for local.md, audit.md, monitoring.md, sign-in-enforcement.md, and the new organization.md (which aliases both the old /ai/sandboxes/security/governance/ and /ai/sandboxes/governance/org/ paths). The governance/api.md → governance/reference/api.md rename uses build: render: never so no rendered page exists at the old URL — no redirect needed.
No AI-isms found: No hedge words (simply, easily, just, seamlessly), no meta-commentary, no marketing language in the new content.
Content quality: The MCP gateway, concepts, and policy reference pages are well-structured and technically clear.
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟡 NEEDS ATTENTION
Two medium-severity findings in the new documentation. No vendored files were touched. All moved/renamed pages include proper aliases: entries for redirect coverage. New content follows style guide conventions well — no hedge words, no marketing language, correct use of select throughout.
MCP policy support needed public-facing governance documentation before broader rollout. Add a focused governance stub covering Cedar-based MCP policy concepts, approval gates, organization policy context, and audit-log coverage.
The governance section mixed policy scope, access surfaces, monitoring, enforcement, and reference pages at one level. Group governance docs into access controls, monitor and enforce, and reference; add network, filesystem, and MCP access pages; preserve old URLs with aliases and update inbound links.
The organization policy page repeated policy evaluation and access-rule details covered by the concepts and access-control pages. Trim it to admin-console management, policy type selection, team scoping, and propagation troubleshooting, and move filesystem mount troubleshooting to the filesystem access page.
MCP governance policy docs needed a Docker-specific reference for the Cedar namespace surface without teaching the full Cedar language. Add an MCP policy reference page and link it from the governance reference, concepts, and MCP access-control pages.
The MCP policy reference included stale behavior from the original runbook for context args, resource reads, prompt access, and tool category/default semantics. Update the reference against docker/mcp-gateway-enterprise source to document current Cedar actions, attributes, context fields, and gateway limitations.
The sandbox governance docs needed a final prose and sidebar-ordering pass after adding MCP policy coverage. Normalize governance subtree weights to 10-point increments, add missing reference links and API keywords, and smooth wording in the new governance pages.
Document the local MCP gateway workflow for Docker Sandboxes, including server registration, OAuth handling, static and dynamic sandbox modes, live loading, bundles, and governance cross-links. Reorder the top-level Sandboxes section weights so the new MCP gateway page has a stable place in the sidebar.
Improve the MCP gateway usage page with progressive disclosure: explain the gateway model first, add a quick start, move registration details after the first run, and remove gateway-mode diagnostics from the public local-mode flow. Add an upfront note that the Docker Sandboxes MCP gateway is separate from the Docker Desktop MCP Toolkit.
Segment the sbx mcp registration paths into remote endpoint, MCP registry, server manifest, Docker Hardened Image, local container, and local stdio options. Clarify that registration before sandbox start seeds the initial MCP catalog, while already-running sandboxes need sbx mcp load.
The previous wording exposed hosted gateway internals while explaining --local. This clarifies that --local runs registry or manifest entries as host-side stdio servers and rejects non-stdio packages.
The MCP gateway page described flags without separating endpoint URLs from metadata URLs. This adds the registration input model and clarifies that local stdio servers run on the host, not inside the sandbox.
The MCP gateway page did not state that metadata-based local registration only supports OCI stdio packages. This clarifies the OCI and host Docker requirements for --local --url registrations.
The Sandboxes security and architecture pages did not explain where MCP gateway traffic and local MCP servers sit relative to the VM boundary. This adds the gateway placement, host-side local server caveat, and MCP policy enforcement point.
MCP policy docs described default deny once Cedar evaluates a request, but did not distinguish that from the ungoverned gateway posture. This adds the pass-through versus fail-closed distinction to the access guide and reference page.
The MCP gateway page described dynamic discovery for local gateway usage, which made the local model sound broader than the supported behavior. Update the page to center explicit server exposure and add a local built-in gateway tools section, then align the MCP policy reference examples.
The built-in gateway tools section listed tool names without explaining why users or admins might see them. Add context that agents can see these gateway-owned tools and that admins govern them separately from registered server tools.
PR docker#25563 removed stale Admin Console navigation language from the sandbox docs, but this branch reintroduced it through the governance IA move. Update the reorganized sandbox governance pages to use Docker Home and AI Platform wording, and split the policy creation navigation steps so they describe distinct actions.
Admins need a concrete pattern for blocking remote MCP server registration by identity URL, plus the caveat that registration policy does not revoke existing registrations. Add the deny-list example to the MCP access policy page and record the existing-registration limitation in the MCP policy reference.
The organization policy troubleshooting section only compared network and filesystem timing even though the PR adds MCP governance. Broaden the section to cover MCP registration-time and use-time enforcement, while preserving the old heading anchor.
The previous network-versus-filesystem anchor no longer matches the broadened organization policy timing section. Remove the explicit heading ID so the page uses the new enforcement-timing heading anchor.
The MCP access guide was organized around Cedar primitives, which obscured the separate registration-time and use-time controls administrators need to combine.\n\nReframe the guide around the server lifecycle and representative admin outcomes, trim duplicate concepts content, and align related timing and reference guidance. Co-Authored-By: Codex <noreply@openai.com>
The MCP policy guide described approval as user confirmation without explaining who receives the request or how the gateway resolves it.\n\nDocument the in-protocol elicitation flow, trust boundary, client requirements, and digest-bound re-evaluation with a Mermaid diagram and aligned reference guidance. Co-Authored-By: Codex <noreply@openai.com>
The approval section opened with narration about a possible misconception instead of stating the behavior directly.\n\nLead with the per-request MCP confirmation behavior and connect the example directly to that explanation. Co-Authored-By: Codex <noreply@openai.com>
e9c5077 to
61bb4f9
Compare
The upstream workflow reorganization introduced a source link to the removed governance/org.md page, causing Hugo reference validation to fail.\n\nPoint the workflow at the organization policy page, align its terminology, and resolve the outstanding MCP registration-list style finding. Co-Authored-By: Codex <noreply@openai.com>
The policy creation steps only covered network and filesystem policies even though MCP policies follow the same administrative flow. Include MCP in the shared procedure and distinguish rule authoring only at the final step.
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
This PR adds documentation for Docker Sandboxes MCP gateway and MCP access governance. The new pages are well-structured, use active voice, avoid AI-isms, and match existing documentation style. Front matter is complete on all new files. No missing redirects needed (these are new pages, not moved ones). No markdown formatting issues found.
One low-priority style observation is noted below but does not affect user understanding.
| }; | ||
| ``` | ||
|
|
||
| `local-stdio` covers explicit commands, including commands that start a Docker |
There was a problem hiding this comment.
[LOW] Link text pattern "Use [link]" is slightly awkward
The four "Related information" list items each start with "Use [link text]" (e.g., Use [Policy concepts](...)). Per the style guide, link text should be descriptive (~5 words) and stand on its own without a leading verb. Consider using the link label directly, e.g., - [Policy concepts](../concepts.md#mcp-policies) — the MCP policy model. or similar.
Some MCP guidance depended on readers having consumed earlier lifecycle explanations, and network and filesystem concepts lacked links to their policy guides. State the registration and use-time distinction locally and add the missing policy-page references.
| resource in MCP::Server::"example" && | ||
| resource.identityURL == "https://mcp.example.com/mcp" | ||
| }; | ||
|
|
There was a problem hiding this comment.
nit: we could add inline comments here to help with the readability
| // Allow only readOnly tools in example MCP Server |
| resource or prompt permit if users don't need that capability. | ||
|
|
||
| ## Require confirmation with MCP elicitation | ||
|
|
There was a problem hiding this comment.
Could we add a screenshot of how the elicitation looks like in sbx I can provide if needed
saucow
left a comment
There was a problem hiding this comment.
@dvdksn reviewed the policy related docs, overall looks really good. Agent also returned some suggesting providing the aggregated feedback here:
1.1 Actions table: "Remote server registration needs an explicit permit"
- Where:
reference/mcp-policy.md, Actions table,registerrow. - Issue: the "Remote" qualifier implies local registrations are treated differently. They are not: registration is uniformly default-deny for
local-stdio,container-stdio, and remote servers.ValidateRegistrationhas no branch on server type (sandboxessandboxlib/mcp/policy_registration.go:66-101), andTestValidateRegistration_NoRegisterRuleDenies(policy_registration_test.go:136-153) proves both a local npx spec and a remote spec are implicitly denied without a register permit. The access-controls page already states this unqualified, so the reference row is also internally inconsistent with the rest of the PR. - Suggested: "Server registration needs an explicit
permit."
1.2 resource.category never matches at the local gateway
- Where:
reference/mcp-policy.md, Resource attributes table and Limitations. - Issue: the copy-from-catalog mechanism exists only at the remote gateway (mcp-gateway-enterprise
pkg/service/dataplane/auth_middleware.go:375-386). The local entity builder never populates category (sandboxessandboxlib/mcp/entity_builder.go:50-65, called viapolicy_interceptor.go:85), so for locally governed tools it is always the empty string. A category-keyedpermitfails closed (everything denied); a category-keyedforbidfails open (nothing blocked). In a local-scoped reference this invites rules that silently never fire. - Suggested: remove the attribute from this page, or state plainly that it is not populated for the local gateway and rules keyed on it will not match locally.
1.3 resource.type vocabulary is incomplete and partly wrong
- Where:
reference/mcp-policy.mdattribute table;access-controls/mcp.md"Restrict host-run servers". - Issues:
local-stdiois not only "explicit host commands". Metadata-resolved--localOCI servers also classify aslocal-stdio(mcpruntimeresolve.go:604-613assigns Typelocal; sandboxesentity_builder.go:77-95mapslocaltolocal-stdio).container-stdiois the manifest-OCI shape provisioned via the enterprise gateway, not the general OCI-stdio case.- Remote servers bind
remote-dcr/remote-no-dcr(sandboxesentity_builder.go:84-93). The doc omits these, so a reader who writesresource.type == "remote"gets a rule that never matches anything.
- Suggested: describe
local-stdioas host-run stdio servers (explicit commands and--localmetadata-resolved OCI images run on the host), and publish the remote values so admins do not guess. The "Restrict host-run servers" example itself still works as written.
1.4 context.oauth_scopes is not bound at the local gateway
- Where:
reference/mcp-policy.md, Context fields table. - Issue: it is bound only at the remote gateway (mcp-gateway-enterprise
pkg/plugins/providers/governor/entities.go:336). The local request builder sets onlyargsandrequest_time, and its own comment listsoauth_scopesas a remote-only input (sandboxesentity_builder.go:305-327). Locally, a rule referencing it never matches: a permit fails closed, a forbid fails open. - Suggested: scope the row to remotely enforced requests, or drop it from this local-scoped page.
1.5 context.request_time is not bound at registration
- Where:
reference/mcp-policy.md, Context fields ("Bound at each enforcement point"). - Issue: the registration check made for
sbx mcp addsends no context at all (sandboxespolicy_registration.go:83), so a time-window condition on a register permit never matches and the registration falls to default deny.request_timeis bound forinvokeTool,invokePrimordial,readResource, andgetPrompt. - Suggested: qualify: bound for invocation, read, and prompt decisions; registration decisions carry no
request_time, so time-window register rules fail closed.
1.6 code-mode generated tools are not session-scoped
- Where:
mcp-gateway.md, Built-in gateway tools. - Issue: a generated tool registers on the sandbox gateway's shared MCP server and lives until the gateway is replaced or stops; it is visible to any client connected to that sandbox's gateway, not only the session that created it (mcpruntime
codemode.go:188-208; removal only on backend replace/close,gateway.go:788-812). - Suggested: "scoped to the sandbox's gateway: generated tools are ephemeral, shared by connections to that gateway, and disappear when the gateway stops."
1.7 <server>-authorize exposure is broader than described
- Where:
mcp-gateway.md, OAuth section and Built-in gateway tools. - Issue: "only when an OAuth-backed server is exposed to the sandbox and needs authorization" is too narrow. The helper is registered for every qualifying OAuth-backed remote backend, including ones that connected with a valid token, and it supports re-authorization (mcpruntime
gateway.go:1193-1197). Only remote URL backends qualify; local stdio OAuth servers never get one (local_authorize.go:33-42). - Suggested: the gateway exposes
<server>-authorizefor OAuth-backed remote servers exposed to the sandbox (it can also be used to re-authorize); when the server is not yet authorized, the helper is the only tool that server exposes.
1.8 Smaller precision fixes
- The
context.args"too deeply nested arguments are omitted" clause is remote-only. The remote gateway enforces a 64-level depth cap; the local builder has no depth cutoff (sandboxesentity_builder.go:371-420). Either drop the clause or scope it. resource.identityURLfor explicit local commands is the resolved host command path, and for--localmetadata registrations it is alocal://stdio/<name>placeholder, not the registry URL (sandboxesentity_builder.go:103-112). Worth a sentence, since the withdraw pattern pivots on identityURL.- "If you omit
--static-mcp, the sandbox starts with an MCP gateway but no registered MCP servers" is accurate for the local mode this page documents, but in hosted/dynamic mode the registered catalog remains discoverable and loadable via gateway discovery tools. Consider scoping the sentence to the local gateway mode explicitly.
Summary
Add Docker Sandboxes MCP docs for the local gateway path, including
sbx mcpusage, OAuth behavior, bundles, explicit sandbox exposure, built-in gateway tools, and MCP access-governance documentation.Generated by Codex
Scope note for reviewers
This PR deliberately documents the local MCP gateway path only. That is the path that ships by default for Docker Sandboxes: servers and bundles are registered on the host, exposed explicitly to sandboxes, and governed through the local gateway surface.
Remote, SaaS, and self-hosted gateway behavior is intentionally out of scope for this PR. That includes dynamic discovery tools such as
mcp-findandmcp-add, remote dataplane behavior, and setup for non-local gateways. Reserving this for a follow-up PR.Preview links: