Repository navigation
Conversation
Add optional trace.uid enrichment through a plain sampled-context extractor, with explicit correlation taking precedence on all ten event builders. Register the extractor at gateway and supervisor startup and keep an INFO span active around network and HTTP deny emissions at the default log level. Integrate the Authentication event and current network APIs while retaining sanitization, policy decisions, credential handling and conditional DEBUG parenting. Document per-decision traces and export/retention limits. Signed-off-by: Harry Turner <harry.github@loopfeed.com>
Remove the top-level trace object and Trace profile from the existing 1.1/1.3 projection path, keeping this compatibility contract separate from native trace correlation. Test trace removal for both legacy targets and native OTLP body preservation, including source-event immutability. Document the legacy trace contract without redesigning downgrade behavior or claiming full schema conformance. Signed-off-by: Harry Turner <harry.github@loopfeed.com>
|
All contributors have signed the DCO ✍️ ✅ |
|
I have read the DCO document and I hereby sign the DCO. |
|
recheck |
Merge NVIDIA/OpenShell main at d223943. Keep both resource_details and the Trace schemas in the vendored schema README, correct its object count and preserve the refresh instructions. Retain both published correlation commits and the tested source tree 247a27f. Signed-off-by: Harry Turner <harry.github@loopfeed.com>
|
The README conflict is resolved, and the updated branch passes the local checks. Could a maintainer please vet and approve the CI workflows? Fresh Linux/Collector/Tempo validation remains pending. |
rhuss
left a comment
There was a problem hiding this comment.
cc-review Summary
@HarryMoss, please have your agent assess each of these comments and check it against the code before acting on it. Some may turn out not to apply, and I would rather you confirm or refute them than take them at face value.
This review comes from an agent-assisted run with several reviewers (cc-review: seven prompt reviewers plus Codex and CodeRabbit, then a skeptic/calibration pass). The findings and the scenarios in them come from the agents reading the code. Nothing was executed or reproduced, and I have not verified each scenario myself.
What Went Well
crates/openshell-otel/src/correlation.rscurrent_ocsf_trace_correlationonly correlates when the span context is both valid and sampled.crates/openshell-ocsf/src/trace.rskeepsopenshell-ocsffree of OpenTelemetry through aOnceLockextractor, andenrichnever overrides an explicit trace.crates/openshell-ocsf/src/events/base_event.rsset_traceadds thetraceprofile only once.crates/openshell-ocsf/src/format/downgrade.rsstrips both thetracefield and the profile for 1.1 and 1.3, with tests for each target.crates/openshell-supervisor-network/src/telemetry/tests.rsexportedchecks real OTLP/gRPC exports instead of only the JSON shape.
Findings
| Severity | File | Description | Source |
|---|---|---|---|
| Important | crates/openshell-supervisor-network/src/telemetry.rs:32 |
Paired deny event and finding get different trace IDs | gator |
| Minor | crates/openshell-server/src/cli.rs:669 |
Gateway trace.uid is caller-propagated but documented as trusted |
security |
| Minor | crates/openshell-supervisor-network/src/l7/middleware.rs:466 |
Capacity-exhausted finding marked deny when allowed | correctness |
| Minor | crates/openshell-supervisor-network/src/l7/middleware.rs:487 |
Load shedding traced as policy deny | goal-alignment |
| Minor | crates/openshell-supervisor-network/src/l7/middleware.rs:1004 |
denied: predicates untested |
test-quality |
| Minor | crates/openshell-supervisor-network/src/proxy.rs:1261 |
Transparent middleware deny not parented on connect span (see below) | correctness |
| Minor | crates/openshell-supervisor-network/src/proxy.rs:5677 |
Non-canonical rejection gets no deny span | codex |
| Minor | crates/openshell-supervisor-network/src/proxy.rs:5956 |
CONNECT/FORWARD deny-span wiring untested | test-quality |
| Minor | crates/openshell-supervisor-network/src/proxy.rs:6072 |
Audit-mode L7 failure traced as enforced deny | codex |
| Minor | crates/openshell-supervisor-network/src/proxy.rs:6660 |
parent: is a no-op for non-deny events |
architecture |
| Minor | crates/openshell-supervisor-network/src/proxy/trace_tests.rs:80 |
Debug deny test lacks count and uid checks | test-quality |
| Minor | crates/openshell-supervisor-network/src/telemetry.rs:11 |
Local ocsf_emit! shadows the upstream macro |
architecture |
| Minor | crates/openshell-supervisor-network/src/telemetry.rs:41 |
Deny classification split between event and flag | architecture |
| Minor | crates/openshell-supervisor-network/src/telemetry.rs:55 |
Deny-span policy/host attributes never asserted | test-quality |
| Minor | crates/openshell-supervisor-network/src/telemetry.rs:64 |
One exported root span per deny, no rate gate | production |
| Minor | crates/openshell-ocsf/src/builders/network.rs:121 |
.trace() setter on 10 builders used only by tests |
architecture |
| Minor | crates/openshell-otel/src/lib.rs:49 |
Supervisor filter moved into shared public API | architecture |
| Minor | docs/observability/ocsf-json-export.mdx:281 |
Docs mention the internal builder API | architecture |
Outside the diff: crates/openshell-supervisor-network/src/proxy.rs:1261. The transparent-TCP fail-closed middleware deny calls emit_middleware_uninspectable without the live connect_span, unlike the sibling transparent denies, so at debug level this deny is not linked to the connect/authorize trace even though the docs say it should be. An optional parent parameter, or wrapping the call in connect_span.in_scope(...), would fix it.
Observation: the supervisor.egress.deny span and its openshell.policy.* keys live in telemetry.rs, separate from the supervisor.egress.* spans in proxy/egress.rs, and the attribute values come from string-keyed evidence lookups. Shared constants would keep the two in sync.
Review Details
- Findings posted: 18
- Findings reviewed and not posted: 0
- Gate outcome: FAIL (one Important finding)
- Participating reviewers: architecture, correctness, goal-alignment, production, security, test-quality, gator, codex (CodeRabbit ran with no findings)
| impl<'a, EndpointState> NetworkActivityBuilder<'a, EndpointState> { | ||
| /// Set trace correlation explicitly instead of using the active span. | ||
| #[must_use] | ||
| pub fn trace(mut self, trace: crate::TraceCorrelation) -> Self { |
There was a problem hiding this comment.
Minor: All ten builders gain a public .trace(TraceCorrelation) setter with typestate plumbing, but only tests call it; production correlation goes through the registered extractor.
Why this matters: That is about 130 near-identical lines of public API, and TraceCorrelation.uid is a public String whose 32-hex invariant is only documented. The PR description lists the setters as intended, so treat this as a design question.
Suggested fix: Either let tests use BaseEventData::set_trace and drop the setters, or keep one validating constructor with a private field.
Source: architecture agent
Integrate upstream snapshot c4688aa while retaining optional trace correlation in the borrowed/shared-context builders. Signed-off-by: Harry Turner <harry.github@loopfeed.com>
Group companion audit records and terminal response findings under one denial span. Keep ordinary transport errors out of enforced-denial spans, retain available HTTP policy context, and export the OCSF class as an integer. Clarify propagated context and the additional Trace-profile applicability, with regression coverage and operator documentation. Signed-off-by: Harry Turner <harry.github@loopfeed.com>
|
Thanks for the review, @rhuss. The follow-up at 910509993e18659404e923a2aa33d772a4ae5655, following the upstream integration, groups companion deny records and terminal response failures under one decision span, corrects caller-propagated correlation wording, and keeps ordinary I/O failures out of enforced-denial spans. Forward evaluation-error spans retain the HTTP policy context, and The final source tree is The docs now explicitly identify Trace applicability on the eight extra classes as an OpenShell extension beyond official OCSF 1.8 HTTP/API applicability. Please confirm whether that extension is acceptable. Fresh Linux and default-level Collector/Tempo validation with allowed/schema controls, NVIDIA CI approval/completion and reviewer reassessment remain pending. This remains Draft; earlier independent deployment results apply only to |
Merge upstream 42671c2 while retaining optional correlation and the current native OCSF 1.8 event contract. Add exact Trace-profile schema variants with reproducible composition for the documented applicability extension. Preserve required Process/SSH builder state, destination authorization and OTLP relay behavior. Group unsupported CONNECT companion audit records under one deny scope. Signed-off-by: Harry Turner <harry.github@loopfeed.com>
|
@krishicks @TaylorMutch wdyt? Could we try to get this PR in? All findings from my review are addressed (I checked each against
CI also still needs @HarryMoss is there anything left before moving the PR out of |
|
Thanks @rhuss. Yes please, a fresh Podman + Collector/Tempo check on Local macOS validation on that exact source tree is complete, including the affected Rust suites, six-crate all-target Clippy, schema checks and docs checks. Fresh Linux CI and the deployed check are still pending. I have resolved the 16 review threads you confirmed as addressed and left the public @krishicks @TaylorMutch, could you please vet/approve CI and advise on the three choices above: the Trace applicability extension beyond HTTP/API, keeping or dropping the public setters, and vendored versus generated profile schemas? I can make the corresponding changes once the intended direction is clear. I will keep this as a draft pending those decisions and the outstanding validation. Thanks for helping move this forward. |
|
Written by Claude Code, reviewed by @krishicks Thanks @HarryMoss for the thorough work, and @rhuss for driving the review. Here are maintainer decisions on the three open questions, plus a few more items. Severity follows rhuss's scale. References are to DecisionsTrace profile applicability: emit Public Schema catalog: vendor only what Findings
Important: restrict
Important: changes to audit records need calling out. Besides adding correlation, several existing records change meaning:
These look like correct fixes. Those were denials that lacked an action. But they shift SIEM deny counts. Please put them in their own commit and mention them in the PR description and docs. Minor: make Minor: set the OTLP log record's trace context. Minor: derive deny classification from the event. The decision still comes from three places:
Minor: guard against the upstream Minor: bound deny-span volume. Every denied decision exports a root span, and the workload controls how often it is denied. A tight retry loop against a blocked host can fill the batch exporter queue and cause the supervisor's other spans (startup, policy) to be dropped. Please add a per-destination rate limit on deny-span creation. OCSF records stay unaffected. Nit: Nit: test harness cost. Each trace test starts a loopback OTLP gRPC server behind a global lock. Keep one or two end-to-end export tests and use an in-memory exporter for the rest. Nit: commit structure. This would review and bisect better as separate commits:
|
Summary
Adds optional
trace.uidcorrelation to OCSF audit records emitted within a valid, sampled OpenTelemetry span, so operators can find the corresponding trace. Dedicated supervisors with OTLP tracing enabled emit INFO deny spans at the default log level, and companion audit records share one decision scope, including unsupported CONNECT required-middleware refusals.This remains a draft pending the validation and maintainer decisions below.
Related Issue
Closes #2640
Changes
openshell-ocsfhas no OpenTelemetry dependency.ocsf.class_uidattributes; ordinary transport failures and allowed/audit/fail-open controls do not create enforced-denial spans.Submitted revision
Head:
fed4f94257a49d44b5380678ecd32c16b1bf64b3. Verified source tree:4170b2aca8db928bdf5319a52e125a847ae6d42d. Integrated upstream snapshot:42671c2dd2c02b744850e0bda72b99d5509969c1. The submitted tree exactly matches the locally validated review candidate. Existing commits and review history are preserved; the original3fae097abranch remains unchanged.Testing
macOS arm64, Rust 1.95.0, locked dependencies and repository default profiles. All results below apply to source tree
4170b2aca8db928bdf5319a52e125a847ae6d42d; server validation and Clippy completed on 2 November 2026.-D warnings.The earlier space-limited server attempt was resumed using the same source, toolchain and configuration. No implementation change was needed for the completed validation.
Fresh Linux compilation/tests and deployed default-level deny-to-Collector/Tempo validation with allowed/schema controls remain pending for this revision. Local loopback exporter tests do not establish a deployed pass. Kevin's independent review and rhuss's earlier deployed check apply only to
3fae097a5d4355eeff77746f3ea90e89228455e3.Shared supervisor hosts currently initialize no OTLP exporters and provide no automatic sandbox trace correlation. NVIDIA CI approval/completion, maintainer disposition of the Trace applicability/explicit setter API and reviewer reassessment remain pending.
Checklist