Enforce permitted MCP request profiles at the forwarding boundary
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 25/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 停滞
- 技術スタック
- rust
調査の方向性
まず、PR #3199、#3241、#3251、#3335 の受け入れ基準と実装手順を読み、次に参照されている proof commit を確認します。許可された MCP プロファイル、batch および rewrite のチェック、policy/storage パス、ドキュメント、マージ済みの proof、必須チェック、人によるレビューのすべてが、記載された証跡要件を満たし、未解決の正確性上の欠陥がない状態を完了とします。
索引モデルが issue の本文から書いたものです。
説明
User Story
As a sandbox operator, I want MCP traffic checked against an explicitly permitted request revision and my method/tool policy, so that valid supported clients work and the request reaching the upstream matches the request OpenShell authorized.
Problem Statement
MCP revisions differ in request grammar, batching, method availability and HTTP metadata. An endpoint allowlist alone does not establish which revision governs a request, whether every operation is authorized, or whether middleware preserves that decision. A version-independent parser can reject valid older traffic or accept a request shape unavailable in the selected revision.
The acceptance scope is correctness around the request OpenShell authorizes and forwards. This replaces the earlier proposal's OpenShell-owned wire registry and negotiated-session/response guarantees with the request contract below. It does not describe those broader guarantees as implemented.
Impact / Why This Matters
Unconditional MCP batch rejection breaks the March 2025 request contract; unconditional acceptance admits forms later revisions prohibit. Operators also need protection against a request being inspected under one interpretation and forwarded under another after a rewrite. Requiring a proxy session registry or extra handshake round trips would add operational burden without establishing a demonstrated requirement for the method/tool authorization boundary.
Proposed Design
An operator configures a nonempty allowlist of supported exact revisions with mcp.versions. The supported vocabulary is 2025-03-26, 2025-06-18, 2025-11-25 and opt-in 2026-07-28. Omission keeps the pinned ["2025-11-25"] default; adding support in a dependency cannot widen an existing policy.
OpenShell selects one endpoint-permitted profile for each request outside valid standalone legacy initialization. That initialization is an explicit bootstrap exception: structural inspection and endpoint method policy still apply, but the client's proposed params.protocolVersion is not treated as an effective or negotiated revision. For subsequent requests, the allowlist never unions profile grammar. The missing-header fallback for legacy requests is March 2025, which must itself be allowed; it is distinct from the policy default. July 2026 requires its sessionless request metadata and matching HTTP mirrors.
Tower owns revision-specific JSON-RPC/MCP structure, method availability, direction, typed parameters and batch grammar. OpenShell owns its supported policy vocabulary, endpoint authorization, request limits, HTTP/body consistency, audit behavior and forwarding. Typed inspection is not a claim of complete JSON-schema validation.
Every policy-relevant operation is checked, including every batch member. In enforce mode a denied member prevents forwarding the complete batch. Malformed or ambiguous protocol input remains rejected in audit mode. Unknown extensions require exact-method permission; deny rules retain precedence. Generic JSON-RPC keeps its separate policy contract.
The final forwarded representation must preserve the authorization decision. Replaced bodies are reinspected and reauthorized; final header-selected grammar and required metadata mirrors are checked before forwarding. Middleware cannot change method, path or query. Future changes that alter policy inputs must reauthorize those inputs. This does not claim arbitrary tool-argument authorization or unconditional OPA reevaluation for every header change.
Client and server retain negotiation and session lifecycle ownership. This scope does not certify initialization results, validate server response contents, correlate callbacks/resumed responses, or prove equality with an earlier negotiated revision. It also does not claim complete MIME/Accept or lifecycle conformance: legacy DELETE cleanup is unsupported. Existing response forwarding, framing and streaming behavior is preserved within the tested boundaries. Any demonstrated interpretation or forwarding bypass of the retained request contract remains a correctness defect that must be fixed before closure.
Acceptance Criteria
- Canonical revision allowlists survive all policy, provider, protobuf/storage, update, projection and activation paths without silent loss or widening.
- Outside valid standalone legacy initialization, each inspected request uses one supported permitted profile; conflicting, duplicate, unknown or disallowed selection signals fail closed. Bootstrap initialization remains structurally inspected and subject to method policy without treating the proposal as the effective or negotiated revision.
- Supported valid requests and explicitly permitted extensions work; unavailable methods, invalid shapes, ambiguous JSON and bounded-request violations are rejected.
- Enforce-mode batch denial is atomic, with valid, malformed and audit controls proving the documented behavior.
- Middleware rewrites preserve the configured method/tool policy behavior. In enforce mode, denied rewrites forward no request bytes; audit may forward otherwise valid policy-denied rewrites. Malformed or profile-invalid rewrites are rejected in both modes, and forwarded rewrites have the expected representation.
- Authenticated proxy evidence covers every supported revision and a multi-version endpoint; relay evidence covers both entry paths, bootstrap, final-request checks and relevant transport rejection cases.
- Clients require no proxy-managed session registration, added handshake round trip, manual session bookkeeping or extra version-selection knob.
- User/architecture documentation states the default, ownership boundary, audit behavior and compatibility limits consistently.
- Required implementation and proof commits are merged, required checks/reviews pass, and the final upstream source matches the acceptance evidence with no unresolved in-scope correctness defect.
Alternatives Considered
- Reject or accept batches for every MCP endpoint: either choice violates one of the supported request profiles.
- Use a
disable_batchswitch or dependency-selected defaults: these create contradictory policy settings or silently changing policy semantics. - Permit only one revision per endpoint: this excludes legitimate clients using different supported revisions at the same endpoint.
- Maintain a second MCP schema registry in OpenShell: this duplicates protocol ownership already provided by Tower.
- Enforce initialization responses and session equality now: this can detect additional server/session inconsistencies, but requires an explicit policy guarantee, correlation/state ownership and resource limits. It is separately scoped unless a concrete failure shows it is necessary for the retained authorization boundary.
Agent Investigation
The implementation sequence includes #3199, #3241, #3251 and the current #3335. The latter delegates inspection to pinned tower-mcp-types 0.22.2 and includes the canonical policy-schema integration and deterministic boundary-digest correction.
Published proof commits 5e9a833ba and d34c38946 cover atomic March batch denial, actual middleware tool rewrites and per-profile sandbox execution. The final sandbox harness executed both tests successfully. The supported November conformance scenarios passed separately; neither result establishes complete conformance across all revisions. Final-head hosted Branch Checks passed; local workspace/server verification and required human review remain in progress. Issue closure requires merged acceptance evidence, not merely this implementation status.
Checklist
- I've reviewed existing issues and the architecture docs
- This is a design proposal, not a "please build this" request
- 主要言語
- Rust
- スター
- 8.7k
- フォーク
- 1.3k
- 平均マージ
- 2日 7時間
- マージ済み PR(30日)
- 243
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
NVIDIA/OpenShell のほかの issue
-
area:docs
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
-
state:triage-needed
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
area:cli state:validated
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
state:triage-needed
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
-
area:build spike state:review-ready state:stale
難易度 2/5 半日 初心者へのやさしさ 68/100
NVIDIA/OpenShell の issue をすべて見る
似ている issue
-
risk:low runtime status:in-progress type:test
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
zeroclaw-labs/zeroclaw#11023 ·
-
good first issue refactor
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
EricSpencer00/Resilient#4835 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
bisq-network/bisq-musig#204 ·
-
agent:ready documentation
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
cesarferreira/stax#890 ·