NVIDIA / NVIDIA/OpenShell

feat(policy): add JSONPath predicates for REST request bodies

Open
#1,848 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

state:stale
Dominant language
Rust
Stars
8.7k
Forks
1.3k
Avg merge
2d 11h
Merged PRs (30d)
253

Description

Problem Statement

OpenShell REST L7 policy can restrict by host, port, binary, HTTP method, path, and query parameters. Some REST APIs put the security-relevant authorization target inside the JSON request body, so path/query policy cannot express the intended least-privilege rule.

Example: Microsoft Graph sendMail is a REST call, not GraphQL:

POST https://graph.microsoft.com/v1.0/users/agent-mailbox@example.com/sendMail
Content-Type: application/json

The path identifies the sending mailbox, but the allowed recipient is only in the request body. With current REST L7 rules, policy can allow or deny the entire sendMail endpoint, but cannot express: allow this tool to send email only to allowed-recipient@example.com, with no cc/bcc recipients.

Proposed Design

Allow protocol: rest rules to include JSONPath predicates over the request body, evaluated fail-closed before forwarding upstream.

Example desired policy:

network_policies:
  outlook_send_self:
    name: outlook-send-self
    endpoints:
      - host: graph.microsoft.com
        port: 443
        protocol: rest
        enforcement: enforce
        rules:
          - allow:
              method: POST
              path: /v1.0/users/agent-mailbox@example.com/sendMail
              json_body:
                max_bytes: 262144
                assertions:
                  - selector: $.message.toRecipients[*].emailAddress.address
                    op: all_equal_ci
                    value: allowed-recipient@example.com
                  - selector: $.message.toRecipients
                    op: length_eq
                    value: 1
                  - selector: $.message.ccRecipients
                    op: empty_or_absent
                  - selector: $.message.bccRecipients
                    op: empty_or_absent
    binaries:
      - path: /usr/local/bin/outlook-send-self-email

Example Microsoft Graph payload:

{
  "message": {
    "subject": "Poem about DGX Spark",
    "body": {
      "contentType": "Text",
      "content": "DGX Spark wakes with silicon light,\nA desk-side star for models in flight.\nThrough tensors bright and memory wide,\nIt keeps tomorrow close beside."
    },
    "toRecipients": [
      {
        "emailAddress": {
          "address": "allowed-recipient@example.com"
        }
      }
    ],
    "ccRecipients": [],
    "bccRecipients": []
  },
  "saveToSentItems": true
}

Required semantics:

  • Apply only to JSON request bodies.
  • Fail closed if the body is missing, malformed, too large, or cannot be evaluated.
  • Do not log request body contents or selected values.
  • Deny rules should continue to take precedence over allow rules.
  • Deny responses should identify which assertion failed without leaking body data.

Alternatives Considered

This is related to #1272. The content_filters proposal there is more flexible and could solve this use case by running a supervisor-side filter script over the request body.

The request here is for a simpler declarative policy UX for common structured JSON API cases. JSONPath predicates would be enough for this example, but either approach would unblock the underlying need: allow or deny REST requests based on fields inside the JSON body.

One workaround we found is to put the recipient validation in a dedicated precompiled helper tool, then use OpenShell policy to restrict the sensitive endpoint so only that tool can call it.

Agent Investigation

  • Reviewed the current policy schema: REST L7 rules support method, path, and query matching; GraphQL rules support operation type/name/fields; request body credential rewrite is for placeholder substitution, not arbitrary JSON allow/deny predicates.
  • Confirmed Microsoft Graph sendMail is a REST endpoint with recipient information inside the JSON body, not a GraphQL operation payload.
  • Reviewed existing related issues: #1272 covers general scriptable content filters, #1022 covered GraphQL-specific body inspection, and #459 covered request-body credential placeholder rewriting.

Checklist

  • I've reviewed existing issues and the architecture docs
  • This is a design proposal, not a "please build this" request

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the current policy schema and architecture docs, then inspect the related proposals in #1272, #1022, and #459. The issue is a design proposal rather than an implementation task; completion would require an agreed declarative JSONPath predicate design covering fail-closed evaluation, precedence, size limits, and safe denial reporting.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.