Validate and normalize SandboxPolicy before supervisor activation
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 25/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- kubernetes, rust, yaml
調査の方向性
まず、issue で言及されている gateway の起動/リロード、combined-topology の OPA 構築、sidecar の control-socket の bootstrap/update、OPA YAML/protobuf loaders、および policy-advisor の /wait endpoint を洗い出します。次に、既存の policy-load テストと parity テストを確認し、受け入れ基準を使って、これらの経路全体で一貫した検証、正規化、プロトコル動作、エラーの上限、および snapshot の再チェックを確認します。
索引モデルが issue の本文から書いたものです。
説明
User Story
As an OpenShell operator, I want every code path that turns policy input into active runtime state - including gateway startup/reload, combined-topology OPA construction, sidecar bootstrap/update, and OPA YAML/protobuf conversion - to enforce one effective-policy contract: validate and normalize a SandboxPolicy at typed-policy boundaries and apply equivalent schema validation and normalization at OPA-native data boundaries, so the policy cannot change meaning between save, serialization, transport, and supervisor activation.
Problem Statement
In Kubernetes sidecar topology, the network supervisor sends policy to the process supervisor in bootstrap and update messages over the local Unix control socket. The sandbox policy loader can also convert protobuf or YAML data into OPA input and the internal policy used for enforcement. Each boundary can interpret policy before validation and normalization unless it checks the policy explicitly.
The known concrete failure is MCP: YAML alias lowering can discard the mcp_versions array while protobuf conversion retains it, giving the same authored policy different runtime meaning. The same failure mode is relevant to any protocol-specific policy field that is dropped or reinterpreted by one loader; the implementation must establish the invariant for the complete policy rather than add an MCP-only exception.
Impact / Why This Matters
Without validation in each policy-loading handler, a protocol-specific option can reach enforcement code even though the policy compiler would reject it. A YAML-loaded policy and a protobuf-loaded policy can then authorize different traffic, and a bootstrap or update path can install a different policy from the one stored by the gateway. The operator may believe the configured policy is active while the supervisor is using a weaker or different interpretation.
This can affect any endpoint whose policy travels through an affected bootstrap, update, YAML, or protobuf path, including REST, GraphQL, WebSocket, generic JSON-RPC, and MCP endpoints. A policy that changes meaning across restart, live update, or serialization format can authorize requests the operator did not approve or reject requests the operator expected to allow.
Proposed Design
OpenShell validates and normalizes the complete SandboxPolicy at each listed typed-policy boundary, before installing supervisor state or constructing enforcement input. At the OPA-native YAML boundary, it validates the complete OPA data schema it accepts and applies equivalent normalization before the data is installed in OPA; it does not need to fabricate a reverse SandboxPolicy for data that has no complete typed representation. The listed boundaries include gateway-provided startup and reload data, combined-topology OPA construction, sidecar bootstrap and update messages, and OPA YAML/protobuf conversion. For Kubernetes sidecar topology, the same check applies to the policy bootstrap and update messages sent from the network-supervisor sidecar to the process supervisor over the local control socket. Each protocol keeps its own policy contract: omitted MCP revisions resolve to the pinned default, valid MCP allowlists use deterministic ordering, and invalid, duplicate, unsupported, or misplaced MCP values are rejected before activation.
All listed policy-loading paths produce the same effective SandboxPolicy for the same authored input, including every protocol-specific field. An endpoint with protocol: json-rpc, REST, GraphQL, or WebSocket retains its own protocol behavior and does not acquire MCP revision state. Failure messages identify which policy load was rejected and remain bounded; they do not include the policy body or credential material.
The policy-advisor /wait endpoint evaluates coverage once for each installed policy snapshot and proposed rule, regardless of protocol, and repeats the check only when a new snapshot is installed. This preserves the comparison while avoiding a full comparison of an unchanged snapshot on every timer tick.
Acceptance Criteria
- The gateway runtime startup/reload path, combined-topology OPA startup/reload, and sidecar control-socket bootstrap/update validate a complete
SandboxPolicybefore installing supervisor state; OPA-native YAML loading validates the complete schema it accepts before creating enforcement input. - In Kubernetes
topology: sidecar, the process supervisor rejects invalid policy in the initial control-socket bootstrap message before installing it; MCP omission still materializes the pinned revision when omission is valid. - Policy-update messages sent over the sidecar control socket apply the same validation and normalization as bootstrap for every protocol.
- Where the same authored policy is representable in both formats, OPA protobuf and YAML policy loaders produce the same validated and normalized effective
SandboxPolicyand preserve all protocol-specific fields, including the MCPmcp_versionsarray; OPA-only data files are validated against their own schema before becoming OPA input. - MCP options on a non-MCP endpoint, explicit empty YAML
mcp_versionslists, duplicates, padded values, unsupported revisions, and draft revisions fail before lowering or enforcement; a missing or empty protobuf repeated field follows the documented pinned-default behavior because protobuf does not preserve authoring presence. - REST, GraphQL, WebSocket, and generic
protocol: json-rpcendpoints retain their own behavior, receive validation for their own policy fields, and do not receive MCP revision state. - Representative policy-load and YAML/protobuf parity tests cover REST, GraphQL, WebSocket, generic JSON-RPC, and MCP policies; MCP tests cover omission, invalid values, and revision-array preservation.
- The policy-advisor
GET /v1/proposals/{chunk_id}/wait?timeout=<s>endpoint does not repeat full coverage validation for an unchanged policy snapshot and does recheck a newly installed snapshot for a matching proposed rule. - Runtime errors are bounded and contain no policy payload, credentials, or raw request body.
- Tests cover sidecar bootstrap/update, YAML/protobuf parity, omission and invalid values, generic JSON-RPC preservation, and unchanged-versus-replaced
/waitsnapshots.
Alternatives Considered
Validating only when the gateway saves a policy is insufficient because the running supervisors can receive older records, direct protobuf messages, or data produced by another path. Each listed active-runtime boundary must validate the complete policy before it installs supervisor state or creates enforcement input.
Fixing only the known MCP field or trusting protobuf while leaving YAML lowering unchanged would preserve one input path while silently dropping a protocol-specific policy field on another. YAML and protobuf must produce the same validated and normalized SandboxPolicy, and the same rule must apply to sidecar bootstrap and updates.
Agent Investigation
No response
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日 6時間
- マージ済み PR(30日)
- 297
コントリビューションガイド
はじめの一歩
- 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
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
state:needs triage
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
zed-industries/zed#64680 · コメント 2 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
RustPython/RustPython#8802 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
TheLarkInn/aipm#2390 ·