Repository navigation
feat(supervisor): correlate relayed TCP events with upstream sockets - #5135
Open
vineethsai7 wants to merge 6 commits into
Open
vineethsai7 wants to merge 6 commits into
vineethsai7 wants to merge 6 commits into
Conversation
Signed-off-by: Vineeth Sai Narajala <vnarajal@cisco.com>
Signed-off-by: Vineeth Sai Narajala <vnarajal@cisco.com>
Author
|
I have read the DCO document and I hereby sign the DCO. |
Signed-off-by: Vineeth Sai Narajala <vnarajal@cisco.com>
Keep resolved ancestor executable paths as separate OCSF entries so a path containing the display delimiter cannot alter the reported process chain. Treat upstream socket address queries as optional audit metadata after the connection is authorized, preserving the relay if either lookup fails. Cover both event classes, direct and TLS proxy sockets, and clarify receiver tuple comparisons in the docs. Signed-off-by: Vineeth Sai Narajala <vnarajal@cisco.com>
Signed-off-by: Vineeth Sai Narajala <vnarajal@cisco.com> # Conflicts: # crates/openshell-supervisor-network/src/proxy.rs # crates/openshell-supervisor-network/src/proxy/egress.rs
…ilure Signed-off-by: Vineeth Sai Narajala <vnarajal@cisco.com>
8 of 9 tasks
vineethsai7
marked this pull request as ready for review
November 3, 2026 04:23
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
8 tasks
This branch has not been deployed
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.
Depends on #5134. The first 2 commits are from #5134; review only
e1a3fc756..903a54eda.Summary
Record the immediate upstream TCP socket tuple and the authorized executable digest in allowed supervisor
NetworkActivityevents. A directly connected receiver can match its accepted socket to the event and read the sandbox process identity. This is the audit correlation slice of the broader caller identity request.Related Issue
Part of #4271. The issue is still
state:triage-needed; design feedback is welcome.Changes
unmapped.upstream_socket_localandunmapped.upstream_socket_peerto their allowed OCSF events. Carry the executable SHA-256 used for authorization intounmapped.binary_sha256when identity evidence is available. Transparent TCP events now include the resolved ancestor executable paths inactor.process.Design
The supervisor already has the trusted caller identity and emits an allowed connection event. This change attaches the connected socket tuple at that point, using the existing OCSF
unmappedextension path. It does not add a policy field or change the relay. The receiver's accepted socket sees the supervisor's upstream local address as its peer when the direct path has no address translation.An opt-in PROXY protocol v2 header would deliver identity before workload bytes and support an access decision at the receiver, but it requires a new endpoint contract and receiver support. Supervisor middleware cannot inspect
tls: skipTCP, gateway interceptors do not see workload connections, and provider credentials identify a sandbox rather than a process. The header belongs in a follow-up design review.Example
Existing policy and JSON export settings suffice for this slice:
Relevant fields from an allowed event:
{ "class_uid": 4001, "container": {"uid": "sandbox-id"}, "actor": {"process": {"name": "/usr/bin/curl", "pid": 57, "parent_process": {"name": "/usr/bin/sh", "pid": 0}}}, "unmapped": { "upstream_socket_local": "127.0.0.1:41001", "upstream_socket_peer": "127.0.0.1:3129", "binary_sha256": "<SHA-256 hex>" } }For a direct connection without address translation, compare the receiver's peer address to
upstream_socket_localand its local address toupstream_socket_peer.Compatibility
The workload byte stream, network policy, and CLI are unchanged. The JSON fields are additive;
binary_sha256is omitted when identity evidence is unavailable. If the local socket address lookup fails, transparent TCP events retain their existingupstream_socket_peerfield but omitupstream_socket_local; a peer lookup failure omits both. A configured corporate upstream proxy becomes the immediate peer in this tuple. Address translation may change the tuple before the final receiver sees it. OCSF delivery is best-effort, and a backend that supplies no PID still recordsactor.process.pidas0. The new tuple, digest, and ancestor values are absent from the default shorthand log and require the opt-in JSON export. This slice supports attribution where the tuple is observable; it does not provide synchronous per-process enforcement at the receiver.Release Notes
Allowed CONNECT and transparent TCP JSON events include the upstream socket tuple for direct receiver correlation and the authorized executable digest when available.
Testing
cargo fmt --check -p openshell-ocsf -p openshell-supervisor-middleware -p openshell-supervisor-networkthroughdcb.cargo clippy --locked -p openshell-ocsf -p openshell-supervisor-middleware -p openshell-supervisor-network --all-targets -- -D warningsthroughdcb.cargo test --locked -p openshell-ocsf -p openshell-supervisor-middleware -p openshell-supervisor-networkthroughdcb: 176 OCSF, 129 middleware, and 1,588 network unit tests plus local integration tests passed; fixture-dependent tests remain ignored.uv run tasks/scripts/check_docs_nav.pythroughdcb.fern-api@5.112.0 check(0 errors; 3 warnings outside the changed page)markdownlint-cli2@0.22.0on the changed README and MDX page (0 errors)Follow-ups
Checklist
Review follow-up
Local review:
REVIEW-5135.md. GitHub had no inline review comments or submitted reviews at the time of this follow-up.c4aa964f940e: Preserve each resolved ancestor path as one OCSF process entry, including paths containing->.c4aa964f940e: Keep authorized relays running when an upstream socket address lookup fails; omit the incomplete audit tuple.903a54eda0d1: Preserve the preexisting transparent TCPupstream_socket_peerfield when only the new local address lookup fails. A regression failed before the fix and passed after it.c4aa964f940e: Use the production socket-inspection helper in the receiver-correlation test.c4aa964f940e: Explain IPv6 tuple syntax and IPv4-mapped IPv6 comparison.c4aa964f940e: Explain that an upstream proxy bypass records the direct receiver as the peer.The default shorthand log omits the new socket tuple, executable digest, and ancestor chain; the opt-in JSON export includes them. A regression checks that projection.
The runner-vetting and DCO issue comments raised no code finding. Issue #4271 remains
state:triage-needed, and the PR body saysPart of #4271; the repository's issue-acceptance and closing-reference requirements remain for a maintainer to resolve. The issue and PR were not edited in this follow-up.Manual verification
PR: NVIDIA/OpenShell #5135 (feat/4271-v1), head
c4aa964f940e910dced3e653d791727fe5a5b413.Before: upstream main
be5e49499(openshell 0.1.7-dev.40+gbe5e49499). After: the PR head.Environment
cargo build --release); supervisor and sandbox runtime packaged as local images and set assupervisor_image/sandbox_runtime_image. Gateway and CLI ran on RHEL 9 through an Ubuntu 24.04 glibc loader.ubuntu:24.04pluscurl(sha256 of/usr/bin/curlin the image:1ccbd3dae948374ba8eef1ebda26c64b783ede50b463196e53666e0880bdac60).ip:port) of every connection it accepts. The sandbox reaches it ashost.openshell.internal.Steps
Before (main)
The allowed CONNECT event (
class_uid4001, "CONNECT allowed host.openshell.internal:28125") hassrc_endpoint,dst_endpoint,proxy_endpoint,actor.process(/usr/bin/curl, parent/usr/bin/bash) andfirewall_rule, and nounmappedobject at all: no upstream socket and no executable digest. (grep -c 'upstream_socket\|binary_sha256'on the captured event: 0.)After (PR head)
Two probes sent from the sandbox, with the receiver's own log next to the event:
The
upstream_socket_localof each event equals the address the receiver saw as the connecting peer (51396,53374), andupstream_socket_peeris the receiver's listening address.binary_sha256equals the sha256 of/usr/bin/curlin the workload image. A receiver that records its accepted-socket peers can therefore map a connection back to the sandbox process that opened it.Only the CONNECT relay with
tls: skipwas exercised. The transparent-TCP relay named in the PR (ancestor paths inactor.process) was not run.Observation
actor.process.pidis0in both the main and the PR event (a pre-existing value in this Docker deployment, not caused by the PR).Result
PASS: the new
unmapped.upstream_socket_local,upstream_socket_peerandbinary_sha256fields appear in a real allowed TCP event, the socket tuple matches the receiver's accepted socket, and the digest matches the executable. None of them exist on main.