Add sealed ETL denial analysis (replacement for #699) - #709
Open
richiemsft wants to merge 12 commits into
Open
Conversation
Introduce the learning_mode_core crate as the cross-platform hinge of the captureDenials pipeline (PR4/PR5 foundation): - model: DeniedResource / ResourceType (file|ui|network|capability|other) / AccessType, camelCase wire contract with round-trip + key-stability tests. - summary: DenialSummary terminator (exitCode, totalDenials, deniedResourcesTruncated). - frame: self-describing type-tagged DenialFrame (denial|summary). - emit: RFC 7464 (0x1E-framed) NDJSON stream writer over any io::Write. - analyze: DenialAnalyzer decode trait + AnalyzeError, implemented per-OS by the backend ETL decoders (Windows first). No OS-specific code; 16 unit tests + 1 doc-test, clippy/fmt clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Decode the learning-mode `.etl` that CaptureSession::finish seals into cross-platform learning_mode_core::DeniedResource values, implementing the DenialAnalyzer trait. - path_norm: kernel-form -> drive-letter, incl. the `\??\C:\...` / `\??\UNC\...` DOS-devices prefix the trace actually emits. - tdh_decode: TDH EVENT_RECORD -> (event_id, props). - extractors: route event 14/4907 (access check) by ObjectType (File -> file, Key -> registry/other, empty -> capability) and derive accessType from AccessMask with a File/Registry right vocabulary (Write > Execute > Read); event 27 -> Ui; event 28 -> capability denial (Denied gate, payload ProcessId). Missing/unparseable mask degrades to Unknown rather than dropping the denial. - etl_decode: file-mode OpenTraceW/ProcessTrace loop + dedup by (user-visible path, accessType). - examples/lm_analyze: NDJSON emit + `--raw` event dump for validation. Event vocabulary and AccessMask classification confirmed on the GE_CURRENT x64 VM against real block-and-log (Mode="Normal") and allow-and-log (Mode="Permissive") captures: File/registry denials decode identically in both modes; capability denials arrive as empty-ObjectType event 14 (permissive) or event 28 (block). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Factor the pure decode composition (extract_denial routing -> path normalisation -> dedup) out of EtlDenialAnalyzer::analyze into resources_from_events, and cover it with tests built from the event shapes captured on hardware for both learning modes: - block-and-log (Mode="Normal"): file/registry event 14 + capability event 28 - allow-and-log (Mode="Permissive"): capability folded into empty-ObjectType event 14 (no event 28) - empty-path capabilities from event 14 and event 28 collapse to one resource - non-actionable object types / not-denied records / unknown event IDs dropped A live ETW/TDH fixture read is intentionally not used: it needs the provider manifests registered on the machine, and a raw capture embeds token SIDs that don't belong in a public repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Allocate TRACE_EVENT_INFO storage with its required alignment and decode UTF-16 payloads from byte pairs so unaligned ETW data never forms invalid Rust references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Stream raw ETL diagnostics, honor producer pointer width, normalize Windows path aliases, correct access masks and empty identifiers, and serialize FILETIME losslessly for JSON consumers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Describe the record-separator-framed output as an RFC 7464 JSON text sequence rather than NDJSON across the core API and diagnostic example. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Normalize DOS devices, mapped drives, MUP redirectors, and DFS paths to absolute user-visible forms while omitting pipes, relative paths, and unknown device namespaces. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
Document lm_analyze as a developer-only tool and explain why the sealed, policy-oriented learning-mode decoder does not directly reuse the diagnostic console's real-time display consumer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dfea4d42-e8a5-42ef-978a-6434e8bf89ec
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
This was referenced Jul 30, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Adds cross-platform denial primitives and Windows sealed-ETL analysis for Learning Mode captures.
Changes:
- Adds denial models, summaries, framing, and emission.
- Implements bounded ETL decoding, extraction, normalization, and deduplication.
- Adds the Windows-only
lm_analyzediagnostic.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/core/learning_mode_core/src/summary.rs |
Defines capture summaries. |
src/core/learning_mode_core/src/model.rs |
Defines denial wire models. |
src/core/learning_mode_core/src/lib.rs |
Exposes the core API. |
src/core/learning_mode_core/src/frame.rs |
Defines framed records. |
src/core/learning_mode_core/src/emit.rs |
Emits RFC 7464 streams. |
src/core/learning_mode_core/src/analyze.rs |
Defines analyzer abstractions. |
src/core/learning_mode_core/Cargo.toml |
Configures the new crate. |
src/Cargo.toml |
Registers the workspace crate. |
src/Cargo.lock |
Records dependency changes. |
src/backends/learning_mode/windows/src/tdh_decode.rs |
Decodes TDH properties. |
src/backends/learning_mode/windows/src/path_norm.rs |
Normalizes Windows paths. |
src/backends/learning_mode/windows/src/lib.rs |
Exports analyzer APIs. |
src/backends/learning_mode/windows/src/extractors.rs |
Extracts typed denials. |
src/backends/learning_mode/windows/src/etl_decode.rs |
Processes sealed ETL files. |
src/backends/learning_mode/windows/examples/lm_analyze.rs |
Adds the diagnostic CLI. |
src/backends/learning_mode/windows/Cargo.toml |
Adds the core dependency. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3a8860a9-bb20-48ef-91a1-3da8e34b92fb
Contributor
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
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.
📖 Description
Replacement for #699, which was mistakenly marked merged when the stacked parent branch temporarily received child-stack history during a stack-handling mistake. This PR restores the intended review boundary on top of repaired Integration PR #696.
Adds the denial-analysis layer on top of #696:
learning_mode_coredenial model, summary, analysis, framing, and emission primitives.lm_analyzeas a developer-only trace diagnostic.This PR is intentionally stacked on #696 and should merge after it.
🔗 References
🔍 Validation
cargo test -p learning_mode_corecargo test -p learning_mode_windows --all-targetscargo clippy -p learning_mode_core -p learning_mode_windows --all-targets -- -D warnings✅ Checklist
Cargo.lock, thedependency-feed-checkcheck passes (see docs/pull-requests.md)📋 Issue Type
GitHub Actions runs the PR validation build automatically. The ADO pipeline
(
MXC-PR-Build) is the Azure version of the PR pipeline, kept in parity with the GitHubActions build; it runs on merge to
main, and Microsoft reviewers with write access can trigger iton a PR with
/azp run. See docs/pull-requests.md.Microsoft Reviewers: Open in CodeFlow