Repository navigation
feat(docker): support host and bridge supervisor networking - #4016
Conversation
|
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. |
d633562 to
16bad48
Compare
|
🌿 Preview your docs: https://nvidia-preview-pr-4016.docs.buildwithfern.com/openshell |
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
9e2288b to
8f122f7
Compare
|
Label |
TaylorMutch
left a comment
There was a problem hiding this comment.
One non-blocking telemetry concern: bridge mode changes the reachability of loopback OTLP endpoints. This can be addressed here or in a separate follow-up fix if preferred.
I reviewed the full diff and surrounding code and verified the host-gateway alias mapping in a temporary Docker Desktop bridge container. I did not run the full test suite or validate ECI itself.
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Since #4016, host e2e runs omit the Docker driver's grpc_endpoint and let the driver discover the gateway. The HTTP session hook test required the key and panicked. Fall back to loopback, which the host-networked supervisor shares with the gateway, and read the key only from the Docker driver table. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
…the middleware (NVIDIA#4359) * feat(middleware): add HTTP middleware protocol 2 Add EvaluateHttp, a streaming HTTP middleware protocol with BUFFERED and STREAM body modes, next to the released HTTP protocol 1, which keeps its engines unchanged and is deprecated for removal in 0.2.0. - One EvaluateHttp stream per HTTP message and stage, or per uninspectable connection. A preflight selects continue, inspect, or reject; late header mutations apply before the head commits. - A service implements one HTTP protocol, chosen per binding with http_protocol_version, and a protocol 2 service requires the openshell.supervisor-middleware.http-v2 capability. The gateway delivers each service's protocol to supervisors. - Protocol 2 is always fail-closed. The gateway rejects fail_open on protocol 2 services and policies whose overlapping selectors mix protocols; a mixed chain fails closed at runtime. - Protocol 2 middleware decides about uninspectable traffic (tls: skip, h2c, unsupported tunnels, raw TCP, SQL passthrough) at a preflight, and is exempt from the static tls: skip conflict rule. - Request bodies stream to the upstream unless a later step needs the whole body; responses stream with chunked framing or buffer before commit. - Migrate the content guard example to protocol 2, add a Docker e2e suite, and document the protocol. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): select HTTP protocol 2 by binding operation Replace the http-v2 capability and per-binding protocol fields with new binding operations, and stop delivering the protocol to supervisors. - HTTP_REQUEST_V2 and HTTP_RESPONSE_V2 select HTTP protocol 2. Released gateways and supervisors already reject unknown operation/phase pairs at Describe, so the capability, extension_metadata_with_requirements, and MiddlewareBinding.http_protocol_version are removed. - Drop supported_http_body_modes. The preflight offers every mode the message is eligible for, and the stage picks one or continues or rejects. A protocol 2 binding with a zero payload limit is offered no body modes. - Move the tls: skip conflict rule out of the shared policy validator into the gateway's safety validation, which knows each service's protocol. This removes the delivered SupervisorMiddlewareService protocol field, the process-wide protocol 2 set in openshell-policy, and the supervisor's undescribed-service tracking. An undescribed entry follows on_error, which the gateway requires to be fail_closed for protocol 2 services. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): split EvaluateHttp into request and response RPCs Replace EvaluateHttp with EvaluateHttpRequestV2 and EvaluateHttpResponseV2, one RPC per binding operation, as for HTTP protocol 1 and WebSocket. Both keep the shared HttpEvent and HttpResult messages, so the stage pipeline is unchanged; OpenShell picks the RPC from the preflight subject. Traffic OpenShell cannot inspect stays on the request RPC. Only services that bind HTTP_REQUEST_V2 decide about it, so only they are exempt from the gateway's tls: skip conflict rule; a response-only protocol 2 service keeps the rule and its fail-closed entry denies such traffic at runtime. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): call the new contract v2 HTTP hooks Rename "HTTP protocol 1/2" to v1 and v2 HTTP hooks across code, proto comments, docs, skills, and the example. The docs page moves to extensibility/supervisor-middleware/http-hooks-v2, the protocol2 modules become http_v2, HttpProtocol becomes HttpHookVersion, and the mixed-chain reason becomes middleware_hook_versions_mixed. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): select HTTP session hooks by required capability Rename the streaming HTTP hook RPCs to EvaluateHttpRequestSession and EvaluateHttpResponseSession, and drop the unreleased HTTP_REQUEST_V2 and HTTP_RESPONSE_V2 operations. A service keeps its HTTP_REQUEST and HTTP_RESPONSE bindings and selects HTTP session hooks for all of them by listing openshell.supervisor-middleware.http-session in its extension required_capabilities. Released gateways and supervisors already reject unmet required capabilities at Describe, so they never call such a service through the v1 RPCs. Registration rejects a manifest that supports the capability without requiring it. Mark the v1 HTTP hook RPCs, the HttpResponsePreReturn service, and the types only they use deprecated in the protobuf contract. Rename the docs page, module, and e2e suite to HTTP session hooks, and update RFC 0009 so capability-gated contracts and removing deprecated elements in a minor release match the release stability policy. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): begin body stages on every preflight mutation A body stage captured the head right after its own preflight, so its begin event lacked the preflight mutations of later stages even though the delivered head carried them. Keep the final preflight head on the pipeline and begin every stage on it plus earlier stages' late mutations, as the HttpBegin contract states. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(network): check the policy generation before every response write A STREAM response stage can keep emitting output after it consumed the upstream body, and the session response writer checked the policy generation only when it committed the head. Output and the terminating chunk then reached the client under revoked authorization, before the final check. Check the generation before every write instead, and treat the response as committed only once a byte was written. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(network): complete session hook messages only after every stage With a declared output length, a STREAM stage could emit every byte and then reject at input_end. The relay had already written a complete Content-Length message, so the sandbox saw a successful response, and on uploads the upstream received a complete request it could act on or answer. Hold back what would complete the message until every stage returns its terminal result: the final byte of a declared length, or the whole head of a declared empty body. The chunked terminator already waited. An empty response body that is rejected still gets the canonical 403. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(examples): split expanded content guard output within the chunk limit Redacting a term shorter than the marker makes STREAM output longer than its input, so one output chunk could exceed the max_chunk_bytes the preflight offered and fail the message closed. Split every output chunk within that limit. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): queue HTTP session hooks and explain failures to the sandbox Address load-test findings on HTTP session hooks: - Give HTTP session hooks their own admission budgets: 64 slots for preflight and BUFFERED bodies, and 256 for STREAM bodies so long-lived server-sent events cannot starve short messages. A message waits for a slot within the chain deadline instead of failing at once, releases it when no stage inspects the body, and frees its BUFFERED slot when the last BUFFERED stage ends. Uninspectable decisions use the same budget. - After an early middleware response (preflight rejection or failure, 503, mid-stream failure, or 408), shut down writing and discard what the sandbox still sends, within time and byte bounds, so the sandbox reads the response instead of a connection reset. - Fill originating_process (binary and ancestors) in request and response preflights, as the uninspectable preflight already did. - Return a platform-owned failure_code from a closed set, and the failed stage's policy entry name, in 403, 502, and 503 failure bodies. - Document raising gRPC message limits for 4 MiB BUFFERED bodies, and raise them in the content guard example. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): give each HTTP session hook RPC its own messages Address the proto review of the HTTP session hooks contract: - Split the shared HttpEvent/HttpResult into per-RPC messages (HttpRequestSessionEvent/Result and HttpResponseSessionEvent/Result) with direction-specific preflights, so a request stream cannot carry a response subject and the reverse. Body events and results stay shared. - Add phase to both preflights, as the WebSocket preflight has. - Add an explicit cannot_inspect result, valid wherever reject is, and drop the FAILED_PRECONDITION convention; every gRPC status now maps to middleware_unavailable. - Offer no body mode for a request whose Content-Encoding is not identity (ENCODED), as for responses: middleware would only see the encoded bytes. - Send declared_body_bytes, and apply OVER_LIMIT, only to stages before the first one that inspects the body, which may replace it. - Remove the queue limits from HttpBodyLimits; they had no defined meaning for a service. - Clarify comments: BUFFERED fails over its limit instead of falling back, finish requires output_start, and unavailable_body_modes is empty for a zero payload limit. - Document that policies stored before a service changed hook version must be re-applied. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(network): include the originating process in response preflights The main L7 response path built its middleware request context by hand with originating_process set to None, so HTTP session hook response preflights lacked the process that request preflights already carry. Build it with middleware_request_context, as the other paths do. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): retain response delivery blocking and consolidate docs Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): release the preflight slot while waiting for a stream slot A message whose stages selected STREAM kept its preflight slot while it waited, up to the chain deadline, for one of the stream slots. With every stream slot taken by open server-sent-event responses, waiting messages could hold all preflight slots and starve BUFFERED messages and uninspectable-connection decisions. Take a free stream slot immediately when one is available. Otherwise release the preflight slot before waiting, and take one again afterwards only if a BUFFERED stage runs. No message holds a preflight slot while it waits for a stream slot, so the two waits cannot deadlock. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): protect request Content-Encoding from session hook stages Response preflight already treats Content-Encoding as read-only. On requests a stage could still write or remove it. That was not a bypass, because body-mode offers come from the original head, but a stage could label a body it replaced as encoded, or drop the label from an encoded body. Session hook request heads now protect Content-Encoding. Legacy request hooks keep their released rules. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * feat(middleware): record cannot_inspect diagnostics HttpCannotInspect was empty, so a stage could not attach findings or a reason code for operators the way HttpReject can. Add diagnostics to it. OpenShell validates and records them like a rejection's, and the sandbox still sees only failure_code middleware_cannot_inspect. Also update the HttpPreflightResult comment for the per-RPC split: requests deny with reject, responses with block_delivery, and either can return cannot_inspect. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): cover cannot_inspect for uninspectable traffic and gateway restarts Uninspectable preflights can also return cannot_inspect, which refuses the connection as a failure. The gateway reads each service's Describe manifest only at startup, so re-applying policies after a service changes hook version validated them against the stale manifest. Tell operators to restart the gateway first. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * feat(middleware): let session hook stages own integrity headers Response session hooks stripped ETag, Content-MD5, Digest, Content-Digest, Repr-Digest, Signature, and Signature-Input whenever a stage replaced or streamed the body, and stages could only remove them. A STREAM stage that passed the body through unchanged still lost the upstream's validators, and no stage could supply correct new values. Requests never stripped them. Session hooks now leave these headers alone in both directions, as Envoy's external processor does. A stage that changes the body removes them or writes new values in buffered_result or output_start; a STREAM stage can read all input before output_start to compute one. Legacy response hooks keep their released stripping and remove-only rules. The content guard example removes them when it replaces a BUFFERED body, and at output_start when it streams in redact mode. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): list cannot_inspect where proto comments name stage choices The UninspectableTraffic comment and both preflights' permitted_body_modes comments still said a stage that finds no suitable mode continues or denies. It can also return cannot_inspect. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): recreate sandboxes after a service changes hook version Supervisors also cache each service's Describe manifest and rebuild their registry only when the set of service registrations changes. Restarting the gateway and re-applying policies leaves running sandboxes on the old manifest. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * test(e2e): find the middleware host when Docker discovers the gateway Since NVIDIA#4016, host e2e runs omit the Docker driver's grpc_endpoint and let the driver discover the gateway. The HTTP session hook test required the key and panicked. Fall back to loopback, which the host-networked supervisor shares with the gateway, and read the key only from the Docker driver table. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): deny uninspectable messages with reject The cannot_inspect result replaced a FAILED_PRECONDITION status convention after review, which asked only for an explicit, typed signal whose effect is the reason. A separate result went further: it added a third terminal result to every phase and a failure response (502 on responses, platform-owned failure_code) for what is a decision the stage makes. Remove HttpCannotInspect and the cannot_inspect result field from both session result messages. They are unreleased, so they are deleted, not reserved. A stage that cannot inspect a message rejects it, or blocks delivery, with a reason_code that says so. The content guard example uses reason code cannot_inspect. The platform failure_code middleware_cannot_inspect remains for messages OpenShell cannot show to a stage. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): split HTTP session RPCs into dedicated service Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): decide about uninspectable traffic in a dedicated hook Uninspectable connections (tls: skip, h2c, unsupported tunnels, raw TCP, SQL passthrough) are not HTTP, so they no longer use an HTTP session preflight. A service binds UNINSPECTABLE_NETWORK/PRE_FORWARD and serves the unary UninspectableNetworkMiddleware.Evaluate on the same endpoint. The hook carries only connection metadata, can be a service's only binding, and always fails closed. Entries without the binding keep their on_error behavior: fail_closed denies, and fail_open relays with a bypass finding. That fail_open exception is deprecated for removal in 0.2.0. The gateway tls: skip conflict rule now exempts middleware that binds the new hook. The tls: skip decision runs before 200 Connection Established, so a denial is a plain 403. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): align HTTP denial naming Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): defer inspection decisions until stage input is ready Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): document the UTF-8 rule for HttpHeader values The L7 parser rejects request heads that are not valid UTF-8 before any middleware runs. A response head that is not valid UTF-8 fails an HTTP session hook chain closed with middleware_cannot_inspect, while v1 response hooks follow on_error. Session hooks also fail a message with trailers that are not valid UTF-8. State this on HttpHeader so service authors know the string type matches what OpenShell forwards. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): tidy the unreleased HTTP session hook contract HttpRequestSessionPreflight skipped field 2 after the uninspectable subject moved to its own hook. These fields were never released, so renumber them to match HttpResponseSessionPreflight instead of leaving a gap. Rename UninspectableTrafficReason to UninspectableNetworkReason to match UninspectableNetworkMiddleware and the other new UninspectableNetwork names. Document behavior the contract left implicit: a trailer write cannot add a name, Content-Length framing drops trailers, and Process.pid is 0 when unknown. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): report the withheld STREAM output cap per route Routes that hold request output until the chain finishes capped it at 4 MiB, while the contract said STREAM has no total size limit. A pass-through STREAM stage on a SigV4 route therefore failed requests between 4 and 10 MiB that the route accepts without middleware, and the stage had no way to know. Withhold output up to the route's own buffering limit: 10 MiB for SigV4 body signing, 256 KiB for body credential rewriting, and 4 MiB otherwise. Request preflights report that limit to STREAM stages as the new HttpBodyLimits.max_output_body_bytes, so a stage can decide at preflight. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): attach trailer mutation comments to their fields The trailer mutation rules added in 9f7a04a landed on HttpInputChunk.data and inside the HttpDenial comment. Move them onto HttpBufferedResult.trailer_mutations and HttpFinish.trailer_mutations, and restore the HttpDenial comment. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): ask for identity-coded responses when a session stage can inspect bodies HTTP session hooks offer no body mode for a response with a content coding other than identity. The sandbox controls Accept-Encoding, and common clients (requests, httpx, fetch) send gzip by default, so most compressed responses reached response stages uninspectable: a guard either blocked them with cannot_inspect or let them through unread. When the response chain has an HTTP session hook stage that may select a body mode, the relay now replaces every Accept-Encoding field with identity. It does so as the last header step on both the buffered and the streamed request path, after request-stage mutations and before credential injection, so a request stage cannot undo it. Request middleware still sees the sandbox's value. v1 hooks and bindings with max_payload_bytes 0 are unchanged. An encoded response now means the upstream ignored identity. The e2e upstream gains a /compressible route that gzips when asked, and the workload asks for gzip as common clients do. Without the change the guard answers 403 cannot_inspect; with it, the response is redacted. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * feat(middleware): show response stages the forwarded request headers A response stage that needs the request's headers, such as a guard that judges a response against what was asked, had to keep per-request state keyed by request_id and route both streams to the same replica. HttpResponsePreflightHead.request_headers now carries the request headers as the request middleware chain forwarded them: after every request stage's mutations, including a streamed body's late mutations, and before OpenShell injects credentials or replaces Accept-Encoding. They have the omissions and limits of the request preflight's headers, and a value that contains a credential placeholder reads [REDACTED], as the response target's query already does. The relay hands response middleware a request that may already carry token grants, under header names the request-header sanitizer does not know, so the head is recorded before injection: by HttpMiddlewareExchange when request middleware allows the request, and before prepare_inspected_request on the inspected relay path. A live body applies its late mutations to that record when its head commits, before the upstream can answer. A response chain with no recorded head fails closed with middleware_cannot_inspect, as do request headers over the head limits. The response preflight's context comment now says request_id matches the request's preflights. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): hide credential placeholder headers from session hooks HTTP session hook heads already omit Authorization, Cookie, and other credential headers, but a credential placeholder in a custom header, such as X-Api-Key: openshell:resolve:env:API_KEY, reached request stages as-is and response stages as [REDACTED]. Whether a stage saw a placeholder depended on which header carried it. A request header whose value carries a credential placeholder, including one inside a Basic credential, is now a credential header for HTTP session hooks. The request preflight, begin, and the response preflight's request_headers omit every value of that name, and the pipeline rejects a stage mutation that writes or removes it with header_mutation_protected_header, so a stage cannot replace or drop a credential reference it cannot see. The [REDACTED] sentinel is gone. Like Envoy's ext_proc forwarding rules, OpenShell drops headers rather than masking their values; a typed list of withheld names can be added later if a stage needs to know they were present. v1 HTTP hooks keep their released behavior and still receive these headers. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): remove the uninspectable network hook The hook let middleware allow connections OpenShell cannot inspect (tls: skip, h2c, unsupported tunnels, raw TCP, SQL passthrough) by metadata alone. No published middleware uses it, and the mixed-port cases it served are better handled by selector changes, so remove it before it ships. Uninspectable traffic goes back to the chain-level on_error rule: a fail_closed entry denies the connection, and an all-fail_open chain relays it with a bypass finding. That fail_open exception is no longer deprecated. The tls: skip overlap rule returns to shared policy validation, so supervisors enforce it again alongside the gateway. The tls: skip gate still runs before 200 Connection Established, so a denial is a plain 403. The proto service, operation, phase, and enums are deleted rather than reserved because they were never released. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(policy): reject ports in middleware selector patterns Middleware selectors match hostnames on every port, but a pattern such as api.example.com:443 parsed as a hostname that never matches, so the entry was silently never selected. Reject ':' in include and exclude patterns at gateway and supervisor validation instead. IPv6 literals are still accepted. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(policy): keep IPv6 globs in middleware selector patterns Rejecting every ':' outside a complete IPv6 literal also rejected IPv6 globs such as 2001:4860:*, which selectors have matched since they shipped and network endpoints still accept. Treat a pattern containing ':' as IPv6 text instead, and reject only the shapes of a host:port authority: bracketed literals, characters IPv6 text cannot contain, dots before the last ':', a single ':' followed by digits, and invalid literals without wildcards. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * feat(middleware): send the originating process to every middleware hook v1 HTTP request hooks and WebSocket preflights now receive RequestContext.originating_process like v1 response hooks and HTTP session hooks, so every hook sees the same caller. A deep ancestor chain is trimmed, farthest ancestor first, to keep the context within its 4 KiB limit instead of failing the evaluation. Closes NVIDIA#4269 Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(policy): accept only complete IPv6 addresses in middleware selectors IPv6 globs such as cafe:* cannot be told apart from a mistyped host:port, so the heuristic that accepted them let some port patterns through as IPv6 text that never matches. Middleware selectors now accept ':' only in a complete IPv6 address. Docs add the upgrade note for policies with a port or an IPv6 wildcard. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(network): answer a JSON-RPC or GraphQL request timeout with 408 These paths read the whole body before middleware runs, so a request timeout should not occur. If it does, send the same 408 request_timeout as the REST path instead of failing the relay with a generic error. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): map session hook failures to the sandbox failure_code List request_timeout among the sandbox error codes, and name both the OCSF reason and the failure_code a sandbox sees in the troubleshooting skill. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): rename HTTP body modes to WHOLE_BODY and DUPLEX BUFFERED becomes WHOLE_BODY and STREAM becomes DUPLEX, before the HTTP session hooks ship. WHOLE_BODY matches the v1 WHOLE_BODY_BYTES name, and DUPLEX leaves room for a later PER_CHUNK mode with one result per input chunk, like Envoy ext_proc STREAMED, without two modes both called streaming. Renames the proto enum values, HttpWholeBodyMode, HttpDuplexMode, HttpWholeBody, HttpWholeBodyResult, the whole_body and whole_body_result fields, and max_whole_body_bytes, along with the Rust names, the content-guard body_mode values, tests, and docs. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): rename http-session capability to http-hooks The capability that selects the streaming HTTP RPCs is now openshell.supervisor-middleware.http-hooks. "Session" read as a cookie-style HTTP session and clashed with the WebSocket session RPC. Docs, comments, and errors call the new contract "HTTP hooks" and the deprecated contract "legacy HTTP hooks" instead of "v1". HttpHookVersion and ChainHttpHookVersion rename V1 to Legacy, with the audit label legacy_http_hook; the new contract's label is http_hook. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): rename HttpSessionMiddleware to HttpHooks Finish the http-hooks rename so no HTTP hook name still says "session": - Service HttpSessionMiddleware is now HttpHooks; Http{Request,Response} Session{Event,Result,Preflight} messages are now Http*Hook*. - http_session modules, the e2e test, and the mise task and CI suite are now http_hooks / middleware-http-hooks. - HttpHookVersion and ChainHttpHookVersion rename Session to Current; HeaderAuthority renames Session{Request,Response} to Hook*. - HttpRequestSession and HttpResponsePipelineSession are now HttpRequestPipeline and HttpResponsePipeline, carried in a `pipeline` field; MAX_CONCURRENT_HTTP_MIDDLEWARE_SESSIONS is now ..._MESSAGES. Shared stream names (MiddlewareSessionEnd, session_capacity_exhausted) and WebSocket session names are unchanged. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): name HTTP hook budgets after their slots "Messages" and "streams" read as gRPC messages and streams. The two budgets are buffering slots (preflight and WHOLE_BODY) and streaming slots (DUPLEX or deferred stages), as the docs already call them: - MAX_CONCURRENT_HTTP_MIDDLEWARE_MESSAGES -> MAX_HTTP_HOOK_BUFFERING_SLOTS - MAX_CONCURRENT_HTTP_MIDDLEWARE_STREAMS -> MAX_HTTP_HOOK_STREAMING_SLOTS - http_{hooks,stream}_admission -> http_{buffering,streaming}_admission, with matching reserve helpers and debug fields. The streaming budget comment now says deferred stages also take a slot, matching may_stream(). The docs limits row counts HTTP requests and responses instead of messages. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * docs(middleware): align HTTP hooks contract wording with review feedback State how zero-limit HTTP hooks bindings interact with the operator payload limit, align the HTTP/1.0 DUPLEX rule with the proto, document the 403 for a DUPLEX request denied after upstream output starts, and make failure_code wording consistent across the docs. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * test(middleware): cover zero-limit HTTP hooks bindings and late DUPLEX request denial Pin that a zero-limit HTTP hooks binding is excluded from the operator payload limit comparison, and that a DUPLEX request denied after its output started upstream still gets the canonical 403 and an unterminated upstream body. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(middleware): give HTTP hook RPCs package-unique names Rename HttpHooks.EvaluateRequest and EvaluateResponse to EvaluateHttpRequestHook and EvaluateHttpResponseHook, and document in supervisor_middleware.proto that RPC names must be unique across the package's services, with the naming pattern for future hook services. Python and Go servers name handler methods after the RPC alone, so one object implementing several services needs distinct names. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(middleware): mark HTTP hooks response denials in OCSF findings Set ActionId::Denied on the HTTP hooks http_response_blocked finding and on the after-commit delivery failure when a stage stopped delivery, so both hook versions emit the same OCSF for the same decision. Assert that a DUPLEX request denied after upstream start leaves the chunked upstream body unterminated. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> --------- Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Summary
The Docker supervisor previously required host networking. Add an operator-owned
supervisor_network_modesetting so deployments can explicitly use host or bridge networking. Host remains the default, andautoselects host.Bridge callbacks preserve explicit endpoints and TLS verification. Docker's actual host address is discovered automatically once when the driver starts, so Desktop deployments do not confuse the VM's bridge gateway with the host. All runtime changes are confined to the Docker driver; the supervisor is unchanged.
Related Issue
Related to #4015. Automatic ECI mode selection and ECI sandbox-runtime compatibility remain outside this PR's scope.
Changes
network=noneand the existing isolation requirements for workloads.host.docker.internal, resolve Docker'shost-gatewayonce during driver construction and cache the IP for all sandbox launches.--help, wait for exit, and download Docker's generated/etc/hoststhrough the archive endpoint. No shell ordocker execis used.host_gateway_ipremains an optional override that skips discovery.Validation
192.168.65.254and verified no resolver container remained after either successful discovery or a deliberately failed container start.