Skip to content

Add denial channel: cross-platform captureDenials transport#558

Open
richiemsft wants to merge 2 commits into
mainfrom
pr1-denial-channel
Open

Add denial channel: cross-platform captureDenials transport#558
richiemsft wants to merge 2 commits into
mainfrom
pr1-denial-channel

Conversation

@richiemsft

@richiemsft richiemsft commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Introduces the denial_channel core crate (DeniedResource/ResourceType/AccessType wire types + serde format) and the SDK denial-channel surface (NDJSON stream parser, named-pipe side-channel transport) with unit tests. This is the shared transport contract consumed by the learning-mode orchestrator and Windows capture runners in later PRs.

📖 Description

First in a stacked series that lands the captureDenials feature.
This PR adds the cross-platform wire contract and transport for access-denial events, with no OS-specific capture logic and no consumers yet (those arrive in later PRs).

Rust — new denial_channel core crate:

  • DeniedResource / ResourceType / AccessType data shapes plus the serde (camelCase) wire format shared by the native binaries and the SDK parser.
  • No OS dependencies; later per-OS learning-mode backend crates depend on this one.
  • Wired into the workspace (Cargo.toml member + [workspace.dependencies] entry).

SDK — new denial-channel surface:

  • stream.ts — NDJSON stream parser (0x1E record-separator framing), default noise filters, path normalisation, and the DeniedResource / summary types mirroring the Rust shapes field-for-field.
  • transports/named-pipe.ts — side-channel transport (named-pipe server) used when the workload owns the PTY and the denial stream needs its own channel.
  • Exported from the package root; two unit-test files added to test:unit.

Scope / limitations: Filesystem/registry denials only; the union is designed so a future network variant is additive. The crate and SDK surface are self-contained — nothing invokes capture yet, so this PR has no runtime effect on its own.

🔗 References

🔍 Validation

  • cargo fmt --all -- --check — clean
  • cargo clippy --workspace --all-targets -- -D warnings — clean
  • cargo test -p denial_channel — 5/5 pass (serde round-trip + per-variant
    wire-format assertions)
  • cargo test --workspace — green
  • SDK npm run build (tsc) — clean
  • SDK npm run test:unit — 203 pass / 0 fail / 4 skip, including the new
    denial-stream and denial-side-channel suites

✅ Checklist

📋 Issue Type

  • Bug fix
  • Feature
  • Task

GitHub Actions runs the PR validation build automatically. The ADO pipeline
(MXC-PR-Build) is the official build pipeline that signs the binaries; it
runs on merge to main and nightly, and Microsoft reviewers can trigger it
on a PR with /azp run. See docs/pull-requests.md.

Microsoft Reviewers: Open in CodeFlow

Introduces the denial_channel core crate (DeniedResource/ResourceType/AccessType wire types + serde format) and the SDK denial-channel surface (NDJSON stream parser, named-pipe side-channel transport) with unit tests. This is the shared transport contract consumed by the learning-mode orchestrator and Windows capture runners in later PRs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 24, 2026 18:25
@richiemsft richiemsft requested a review from a team as a code owner June 24, 2026 18:25
@richiemsft

Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@richiemsft richiemsft changed the title Add denial channel: cross-platform captureDenials transport (Box 1) Add denial channel: cross-platform captureDenials transport Jun 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the first “denial channel” building block for captureDenials: a new Rust core crate defining the cross-platform denial event wire model, plus a TypeScript SDK surface for consuming the denial NDJSON stream and (on Windows) receiving it via a named-pipe side channel.

Changes:

  • Introduces src/core/denial_channel with DeniedResource / ResourceType / AccessType serde wire format and unit tests.
  • Adds SDK denial-channel parsing (parseDenialStream, filters, path normalization) and Windows named-pipe transport (createDenialPipeServer) with unit tests.
  • Wires the new crate into the Rust workspace and adds the new SDK unit tests to npm run test:unit.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/core/denial_channel/src/model.rs Defines Rust denial wire model types + serde format and unit tests.
src/core/denial_channel/src/lib.rs Crate docs and re-exports for the denial model types.
src/core/denial_channel/Cargo.toml New crate manifest and dependencies.
src/Cargo.toml Adds denial_channel to workspace members and workspace deps.
src/Cargo.lock Records the new workspace package entry.
sdk/src/denial-channel/stream.ts Implements the NDJSON/0x1E demux + typed parsing + default filters.
sdk/src/denial-channel/transports/named-pipe.ts Implements Windows named-pipe side-channel server transport.
sdk/src/denial-channel/index.ts Re-export barrel for denial-channel submodule.
sdk/src/index.ts Exposes denial-channel APIs from the SDK package root.
sdk/tests/unit/denial-stream.test.ts Unit tests for parsing/demuxing/filter behavior and forward-compat fields.
sdk/tests/unit/denial-side-channel.test.ts Unit tests for named-pipe server behavior (Windows + non-Windows error).
sdk/package.json Adds the new unit tests to the test:unit script.

Comment thread sdk/src/denial-channel/stream.ts
Comment thread sdk/src/denial-channel/stream.ts
Comment thread sdk/src/denial-channel/stream.ts Outdated
Comment thread sdk/src/denial-channel/stream.ts
Comment thread sdk/src/denial-channel/transports/named-pipe.ts
Comment thread src/core/denial_channel/Cargo.toml
Comment thread src/core/denial_channel/src/model.rs
Comment thread sdk/src/denial-channel/stream.ts
- filetime: serialize as a decimal string on the wire and surface as bigint in the SDK, so 64-bit FILETIME values round-trip without JS number precision loss.
- denial stream parser: coerce incoming chunks to Buffer so streams with an encoding set (string chunks) still demux correctly.
- named-pipe transport: reject denialStream when close() is called before a client connects, so awaiters observe shutdown instead of hanging.
- denial_channel: move serde_json to dev-dependencies (only used in tests).
- docs: describe the SDK DeniedResource as an ergonomic superset of the wire model rather than a field-for-field mirror.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bbonaby

bbonaby commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Is this PR related to #552 ? you mention learning mode in the description and that one is adding learning mode for Windows so I'm wondering if these two go together in some way.

@richiemsft

richiemsft commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

@bbonaby

Is this PR related to #552 ? you mention learning mode in the description and that one is adding learning mode for Windows so I'm wondering if these two go together in some way.

They are distant cousins. This PR (and the subsequent ones) are to introduce a new API in MXC that surfaces the denial events so the app can ask the user if they want to allow access to the denied resource. In Windows, both will use the learningMode capability which enables ETW logging on access checks. #552 is about making the logging accessible for the developer while trying to learn which capabilities or paths are needed during MXC onboarding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants