Repository navigation
docs: add MXC Policy Store feature spec - #1309
Chaz Gordish (ChazGo) wants to merge 19 commits into
Conversation
Proposed feature spec for the MXC Policy Store: an integrity-validated, versioned, read-only known-tool sandbox requirements catalog and SDK resolver. Builds on microsoft#779's config-floor data model and tightens it into a review-ready contract: independent catalog/entry/ policy versioning, ordered strong/weak tool identity, complete per-platform requirement variants, deterministic cycle-rejecting dependency resolution with an explicit v1 composition vocabulary, a resolver API split from catalog metadata inspection, immutable published revisions, and a reviewed PR/CI contribution pipeline. Scoped to what MXC owns; consumers retain access-profile mapping, authorization/elevation, persistence, composition, approval, audit, and final sandbox creation. Status is proposed and review-ready, not approved or shipped; open questions are called out explicitly with recommended answers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Core revision, matching, dependency-version, composition, metadata, and trust semantics remain ambiguous or inconsistent.
Review effort: Balanced
Findings: 6
Open (6)
Clarify policy registration versus catalog entry migration · New Define architecture selectors and variant precedence · New Dependency version ranges lack a version source · New Define unambiguous dependency policy merge semantics · New Define the public CatalogEntryMetadata return type · New Document both failure and excess-capability outcomes · New
What changed in this PR
Defines a proposed read-only MXC Policy Store and resolver contract for known-tool sandbox requirements.
Changes:
- Specifies catalog identity, versioning, platform variants, dependency composition, and governance.
- Defines proposed resolver and inspection APIs.
- Adds the specification to the documentation index.
| File | Description |
|---|---|
README.md |
Links the new feature specification. |
docs/mxc-policy-store.md |
Defines the proposed Policy Store contract. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Chaz Gordish (@ChazGo) - This work needs a broader discussion. Can you please schedule a meeting to go over the overall product story here? |
Gudge (MGudgin)
left a comment
There was a problem hiding this comment.
This doesn't belong in the mxc repository. If we want this, it should be in its own repo, perhaps named microsoft/sandbox-tool-requirements or some such.
Gudge (@MGudgin) Anis Mohammed Khaja Mohideen (@kanismohammed) sorry I was just getting this started and didn't mean to make it set off alarm bells, but it did get the conversation started early at least! I'll get something booked on the calendar. I think we do need to agree on where this should live first, because that should significantly influence how much scrutiny other design decisions will receive. Alexander Sklar (@asklar) FYI on this draft and the meeting I'll be setting up. This essentially takes your #779 design and expands upon it slightly. |
|
@microsoft-github-policy-service agree company="Microsoft" |
Define revision migration, platform selection, dependency metadata, fail-closed composition, inspection metadata, and trust outcomes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Center the first-run containment problem, document the limited support horizon and Learning Mode replacement, and move catalog ownership outside MXC. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add an in-place feature-impact and omission-defaults subsection without restructuring the reviewed document. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the selected support designation while retaining the limited lifetime, proposed SDK boundary, and not-shipped disclaimer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove speculative MXC SDK integration and describe standalone TypeScript/JavaScript, Rust, and .NET libraries, local catalog consumption, and cross-language conformance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Resolver identity, dependency, error, version-range, and dynamic path-conflict behavior remain insufficiently defined.
Review effort: Balanced
Findings: 2
Open (2)
Resolved since last review (6)
Document both failure and excess-capability outcomes Define the public CatalogEntryMetadata return type Define unambiguous dependency policy merge semantics Dependency version ranges lack a version source Define architecture selectors and variant precedence Clarify policy registration versus catalog entry migration
Restore single-tool and multi-tool policy APIs, define additive matching and filesystem floor composition, reuse MXC SDK policy types, and clarify symbol discovery, casing, diagnostics, integrity, and language consistency. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Key cross-language contract semantics remain undefined, and one TypeScript declaration example is invalid.
Review effort: Balanced
Findings: 5
Open (7)
Define an authoritative versioned SandboxPolicy schema · New Specify canonical Package URL equality rules · New Define versionRange grammar and comparison semantics · New Define normative catalog failure codes and reasons · New Define the revision digest format and inputs · New Rename function to distinguish policy from config · New Fix invalid top-level TypeScript declarations · New
| Caller-supplied identity is not verified identity. A `packageUrl` match does | ||
| not prove that the installed tool belongs to that package; the caller is | ||
| responsible for verifying that association. The library does not inspect the | ||
| tool to verify it. |
Use resolveSandboxPolicy and resolveSandboxPolicyWithDiagnostics throughout the spec, retain the original proposal's name as historical context, and make runtime and inspection declarations valid exported TypeScript signatures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The resolution and diagnostics contracts contain unresolved correctness and API ambiguities.
Review effort: Balanced
Findings: 2
Open (6)
Deduplicate contribution layers independently · New Reconcile filesystem aliases by object identity · New Use structured warning variants instead of prose strings · New Prevent silent omissions in policy-only multi-tool resolution · New Specify canonical Package URL equality rules Define an authoritative versioned SandboxPolicy schema
| **The returned policy may cover only a subset of the requested tools.** | ||
| `tool_unmatched`, `version_unparseable`, and `intent_unsupported` pairs contribute | ||
| nothing; other pairs still resolve. Callers inspect per-input diagnostics to | ||
| determine coverage. No wildcard entry fills a missing match, and there is no | ||
| `requireAllMatches` option. |
Dependencies, overlays and composition now follow the pushed spec (microsoft#1309 at 5a2c52c, docs/mxc-policy-store.md): - Dependencies contribute the referenced entry's default plus platform base additions only. A reference may name intents ({ entryId, intents: [...] }); a named intent the dependency's default does not define fails catalog validation. Dependency diagnostics report intentSelection mode "none" or "named". - Overlays use policyAdditions, intentAdditions (default intents only) and newIntents. The former overlay `intents` field is renamed to `newIntents` in the model, JSON schema, metadata and fixtures. - A catalog egress deny that overlaps another requested pair's required egress allow is removed in full, with a diagnostic naming the full destination/port scope and the contributing entries. Non-overlapping denies stay. Overlapping denies are no longer composition_conflict. - Network rule validation parses CIDRs, requires `except` blocks inside their peer, and rejects ports on icmp. - The reviewer view adds an "Added to default" column per row. - Catalog revision 2026-10-05.1 replaces 2026-10-02.1: git entryRevision 2 moves the >=2.50 bundle-fetch intent to newIntents. - New composition-catalog conformance fixture and library tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep lookup command-free with ContainerRequirements using existing v1 SDK field types. Clarify validation, structured diagnostics, PURL matching, contribution attribution, and filesystem identity while preserving the catalog composition and partial-result contract. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
PURL matching can conflate identities, public TypeScript types are not exportable, and the documented open questions conflict with the PR description.
Review effort: Balanced
Findings: 5
Open (6)
Apply type-specific normalization to PURL namespaces and names · New Export and re-export all public API contract types · New Prevent silent omissions in policy-only multi-tool resolution Specify canonical Package URL equality rules Define an authoritative versioned SandboxPolicy schema Align open design decisions with the documented review scope · New
|
|
||
| type ToolInput = string | ToolCandidate; | ||
|
|
||
| interface ResolveContext { |
| | Maintainer sign-off | Recommended answer | | ||
| |---|---| | ||
| | Approve the command-free requirements API surface? | `resolveToolRequirements` / `resolveToolRequirementsWithDiagnostics` return `ContainerRequirements` using existing v1 section types, with optional lookup context, Promise-based Node resolution, corresponding Rust/.NET bindings, and the documented partial-result contract. | |
Add focused API types, behavior tables, and Zava Agent and shared-build examples. Document per-tool catalog sources and retain the reviewed PURL and public-export corrections. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The proposed API has unresolved type-surface, execution-setting, context-precedence, and PURL-matching inconsistencies.
Review effort: Balanced
Findings: 1
Open (8)
Reject unsupported PURL components in catalog predicates · New Restrict nested ContainerRequirements to the closed access-only surface · New Resolve conflicts between projectRoot and symbols.project_root · New Remove execution timeout from access requirements or define composition semanti… · New Export and re-export all public API contract types Prevent silent omissions in policy-only multi-tool resolution Specify canonical Package URL equality rules Align open design decisions with the documented review scope
Resolved since last review (2)
| Candidate version/qualifiers/subpath are ignored with `purl_components_ignored`. | ||
| Only `detectedVersion` supplies version evidence. Invalid PURLs produce | ||
| `tool_unmatched` with `purl_invalid` for that pair, without fuzzy repair or | ||
| invocation-name retry. Invalid catalog PURLs are authoring errors. |
| export type ContainerRequirements = Pick<ContainerRequest, | ||
| "filesystem" | "network" | "ui" | "timeoutMs">; |
| export interface ResolveContext { | ||
| projectRoot?: string; | ||
| symbols?: Record<string, string>; |
| | `filesystem` | `readonlyPaths`, `readwritePaths`, `deniedPaths` | | ||
| | `network` | Directional `egress` and `ingress` policy | | ||
| | `ui` | Required `disable` when UI is present; optional `clipboard` and `allowInputInjection` | | ||
| | `timeoutMs` | Unsigned 32-bit integer | |
PROTOTYPE, pending API review. - docs/policy-store/README.md: ContainerRequirements, the internal mxc-sdk policy_store module, the v1 entry points in each SDK (promise-based Node), per-input statuses, structured warnings, exact MXC 1.0.0 validation, failure reasons, and the catalog workflow with the current test names. - docs/policy-store/design.md: replaced the drifting copy of the spec with implementation notes that point at microsoft#1309 and record the prototype's decisions and known gaps. - src/mxc-sdk/policy_store/README.md and the Node, .NET, and Rust SDK READMEs: prototype sections with examples. - .github/copilot-instructions.md: the policy_store module invariant. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
microsoft#1309 at 5c2ba8e splits the caller-facing contract into docs/mxc-policy-store-api.md and keeps the catalog design in docs/mxc-policy-store.md. Section numbers in the design doc are unchanged. Every API field, status, warning code, and error reason already matches. - Node: export PlatformVariantSelector and EgressRule, which the API spec now names as exported types, and use them in the catalog metadata and NetworkRequirement types. The shapes are unchanged. - Rust doc comments: point the old design §5 references at the matching API spec sections, and define both references in the module docs. - docs/policy-store README and design.md: link both spec documents at 5c2ba8e. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Link the split API contract and catalog design docs at microsoft#1309 head 5c2ba8e; update caller samples (Zava Agent, applyClientSettings, createRequestForTool, Node build runner). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reject unsupported catalog PURL predicate components, define conflicting project-root input handling, and clarify advisory timeout and single-source composition semantics. Preserve approved SDK type reuse and specify unset caller-owned fields across bindings, with matching conformance cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merge microsoft/mxc main at 1ce2f68 without rewriting the published or local fix ancestry. Preserve the upstream documentation layout, retain both Policy Store proposal links, and repair links moved by the documentation reorganization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Cross-platform filesystem semantics, macOS matching, incomplete SDK signatures, and missing .NET AOT coverage remain unresolved.
11 open findings
Policy Store DTOs lack NativeAOT serialization registration · New Reject unsupported PURL components in catalog predicates Rust and .NET API declarations are underspecified · New Path strings cannot resolve cross-environment filesystem identities · New Remove execution timeout from access requirements or define composition semanti… Resolve conflicts between projectRoot and symbols.project_root Restrict nested ContainerRequirements to the closed access-only surface Export and re-export all public API contract types Prevent silent omissions in policy-only multi-tool resolution Specify canonical Package URL equality rules Align open design decisions with the documented review scope
🧠 Review effort: Balanced
Require the illustrative request helper to receive an execution working directory and pass it explicitly in the Git example. Keep projectRoot as symbol-binding context and preserve all diagnostic contracts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace zero-or-one matches with optional selection and add SDK-owned per-input contribution accounting. Use output presence for the single-tool sample and report coverage without gating partial multi-tool results. Preserve caller-owned cwd, clarify local-host path identity, and add the required .NET NativeAOT plan gates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve name-only parity with Rust From<&str> and .NET implicit candidate conversion. Define borrowed/list input forms, nullable context, Task return types and cancellation-token placement, and document the string-array caveat without altering matching or diagnostic semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The cross-SDK contract omits inspection signatures and conflicts on supported network fields.
11 open findings
Reject unsupported PURL components in catalog predicates Add Rust and .NET inspection API signatures · New Resolve ingress support versus validation conflict · New Remove execution timeout from access requirements or define composition semanti… Resolve conflicts between projectRoot and symbols.project_root Restrict nested ContainerRequirements to the closed access-only surface Export and re-export all public API contract types Prevent silent omissions in policy-only multi-tool resolution Specify canonical Package URL equality rules Fix pinned SDK reference link path · New Align open design decisions with the documented review scope
3 resolved since last review
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.
| For caller-facing review, start with the [API spec](mxc-policy-store-api.md). | ||
|
|
||
| This document does not restate general MXC sandboxing concepts already covered | ||
| by the [v1 SDK reference](https://github.com/microsoft/mxc/blob/894f4c159705f5f470727e4fa1e363a2abec88f1/docs/reference/node/v1/README.md) or |
Specify Rust and .NET inspection signatures and name the existing catalog-info metadata shape. Clarify the settled single-source ingress support and limit rejection tests to unsupported composition. Retain the verified pinned reference links. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Lead with the API overview, type origins and core caller examples. Group detailed types, behavior and language bindings later, expand condensed code and explain application decisions without changing the API contract. Update design links to the reorganized sections. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The proposed contract has unresolved cross-language error transport, partial-result ambiguity, and over-broad composition risks.
13 open findings
Prevent broad deny removal from expanding access beyond requirements · New Reject unsupported PURL components in catalog predicates Use the closed identity-kind union in selection diagnostics · New Clarify unresolved-symbol behavior for partial multi-input results · New Respect case-sensitive macOS volumes during executable matching · New Remove execution timeout from access requirements or define composition semanti… Resolve conflicts between projectRoot and symbols.project_root Restrict nested ContainerRequirements to the closed access-only surface Export and re-export all public API contract types Prevent silent omissions in policy-only multi-tool resolution Specify canonical Package URL equality rules Fix pinned SDK reference link path Align open design decisions with the documented review scope
2 resolved since last review
🧠 Review effort: Balanced
| | Catalog deny overlapping a required grant | Remove the whole deny; report its full scope | | ||
| | Non-overlapping deny and grant | Keep both | |
| kind: string; | ||
| strength: "strong" | "weak"; |
| not permission to assume a default. An unresolved required symbol prevents | ||
| requirements from being returned; it is not silently dropped. |
| Invocation names compare case-insensitively and locale-independently on | ||
| Windows/macOS, and exactly on Linux. Name-only matching requires | ||
| `allowWeakIdentityFallback: true`. |
Pin spec links to microsoft#1309 head 2c682f3 and fix the usage-examples anchor (microsoft#2). Match the API samples: createRequestForTool takes workingDirectory, single-input callers check only requirements presence, and the diagnostics table wording follows the spec. Reflect that default.requirements carries access fields plus an optional advisory timeoutMs. Prototype 1103de8 is described as reconciled with 5c2ba8e. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>



📖 Description
Proposes the MXC Policy Store, building on #779, with a separate API contract for focused SDK review. This is documentation, not an implemented feature. Policy Store is proposed for the existing MXC SDK packages; it is not part of MXC 1.0, and no later release is committed.
Start with the Policy Store API contract: exported types, command-free
resolveToolRequirements/resolveToolRequirementsWithDiagnostics, observable behavior, errors, and caller examples. The Zava Agent example checks saved settings before consulting the catalog and applies client-owned settings without prescribing UI or persistence. A smaller shared-build example resolves Git and Node without diagnostics and explicitly accepts best-effort coverage.The catalog design retains authoring, validation, composition internals, packaging, and governance. Editable sources are one JSON file per tool, containing its defaults and variants; tooling assembles complete immutable revision snapshots for embedding.
Both resolver forms intentionally permit partial results. Callers needing per-tool coverage use diagnostics. Floors are best-effort starting requirements, not authorization or guarantees of success or safety; client restrictions remain authoritative. Learning Mode is complementary.
The proposed API names, exact request/schema validation pipeline and version mapping, and type-specific PURL equality rules are now specified. The remaining §13 decision is maintainer sign-off on the proposed command-free requirements API before merge and implementation.
🔗 References
🔍 Validation
Docs-only. Strict TypeScript checks passed for the public declarations and separate caller examples against pinned MXC v1 SDK types, including package exports and bidirectional type parity with the pre-split contract. Stubbed caller-flow checks cover saved-settings precedence, lookup enablement, client restrictions, warning/status/error handling, and concrete request construction. JSON examples parse, document links and anchors resolve, and
git diff --checkis clean.The caller tests use fake SDK responses and application hooks. No actual catalog lookup, native runtime build, or sandbox execution was performed by those checks.
✅ 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