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
Checklist
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
sendMailis a REST call, not GraphQL: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
sendMailendpoint, but cannot express: allow this tool to send email only toallowed-recipient@example.com, with no cc/bcc recipients.Proposed Design
Allow
protocol: restrules to include JSONPath predicates over the request body, evaluated fail-closed before forwarding upstream.Example desired policy:
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:
Alternatives Considered
This is related to #1272. The
content_filtersproposal 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
sendMailis a REST endpoint with recipient information inside the JSON body, not a GraphQL operation payload.Checklist