Skip to content

feat(l7): add JSON-RPC policy enforcement#1865

Open
krishicks wants to merge 35 commits into
mainfrom
hicks/push-nvuozlywzuwu
Open

feat(l7): add JSON-RPC policy enforcement#1865
krishicks wants to merge 35 commits into
mainfrom
hicks/push-nvuozlywzuwu

Conversation

@krishicks

@krishicks krishicks commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds JSON-RPC L7 policy enforcement for sandbox proxy traffic. The implementation supports JSON-RPC endpoint configuration, rpc_method matching, scalar object params matching, forward-proxy inspection, CONNECT tunnel inspection, and deny-if-any-denied batch handling.

JSON-RPC enforcement applies to sandbox-to-server HTTP request bodies sent to the configured endpoint. It does not yet enforce policy on server-to-client JSON-RPC messages carried on MCP SSE streams or response bodies. Tool results continue to pass because responses are relayed, not matched against rpc_method.

Related Issue

Closes #1793

Changes

  • Add JSON-RPC as an L7 endpoint protocol in policy parsing, validation, proto conversion, and relay dispatch.
  • Parse JSON-RPC HTTP request bodies into normalized call metadata for single requests and batch arrays.
  • Extend OPA policy input and Rego rules to enforce rpc_method and flattened scalar object params matchers for allow and deny rules.
  • Inspect JSON-RPC request bodies on both forward-proxy and CONNECT tunnel paths before relaying upstream.
  • Evaluate JSON-RPC batch items independently and deny the whole batch when any call is denied.
  • Redact raw JSON-RPC params from L7 logs and record endpoint, RPC methods, params SHA-256 digest, and policy version instead.
  • Document current JSON-RPC directionality limits and params matcher scope.

Testing

  • mise run pre-commit passes
  • Unit tests added/updated
  • E2E tests added/updated (if applicable)

Additional targeted checks:

  • cargo test -p openshell-sandbox jsonrpc
  • mise run e2e:rust -- --test forward_proxy_jsonrpc_l7

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable)

@copy-pr-bot

copy-pr-bot Bot commented Jun 10, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown

@krishicks krishicks force-pushed the hicks/push-nvuozlywzuwu branch 2 times, most recently from 62da29d to 8dc2a54 Compare June 11, 2026 15:20
@krishicks krishicks marked this pull request as ready for review June 12, 2026 16:35
@krishicks krishicks requested review from a team, derekwaynecarr and mrunalp as code owners June 12, 2026 16:35
@johntmyers johntmyers added the gator:in-review Gator is reviewing or awaiting PR review feedback label Jun 13, 2026
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

Validation: This maintainer-authored PR is project-valid because it implements the JSON-RPC/MCP method-level policy work discussed in #1793, with documented v1 scope around sandbox-to-server HTTP request inspection.
Head SHA: 8dc2a54f9b99d2aa297ccfd49c102ea10ce982f4

Review findings:

  • Blocking: crates/openshell-sandbox/src/l7/jsonrpc.rs flattens JSON-RPC params into dot-separated keys without rejecting literal dotted keys or collisions. A request can present arguments.scope as a top-level param while sending a different nested arguments.scope object path to the upstream server, which can bypass params selectors. Please fail closed on ambiguous/dotted param keys or preserve nested params through policy evaluation.
  • Blocking: crates/openshell-sandbox/src/proxy.rs only force-denies GraphQL parse errors in the forward-proxy path. JSON-RPC parse errors are carried in request_info.jsonrpc.error but can still be allowed by generic REST-style method/path rules such as access: full or read-write. Please include JSON-RPC parse errors in the same force-deny path.
  • Warning: forward-proxy JSON-RPC audit logs use generic FORWARD_L7 / l7 output and omit RPC methods, params digest, and policy version, while the CONNECT path has richer JSON-RPC logging.
  • Warning: json_rpc.on_parse_error and json_rpc.batch_policy appear accepted by policy YAML but are not enforced or converted into proto behavior. Please either implement them or reject/remove them from the accepted schema.

Docs: Fern docs were updated for the new policy schema and sandbox policy behavior.

Next state: gator:in-review

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Follow-Up

Head SHA: 8dc2a54f9b99d2aa297ccfd49c102ea10ce982f4

The required independent reviewer pass confirmed the two blocking findings from the previous gator review:

  • JSON-RPC params flattening can create a policy/upstream parser differential through dotted-key collisions.
  • Forward-proxy JSON-RPC parse errors are not force-denied, so invalid JSON-RPC can still be allowed by generic method/path rules.

Additional non-blocking warning from the independent review:

  • parse_jsonrpc_call accepts any object with a string method and does not require "jsonrpc": "2.0". If this endpoint is documented as JSON-RPC 2.0 enforcement, malformed objects should become parse errors and follow the same fail-closed path.

The earlier warnings also still apply: forward-proxy JSON-RPC audit logs are less detailed than CONNECT logs, and json_rpc.on_parse_error / json_rpc.batch_policy are accepted in YAML but not preserved or enforced in runtime policy semantics.

Next state: gator:in-review

@johntmyers johntmyers added the test:e2e Requires end-to-end coverage label Jun 15, 2026
@github-actions

Copy link
Copy Markdown

Label test:e2e applied for 8dc2a54. Open the existing run and click Re-run all jobs to execute with the label set. The run will execute the standard E2E suite after building the required gateway and supervisor images once. The matching required CI gate status on this PR will flip green automatically once the run finishes.

@ddurst-nvidia

ddurst-nvidia commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

I would recommend adding an Action to add a test the functionality from and to modelcontextprotocol/conformance and through OpenShell.

There is an action, but I don't think it's setup by default in a useful way for testing through OpenShell.

There everything-{client,server} stand ins that can be used to validate. If something isn't supported, we can just mark it as unsupported, but it reduces surprises for people using it.

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Re-check After Maintainer Update

I re-evaluated latest head 8dc2a54f9b99d2aa297ccfd49c102ea10ce982f4 after @ddurst-nvidia's 2026-06-15 comment recommending OpenShell-through-MCP conformance coverage.

Disposition: not resolved yet. There has not been a new commit or author response after the existing gator review feedback, and the maintainer testing recommendation is additional review feedback to address or have explicitly waived by a maintainer before this can advance.

Remaining items:

  • Blocking: JSON-RPC params matching still needs to fail closed on ambiguous dotted keys/collisions or preserve nested params through policy evaluation.
  • Blocking: JSON-RPC parse errors in the forward-proxy path still need the same fail-closed handling as GraphQL parse errors.
  • Review feedback: please address @ddurst-nvidia's recommendation for MCP conformance coverage through OpenShell, or get a maintainer decision that this does not need to block this PR.
  • Non-blocking warnings remain around forward-proxy JSON-RPC audit log detail, accepted-but-unenforced json_rpc.on_parse_error / json_rpc.batch_policy, and JSON-RPC 2.0 validation strictness.

Checks: required branch, Helm, DCO, docs preview, and standard Rust/Python checks are currently passing. OpenShell / E2E is still pending because the labeled E2E run needs execution.

Next state: gator:in-review

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Re-check After CI Update

I re-evaluated latest head 8dc2a54f9b99d2aa297ccfd49c102ea10ce982f4 after the labeled E2E run completed.

Disposition: not resolved. The PR still has unresolved review feedback, and the required OpenShell / E2E gate is now failing.

Remaining items:

  • Blocking: JSON-RPC params matching still needs to fail closed on ambiguous dotted keys/collisions or preserve nested params through policy evaluation.
  • Blocking: JSON-RPC parse errors in the forward-proxy path still need the same fail-closed handling as GraphQL parse errors.
  • Review feedback: please address @ddurst-nvidia's recommendation for MCP conformance coverage through OpenShell, or get a maintainer decision that this does not need to block this PR.
  • CI: OpenShell / E2E failed in run https://github.com/NVIDIA/OpenShell/actions/runs/27429202249. The failed jobs are e2e / E2E (rust-podman), e2e / E2E (rust-docker), e2e / E2E (rust-podman-rootless), e2e / E2E (python), and kubernetes-e2e / Kubernetes E2E (Rust smoke). The failed-log download was not available to this gator run, so a maintainer or author should inspect the failed Run tests steps in the Actions UI before deciding whether this is PR-caused or infrastructure-related.

Next state: gator:in-review

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Re-check After CI Log Review

I re-evaluated latest head 8dc2a54f9b99d2aa297ccfd49c102ea10ce982f4 after inspecting the failed OpenShell / E2E logs for run https://github.com/NVIDIA/OpenShell/actions/runs/27429202249.

Disposition: not resolved. The PR still has unresolved review feedback, and the failed E2E logs now show an actionable policy regression.

Remaining items:

  • Blocking: JSON-RPC params matching still needs to fail closed on ambiguous dotted keys/collisions or preserve nested params through policy evaluation.
  • Blocking: JSON-RPC parse errors in the forward-proxy path still need the same fail-closed handling as GraphQL parse errors.
  • Review feedback: please address @ddurst-nvidia's recommendation for MCP conformance coverage through OpenShell, or get a maintainer decision that this does not need to block this PR.
  • CI: OpenShell / E2E is failing. The logs show existing non-JSON-RPC L7 paths hitting an OPA evaluation error in crates/openshell-sandbox/data/sandbox-policy.rego: object.get(jsonrpc, "method", null) expects an object. This appears to make the new JSON-RPC matcher unsafe when request.jsonrpc is null/missing, causing GraphQL/HTTP L7 E2E regressions such as failed GraphQL forward/CONNECT tests, Python sandbox policy L7 tests returning status 0, and a Kubernetes smoke L7 bypass test returning 403 instead of 200.

Next state: gator:in-review

@krishicks krishicks force-pushed the hicks/push-nvuozlywzuwu branch 2 times, most recently from e9786e2 to 3516a0b Compare June 15, 2026 19:03
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Re-check After Author Update

I re-evaluated latest head 3516a0be911c2717d5789fde4ed6a70ea1a6a9c0 after the new commits addressing the prior JSON-RPC review feedback and adding MCP conformance coverage.

Disposition: partially resolved.

Resolved items:

  • JSON-RPC params matching now fails closed on literal dotted keys / flattened selector ambiguity.
  • Forward-proxy JSON-RPC parse errors now force-deny before generic L7 policy evaluation.
  • Unsupported json_rpc.on_parse_error / json_rpc.batch_policy YAML fields are now rejected instead of silently accepted.
  • MCP conformance coverage has been added, and the direct conformance runner command is wired in the expected client-mode shape.

Remaining items:

  • Blocking: crates/openshell-sandbox/data/sandbox-policy.rego still calls object.get on request.jsonrpc without first proving it is an object. The Rust L7 evaluator serializes non-JSON-RPC requests as "jsonrpc": null, so object.get(request, "jsonrpc", {}) can still return null and then object.get(jsonrpc, "method", null) can hit the same OPA type error seen in the prior E2E logs. Please guard with is_object(jsonrpc) and add a regression test for the actual "jsonrpc": null input shape.
  • Warning: .github/workflows/mcp-conformance.yml still checks out modelcontextprotocol/conformance by mutable tag v0.1.11 and runs npm ci / npm run build in a privileged Docker-socket job with job-level secrets. Please pin the upstream checkout to an immutable commit SHA for that release. Also consider narrowing/removing job-level credentials from the third-party build step.

Checks: current branch and E2E checks are queued or pending for this head, with test:e2e still applied.

Next state: gator:in-review

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Blocked

Gator is blocked because GitHub reports this PR is not mergeable against main (mergeable_state: dirty) at head 3516a0be911c2717d5789fde4ed6a70ea1a6a9c0.

Next action: @krishicks, please rebase or merge main and resolve the conflicts so review and CI monitoring can continue. The earlier JSON-RPC review feedback and the current CI status still need follow-up after the merge conflict is resolved.

@johntmyers johntmyers added gator:blocked Gator is blocked by process or repository gates and removed gator:in-review Gator is reviewing or awaiting PR review feedback labels Jun 15, 2026
@krishicks krishicks force-pushed the hicks/push-nvuozlywzuwu branch from 3516a0b to 6d61408 Compare June 15, 2026 19:25
Comment thread .github/workflows/mcp-conformance.yml Outdated
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
repository: modelcontextprotocol/conformance
ref: v0.1.11

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My last note on this got disappeared from history.

@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Re-check After Author and Reviewer Updates

I re-evaluated latest head 6d614085a82404c0491de0af757e77f234d6631c after the new author commit and @ddurst-nvidia's 2026-06-15 review comment about MCP conformance coverage.

Disposition: still blocked. GitHub still reports this PR is not mergeable against main (mergeable_state: dirty), so review and CI monitoring cannot advance until the merge conflict is resolved.

Remaining items:

  • Blocker: @krishicks, please rebase or merge main and resolve the conflicts.
  • Review feedback: @ddurst-nvidia noted that the workflow still uses the older MCP conformance v0.1.11 release while v0.1.16 is available. Please address that or get a maintainer decision that the older release is intentional.
  • Earlier review feedback should be re-checked after the conflict is resolved and the final diff is stable.

Checks: required branch, Helm, DCO, Rust, Python, and license/header checks are passing for this head. OpenShell / E2E is currently pending with test:e2e applied, including the new MCP conformance job.

Next state: gator:blocked

@krishicks krishicks force-pushed the hicks/push-nvuozlywzuwu branch from 6d61408 to 9af3648 Compare June 15, 2026 20:31
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

Re-check After Author Update

I re-evaluated latest head 9af36485ca1b8d81799338db56df340075b3b75b after @krishicks force-pushed new commits on 2026-06-15.

Disposition: still blocked. GitHub still reports this PR is not mergeable against main (mergeable_state: dirty), so review and CI monitoring cannot advance until the merge conflict is resolved.

Remaining items:

  • Blocker: @krishicks, please rebase or merge main and resolve the conflicts.
  • Review feedback to re-check after the conflict is resolved: the JSON-RPC Rego matcher still appears to call object.get on request.jsonrpc without proving it is an object, so the prior "jsonrpc": null regression concern may still apply.
  • Maintainer review feedback: the workflow now uses modelcontextprotocol/conformance v0.1.16, but the checkout is still by mutable tag rather than an immutable commit SHA.

Checks: branch, DCO, Rust, Python, license/header, and Helm checks are currently passing or skipped for this head. OpenShell / E2E is still in progress with test:e2e applied, but gator remains blocked on mergeability first.

Next state: gator:blocked

@krishicks krishicks force-pushed the hicks/push-nvuozlywzuwu branch from 9af3648 to 7101a37 Compare June 15, 2026 21:26
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Kris Hicks <khicks@nvidia.com>
@krishicks krishicks force-pushed the hicks/push-nvuozlywzuwu branch from 0f54c83 to e3a525e Compare June 23, 2026 17:43
Signed-off-by: Kris Hicks <khicks@nvidia.com>
@krishicks krishicks force-pushed the hicks/push-nvuozlywzuwu branch from e3a525e to 91dac00 Compare June 23, 2026 17:48
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

Validation: This PR remains project-valid because it implements the JSON-RPC/MCP method-level policy work tracked by #1793, with docs and E2E coverage for the current policy schema, bridge hardening, and conformance path.
Head SHA: 91dac0086d60f1326a1b88caedab9725105ae6e5

Review findings:

  • No blocking findings remain from the current independent review.
  • Warning: .github/workflows/e2e-test.yml now exposes GITHUB_TOKEN as job-wide MISE_GITHUB_TOKEN and OPENSHELL_REGISTRY_PASSWORD. This is not blocking, but follow-up should narrow those credentials to only the login and E2E execution steps that need host-side registry auth.
  • Warning: e2e/mcp-conformance/host-bridge.py now enforces the expected bridge controls, but focused fail-closed tests would make the boundary more durable: invalid token before body read, oversized or invalid Content-Length, wrong server_url host, and unsupported env keys.
  • Suggestion: reserve the removed proto field name rpc_method in addition to field number 8 for future protobuf evolution safety.

Docs: Fern docs and MCP conformance README updates are present for the current JSON-RPC policy schema, directional behavior, SSE behavior, and NAT-tolerant bridge model.

Checks: test:e2e remains applied. OpenShell / Helm Lint is passing; OpenShell / Branch Checks and OpenShell / E2E are still pending for this head.

Next state: gator:watch-pipeline

@johntmyers johntmyers added gator:watch-pipeline Gator is monitoring PR CI/CD status and removed gator:approval-needed Gator completed review; maintainer approval needed labels Jun 23, 2026
@rpelevin

Copy link
Copy Markdown

I would treat this head as a pipeline-verification moment for three invariants, not as more schema debate.

The important thing to preserve is the boundary shape:

  1. The conformance runner can exercise the client path without receiving gateway credentials or a host-side network reconfiguration primitive.
  2. The host bridge rejects unauthenticated or oversized requests before body read, then validates the capability, expected server host, and env allowlist before launching anything host-side.
  3. JSON-RPC response frames and malformed receive-stream shapes fail closed before policy evaluation, while valid sparse SSE receive streams stay open across normal idle gaps.

The regression set I would want before merge:

  1. missing or bad bridge token with a large body is rejected before body read;
  2. oversized, negative, nonnumeric, or absent Content-Length is rejected before allocation;
  3. wrong server host with a valid token is rejected before policy rendering;
  4. unsupported or non-string env keys fail closed;
  5. client-to-server JSON-RPC response frames are hard-denied in both forward-proxy and relay paths;
  6. a valid sparse SSE stream remains open across an idle gap longer than the prior timeout;
  7. the conformance runner cannot observe or inherit host registry credentials.

If those pass on the new head, the remaining review question becomes operational confidence in the E2E gate rather than another authorization-boundary issue.

Boundary: architecture and test feedback only; no claim about using this project or running its code.

@johntmyers johntmyers added gator:approval-needed Gator completed review; maintainer approval needed and removed gator:watch-pipeline Gator is monitoring PR CI/CD status labels Jun 23, 2026
@johntmyers johntmyers added this to the OpenShell Beta milestone Jun 23, 2026
johntmyers
johntmyers previously approved these changes Jun 23, 2026
@johntmyers johntmyers added gator:merge-ready and removed gator:approval-needed Gator completed review; maintainer approval needed labels Jun 23, 2026
Comment thread architecture/sandbox.md Outdated
WebSocket upgrade and text-message rules, GraphQL operation rules, and
JSON-RPC method and params rules on sandbox-to-server request bodies. JSON-RPC
request inspection buffers up to the endpoint `json_rpc.max_body_bytes` limit.
Literal dotted keys in JSON-RPC params are rejected before policy evaluation so

@ddurst-nvidia ddurst-nvidia Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As defined by JSON-RPC 2.0, params are allowed to have .'s in them. This also pushes up to the MCP layer.

We shouldn't sacrifice compatibility, for easier enforcement/policy writing.

We could "escape.dots" or we could params.name[]?

@rpelevin

Copy link
Copy Markdown

I agree with that compatibility boundary. I would not reject the request just because a JSON-RPC params object contains a literal dotted key.

The unsafe case is not the dot itself. The unsafe case is letting the policy selector language confuse a literal property name with a nested object path.

The cleaner split is:

  1. Preserve the incoming params object as valid JSON-RPC and MCP payload data.
  2. Make policy selectors unambiguous about whether they mean a nested path or a literal key.
  3. Fail closed when a policy selector is ambiguous, not when a compatible request contains a dotted key.

If the policy language keeps dot-path selectors, I would add an explicit literal-key escape or bracket form for params keys that contain dots. Then the evaluator can distinguish:

  • nested field path
  • literal key containing dots
  • invalid ambiguous selector

The tests I would want are:

  1. params with a literal dotted key are relayed when no policy rule inspects that key.
  2. a selector for a nested path does not match a literal dotted key.
  3. a selector for a literal dotted key does not match a nested path.
  4. a policy rule with an ambiguous selector is rejected or fails closed before it can allow traffic.
  5. MCP tool arguments with dotted names remain representable without rewriting the upstream payload.

So I would move the compatibility restriction from the JSON-RPC request into the policy selector grammar. Runtime compatibility stays broad; enforcement stays precise.

Boundary: architecture and test feedback only; no claim about using this project or running its code.

Signed-off-by: Kris Hicks <khicks@nvidia.com>
@johntmyers

Copy link
Copy Markdown
Collaborator

gator-agent

PR Review Status

Validation: This PR remains project-valid because it implements the JSON-RPC/MCP method-level policy work tracked by #1793, with docs and E2E coverage for the current policy schema and conformance path.
Head SHA: 0c1e237fe3c8c53494f6cb6ce4f67a52bab6f89f

Review findings:

  • Blocking: crates/openshell-supervisor-network/src/l7/jsonrpc.rs now accepts literal dotted params and resolves flattened key collisions by letting the literal key take precedence. A request can send both "arguments.scope": "workspace/main" and "arguments": {"scope": "workspace/secret"}; OPA only sees one arguments.scope value while the upstream still receives both shapes. Because deny rules use the same flattened params map, this can mask a deny rule for the nested value. Please keep JSON-RPC payload compatibility without collapsing literal and nested selectors into the same authorization key: either fail closed on collisions, or introduce an explicit literal-key selector namespace/escape form so nested path selectors and literal dotted keys remain distinguishable.
  • Blocking: the new relay test codifies that a single arguments.scope selector can match both a literal dotted key and a nested path. Please replace it with coverage that proves nested selectors do not match literal dotted keys, literal selectors require explicit syntax, and deny rules cannot be masked by literal/nested collisions.
  • Warning: architecture/sandbox.md, docs/reference/policy-schema.mdx, and docs/sandboxes/policies.mdx currently document “literal key takes precedence.” That is unsafe as an authorization-boundary rule; the docs should describe the unambiguous selector grammar or state that literal dotted keys are ignored by current params matchers until an escaped literal selector exists.

Docs: present, but need the selector-semantics correction above.

Checks: test:e2e remains applied. Current required checks are pending on the /ok to test mirror gate, but this PR should not advance to pipeline/approval until the blocking params-selector ambiguity is resolved.

Next state: gator:in-review

@johntmyers johntmyers added gator:in-review Gator is reviewing or awaiting PR review feedback and removed gator:merge-ready labels Jun 23, 2026
@rpelevin

Copy link
Copy Markdown

I agree with the blocking direction here: literal dotted keys and nested path selectors should not collapse into the same authorization key.

The safe contract I would test is:

  1. nested selector syntax resolves only through object traversal;
  2. literal dotted-key selector syntax is explicit and separate;
  3. if a payload contains both the literal dotted key and the nested object path for the same semantic field, the policy evaluator fails closed unless the policy explicitly handles that collision;
  4. OPA or any downstream policy layer receives a typed selector result that preserves whether the value came from a nested path or a literal key;
  5. the upstream JSON-RPC payload can remain compatible, but the authorization view must be unambiguous.

The important invariant is that payload compatibility cannot become selector aliasing. If "arguments.scope" and arguments.scope can both satisfy the same selector, then a deny rule can be evaluated against one value while execution receives another. That makes the policy result non-replayable and non-verifiable.

I would split the fixture set into four cases:

  1. nested-only value matches the nested selector and enforces normally;
  2. literal dotted key does not match the nested selector;
  3. literal dotted key matches only the escaped or literal-key selector form;
  4. mixed literal-plus-nested payload fails closed unless the policy declares the collision-handling mode.

The docs should also avoid saying literal key takes precedence at the authorization boundary. Precedence is fine for generic JSON convenience, but not for a policy selector. For policy, the choices should be explicit literal selector, explicit nested selector, or collision denial.

Boundary: architecture and test feedback only; no claim about using this project or running its code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gator:in-review Gator is reviewing or awaiting PR review feedback test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support method-level governance for MCP tool calls (JSON-RPC) in sandbox policy

4 participants