docs: add sandbox config floors feature spec - #779
Open
Alexander Sklar (asklar) wants to merge 1 commit into
Open
docs: add sandbox config floors feature spec#779Alexander Sklar (asklar) wants to merge 1 commit into
Alexander Sklar (asklar) wants to merge 1 commit into
Conversation
Proposes config floors: a repository-hosted table describing the minimal filesystem and network access a developer tool needs to function, plus an SDK resolver that reads it. Today every host discovers a tool's sandbox requirements independently, by hand, and hardcodes the result in its own source tree. For agents this is structural rather than tedious -- an LLM-driven caller selects tools at runtime, so the host author cannot enumerate them in advance. Design summary: - A floor IS a Policy -- same type, same schema, same vocabulary. What distinguishes it is the direction of the bound: a policy is an upper bound stated by the host, a floor is a lower bound stated by the tool ecosystem. - An entry is an envelope identifying a tool, wrapping a verbatim SandboxPolicy. The inner object is not a new type, so floors express new Policy fields the day they ship, and validation is inherited. - Spawn requirements live in the envelope via `requires`, never in the inner Policy. SandboxPolicy has no process/spawn field and this spec does not propose adding one. - Identity is name-first and layered: a predicate must be falsifiable against a local artifact. Identity is a precision mechanism, not a security boundary. - getSandboxConfigForTool returns SandboxPolicy | undefined. `undefined` rather than an empty Policy, so absence of data cannot be confused with a claim of zero requirement. Design only -- no implementation, no schema changes. Per docs/authoring-a-new-feature.md this is SDK-library-only: it adds neither a cross-platform security restriction nor backend-specific configuration. Builds on #673 (dev-tool cache discovery; its security properties are carried forward) and #748 (captureDenials on the typed SandboxPolicy, which the authoring pipeline in section 5.1 consumes).
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a design specification for repository-hosted sandbox configuration floors and SDK-based resolution.
Changes:
- Defines floor data, identity, dependency, and symbolic-path models.
- Proposes TypeScript and Rust resolver APIs.
- Documents authoring, trust, compatibility, and testing plans.
Show a summary per file
| File | Description |
|---|---|
docs/sandbox-config-floors.md |
Introduces the config floors feature specification. |
Review details
Tip
Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Suppressed comments (5)
docs/sandbox-config-floors.md:261
- Neither SDK currently has generic
SandboxPolicymerge semantics; the existing helpers only return filesystem fragments for callers to concatenate (sdk/node/src/policy.ts:19-27,mxc_engine/src/policy.rs:27-35). This also cannot be inferred as a simple union: allow lists broaden by union, deny lists narrow by union, andtimeoutMs,tempDir, and clipboard values need explicit conflict rules. Define a merge algebra/API or restrict floor fields before making dependency closure depend on it.
**Composition.** A command line that invokes several tools resolves to the union
of their policies. `npm install && npm test` composes cleanly. Union is over
Policy objects using the SDK's existing merge semantics — not a floor-specific
rule.
docs/sandbox-config-floors.md:832
- For
['npm', 'unknown'], this return is indistinguishable from resolving['npm'], so the caller cannot know the floor is incomplete. Logging is insufficient because SDK diagnostics are best-effort and disabled by default (sdk/node/src/diagnostic.ts:119-137). Return matched/unmatched tools (and resolution warnings) alongside the policy, or return per-tool results, so hosts can safely refuse or warn.
When *some* tools match and others do not, the function returns the union of the
floors that did match. A tool with no entry contributes nothing, which is the same
result as a tool whose floor is empty — correctly, since neither asserts a
requirement. Only the all-unmatched case is distinguishable, and it is the one
that matters: `undefined` rather than a policy.
docs/sandbox-config-floors.md:876
- Current denial capture does not report network endpoints.
learning_mode_core/src/model.rs:53-54reservesResourceType::Networkfor future capture, and the Windows extractor only emits files, registry/other, and capabilities (learning_mode/windows/src/extractors.rs:25-32,167-172). It therefore cannot deriveallowedHostsor configured-registry floors. Scope this pipeline to filesystem/capability data, or acknowledge network capture as a new prerequisite rather than claiming the existing capability is sufficient.
- **Denials are raw.** Capture reports the paths and endpoints a specific run
touched. A floor is the *minimal generalized* requirement. Going from one to
the other is a human judgement, made by the contributor before submission.
docs/sandbox-config-floors.md:952
- This safety claim contradicts the supported direct-adoption path in §2.1. Because the resolver returns a
SandboxPolicy, a host can use a malicious floor directly; broad filesystem/network requirements then become granted authority and can enable data access or exfiltration, not merely rejection. Either make composition with a host-authored policy part of the API contract/enforcement, or classify direct floor adoption as unsafe and remove the claims that adoption can never reduce containment.
This is safe because of §2: a floor is a hint used to construct a request, not a
grant of authority. A malicious or wrong floor can ask for anything; policy
still decides, and the enforcement boundary is untouched. The worst outcome from
bad floor data is a tool that fails to run, or a host that constructs a request
policy then rejects.
docs/sandbox-config-floors.md:661
tempDiris not a field of either current SDK return type: TypeScriptSandboxPolicy.filesystemhasclearPolicyOnExitinstead (sdk/node/src/types.ts:346-359), and RustFilesystemSectionhas the same shape (mxc_engine/src/policy.rs:425-434). A resolver returning this field therefore cannot satisfy the promised existingSandboxPolicytype without a Policy API change. Remove it from the floor vocabulary or explicitly include the required Policy changes in scope.
"tempDir": { "enum": ["shared", "isolated"] }
- Files reviewed: 1/1 changed files
- Comments generated: 3
- Review effort level: Balanced
Comment on lines
+248
to
+252
| **Per-entry policy versioning.** Because the embedded object carries its own | ||
| `version`, entries authored against different Policy versions coexist in one | ||
| table. An entry pinned to `0.6.0-alpha` stays valid when the current version moves | ||
| on. This is the existing versioning design (`docs/versioning.md`) doing its job, | ||
| not a new mechanism. |
Comment on lines
+449
to
+453
| "tool": "some-mcp-server", | ||
| "identity": [ | ||
| { "kind": "npm-package", "name": "@vendor/some-mcp-server" } | ||
| ], | ||
| "requires": [ |
Comment on lines
+778
to
+780
| | OS well-known folders | `${localappdata}` | environment variable, or the platform's folder API | | ||
| | Tool configuration | `${npm_prefix}`, `${npm_cache}`, the configured registry | the tool's own config chain — `npm config get`, `.npmrc`, `NPM_CONFIG_*` — where an environment variable is only one of several layers, and not the one that usually wins | | ||
| | Request-relative | `./package.json` | `projectRoot`, defaulting to cwd | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📖 Description
Design review requested. No implementation in this PR.
Adds a feature spec (
docs/sandbox-config-floors.md) proposing config floors: a repository-hosted table describing the minimal access a developer tool needs in order to function, plus an SDK resolver that reads it.Today every host discovers this independently, by hand, and hardcodes it in its own source tree. For agents it's structural rather than tedious — an LLM-driven caller picks tools at runtime, so the host author can't enumerate them ahead of time.
🎯 Scope
docs/authoring-a-new-feature.md. No change to Policy, ContainerConfig, or executor behavior.getSandboxConfigForTool, returning an existing type.🔍 Where review effort is best spent
🔗 Related
captureDenialson the typedSandboxPolicy) — §5.1 consumes this. The authoring pipeline is a consumer of existing capability, not a new requirement.✅ Validation
Design-only, so no automated coverage. Checked on the document: all JSON examples parse (including the §3.2 schema,
$defsfully connected), all internal§references resolve, all external links resolve.§8 is the test plan for the eventual implementation.
✅ Checklist
Cargo.lock, thedependency-feed-checkcheck passes (see docs/pull-requests.md)📋 Issue Type
GitHub Actions runs the PR validation build automatically. The ADO pipeline
(
MXC-PR-Build) is the Azure version of the PR pipeline, kept in parity with the GitHubActions build; it runs on merge to
main, and Microsoft reviewers with write access can trigger iton a PR with
/azp run. See docs/pull-requests.md.If the
dependency-feed-checkcheck fails on a new dependency, the crate must be added tothe feed before the PR can pass. See docs/pull-requests.md
for the steps.
Microsoft Reviewers: Open in CodeFlow