Repository navigation
Conversation
Add TcpHooks.EvaluateConnection: one stream per admitted upstream connection and stage, selected by TCP_CONNECTION/PRE_CONNECT bindings of services that require openshell.supervisor-middleware.tcp-hooks. The preflight runs before the upstream dial and can deny the connection. In STATS mode the stage receives cumulative upstream byte totals at its interval, only when they moved. A close result aborts the open connection through a metered upstream stream. TCP hooks always fail closed. The hook runs at the CONNECT, transparent TCP, and forward-proxy dial sites. TCP-only services no longer make traffic required to be inspectable: the runtime uninspectable gate ignores them, and the tls: skip conflict check moves from static policy validation to the gateway's registry-aware validation. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
The service selects STATS for every connection, sums upstream bytes per sandbox and policy key in a sliding window, and when a window passes the threshold closes that key's open connections and denies new ones. A smoke suite cuts a burst over tls: skip and checks denial of new connections. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
The stage task dropped its response stream right after queueing TcpEnd, which cancelled the RPC before the end was flushed. Connections that closed before their first stats tick reported nothing, so a transfer split into short connections was never counted. Half-close the request side and drain the stage's responses, bounded by 5 s. Add a split-transfer scenario to the egress-usage smoke suite. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
The middleware config in the sandbox policy now sets max_bytes, window, interval, block_for, and direction, with per-policy-key overrides. Flags supply defaults. ValidateConfig rejects invalid values at policy set, and the smoke suite lowers a budget through a policy update. Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
…ike) Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Spike 02b of the egress usage monitoring RFC. A new TCP connection middleware hook with a STATS mode. A middleware service sees a preflight for every admitted upstream connection, gets cumulative byte counts while it is open, and can deny or close it. Stacked on NVIDIA#4359 (base
1c982faca). This is spike-quality code: it works end to end, but it skips docs, gateway tests, and parts of the contract design.Read first:
examples/supervisor-middleware-egress-usage/README.md. It covers the example service, configuring limits in the policy, and running the smoke suite.Compare with the OCSF-based approach in #5 (spike 01b).
Context
Network policy decides where a sandbox can connect, but not how much it uses an allowed endpoint. An agent allowed to reach a package proxy can download its whole catalog. Several sandboxes can also use one writable path as a message board. The RFC asks for usage accounting per sandbox and policy key, plus a way to act on it.
The RFC's running example: sandboxes reach
artifactory.internal:443under the policy keypkg_proxy, which allowsGETandPUT. Two detections cover the two shapes of misuse:PUTto one host within 5 minutes. The reaction denies writes for those sandboxes.This spike targets D2 by extending the existing middleware model (NVIDIA#4359) from HTTP content to TCP connections. Enforcement then happens in the data path rather than through a policy update.
How this spike solves it
flowchart LR subgraph SUP["Sandbox supervisor"] P["Network policy<br/>admission"] --> H["TCP hook stage<br/>preflight, stats, close<br/>(new)"] H --> R["Relays + metered stream<br/>(new)"] end H <-- "TcpHooks.EvaluateConnection<br/>bidi stream per connection" --> M["Egress-usage service<br/>windows per sandbox + key<br/>(example, operator-run)"] POL["Sandbox policy<br/>network_middlewares.config"] -. "limits" .-> M GW["Gateway"] -- "ValidateConfig on policy set" --> M R --> U["Upstream<br/>(tls: skip, raw TCP, HTTP)"]TcpHooks.EvaluateConnectionstream per matching stage. The preflight carries host, port, inspection kind, policy key, sandbox id, and the policy's middlewareconfig. The service answers continue, inspect with STATS at an interval (1–60 s), or close, which denies. It covers CONNECT (includingtls: skipand raw TCP), transparent TCP, and the forward proxy.bytes_outandbytes_ineach interval, only when they changed, and an end event with final totals.config, whose shape this example service defines (OpenShell passes it through opaquely):max_bytes,window,interval,block_for,direction, and per-key overrides. The gateway callsValidateConfigonpolicy set, so invalid limits are rejected up front.closeon every open connection for that key. Pending reads and writes abort within milliseconds. New connections for the key are denied at preflight forblock_for. Other keys keep working. Denials and cuts emit OCSF Network Activity events with reasonegress_budget_exceeded.fail_openis rejected for TCP stages.Strengths
block_for.openshell policy set, per policy key, without redeploying the service.tls: skip, raw TCP, and inspected HTTP, and never sees payloads.Weaknesses
network_middlewaresentry is not observed.tls: skipendpoints, port selectors. D1 is not implemented here.Changes
TcpHooks.EvaluateConnectionbidi stream, operationTCP_CONNECTION, phasePRE_CONNECT, and capabilityopenshell.supervisor-middleware.tcp-hooks.tcp_hooks.rsholds the metered stream, the per-stage tasks, and the session.proxy.rs, and OCSF deny and close events inproxy/tcp_hook.rs.tls: skipconflict check moved to gateway validation (validate_tcp_hook_rules).examples/supervisor-middleware-egress-usage/:usage.rs(windows and reactions) andconfig.rs(policy limits).policy.yaml, a host-run upstream, andsmoke.sh.Results
tls: skipat 10 MB/spkg_proxyconnection after the tripother_svcstill allowedpolicy setwithmax_bytes: lotsValidateConfigpolicy setlowersother_svcfrom 50 MB to 10 MBIn the eval harness (20 MiB / 60 s, 5 s interval), 02b blocked 9 of 10 abuse scenarios with no false positives across 5 benign scenarios. The 200 MB burst was cut 3.0 s after the threshold with 30 MB through. The miss is D1, which is not implemented.
Testing
smoke.sh --test-suiteon the Docker driveropenshell-core,openshell-supervisor-middleware,openshell-policy,openshell-supervisor-network,openshell-servermiddleware, and the example's config and window testsvalidate_tcp_hook_rules. The oldtls: skipconflict tests are ignored or removed.