You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: rfc/0009-supervisor-middleware/README.md
+33-23Lines changed: 33 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -151,8 +151,8 @@ Configuration-time:
151
151
152
152
Request-time:
153
153
154
-
-`EvaluateHttpRequest` carries the operation phase (`pre_credentials`) plus context: request identity, endpoint and header context, optional originating process data (the binary, pid, and ancestor chain OpenShell resolves when available for network policy and audit), the bounded body, and the middleware's configuration from policy.
155
-
-`HttpRequestResult` is a response OpenShell can apply directly: `allow` or `deny`, optional replacement content and allowed header mutations, findings (labels, counts, confidence, never raw matched values), and namespaced metadata.
154
+
-`EvaluateHttpRequest` carries the selected binding ID and operation phase (`pre_credentials`) plus the request context, middleware configuration from policy, HTTP request target, safe header subset, and bounded body.
155
+
-`HttpRequestResult` is a response OpenShell can apply directly: `allow` or `deny`, a safe reason, optional replacement content, allowed header mutations, findings (labels, counts, confidence, never raw matched values), and namespaced metadata.
156
156
157
157
A simplified sketch of the gRPC contract:
158
158
@@ -179,23 +179,35 @@ message MiddlewareBinding {
179
179
string phase = 3; // e.g. "pre_credentials"
180
180
}
181
181
182
-
// Context plus body as two top-level fields, so the body is cleanly separable.
map<string, string> metadata = 7; // namespaced, no raw values
225
235
}
226
236
```
227
237
228
-
The evaluation and result are shaped so middleware composes cleanly in a chain. The transformed content a middleware returns (`HttpRequestResult.body`) is the same request body the next middleware receives as `HttpRequestEvaluation.body`, and the allow/deny decision travels as a separate signal in `Outcome` rather than being mixed into the content. The supervisor feeds one stage's `body` (and allowed header mutations) as the input to the next stage, so a chain is effectively a fold over a single request representation; a `deny` from any stage short-circuits the rest. See [Middleware ordering](#middleware-ordering) for how chains are assembled and ordered.
238
+
The evaluation and result are shaped so middleware composes cleanly in a chain. The allow/deny decision is a first-class result field rather than being mixed into content. If `has_body` is true, the transformed content a middleware returns (`HttpRequestResult.body`) becomes the request body the next middleware receives as `HttpRequestEvaluation.body`; if `has_body` is false, the supervisor keeps the previous body. The supervisor also feeds allowed header mutations into the next stage, so a chain is effectively a fold over a single request representation; a `deny` from any stage short-circuits the rest. See [Middleware ordering](#middleware-ordering) for how chains are assembled and ordered.
229
239
230
240
Header mutation is deliberately narrow in v1. Middleware may only append safe, non-credential request headers approved by OpenShell. It cannot remove headers, rewrite existing headers, or set credential-bearing and request-routing headers such as `Authorization`, `Cookie`, `Host`, `X-Amz-*`, or OpenShell credential placeholders. This keeps request-body transformation useful while preserving the credential boundary and avoiding a second, middleware-owned routing surface.
231
241
232
242
The interface is gRPC. The hot-path v1 RPC is unary: the supervisor buffers the bounded body, sends one `HttpRequestEvaluation`, and receives one `HttpRequestResult`. Streaming is deliberately not baked into `EvaluateHttpRequest`; if OpenShell later needs chunked or incremental processing, it should add a separate operation-specific method rather than changing the v1 method cardinality. Possible extensions (streaming operations, additional operation phases, semantic context) are collected in the [protocol-extensions appendix](appendices/protocol-extensions.md). The baseline middleware ships in the supervisor and is served in-process over the same gRPC contract, with no network hop. The exact field set is settled during implementation; the sketch above is the contract shape this RFC asks reviewers to evaluate.
233
243
234
-
The `actor` process is the same identity OpenShell already resolves on the egress path - the binary, pid, and ancestor chain it uses for binary-scoped network policy and OCSF audit. It is resolved when the connection is established, so it is per-connection rather than strictly per-request: over a reused or pooled connection it identifies the process that opened the connection, which a middleware should not over-trust for per-request attribution. The field is optional because proxy-only or future shared-supervisor modes may not have reliable actor data; middleware must treat missing actor data as "unavailable" rather than as an authorization failure.
244
+
The `originating_process`is the same identity OpenShell already resolves on the egress path - the binary, pid, and ancestor chain it uses for binary-scoped network policy and OCSF audit. It is resolved when the connection is established, so it is per-connection rather than strictly per-request: over a reused or pooled connection it identifies the process that opened the connection, which a middleware should not over-trust for per-request attribution. The field is optional because proxy-only or future shared-supervisor modes may not have reliable process data; middleware must treat missing process data as "unavailable" rather than as an authorization failure.
0 commit comments