Skip to content

Windows Named Pipe: verify DACL denies other users, and measure read-path perf for MCP workloads #302

Description

@StefanSteiner

Purpose

Track the Windows-specific verification and tuning that the daemon's move to Named Pipe transport (PR A / feat/daemon-engine-ipc) needs but that cannot be done from a macOS/Linux developer machine or from CI. Recorded now because the functional switch lands without a Windows host, but two follow-ups genuinely require one.

What is already handled (no Windows host needed)

  • Access control is automatic. hyperd creates the pipe with an owner-only DACL by default: hyper/net/NamedPipe.windows.cpp:170-176 branches on the named_pipes_allow_all_users setting (defaults to false), and in that branch builds the SDDL D:P(A;OICI;FRFW;;;<current-user-SID>) at :143. Every instance is re-secured via clone()createNamedPipeHelper, and PIPE_REJECT_REMOTE_CLIENTS is set. No client-side ACL code is required; the only obligation is never to set that opt-out setting.
  • The Rust client is implementedAsyncStream::NamedPipe(NamedPipeClient), SyncStream::NamedPipe(File), and detect_transport_type routing tab.pipe:// and \\.
  • CI exercises it on test (windows-latest) and clippy (windows-latest), so the transport switch is compiled and functionally tested on real Windows before merge.

What needs a real Windows session

1. Confirm the DACL actually denies a second user

CI runs as a single account, so a green Windows test proves the pipe works, not that another local account is refused. Verify on a Windows box:

  • Inspect the live pipe's DACL with Get-Acl or Sysinternals accesschk on \\.\pipe\hyper-<pid> and confirm it matches the predicted owner-only SDDL.
  • From a second user context, attempt to connect and confirm it is denied.

This is verification that the source-level fact holds at runtime — not a code change.

2. Measure and, if needed, tune the Named Pipe read regression

docs/BENCHMARK_GUIDE.md records a measured Windows regression for Named Pipes versus TCP: query.full_scan async −76%, sync −29%, attributed to tokio's NamedPipeClient::poll_read delivering less data per completion-port wake-up. That was measured on 100M-row full scans.

Unknown: whether that regression affects MCP-shaped workloads — connection setup, small query round-trips, moderate result fetches — or only bulk scans. The macOS UDS A/B (recorded in the same guide) showed IPC winning latency and losing only on bulk streaming, saturating around +62%; the Windows read path may behave differently because the mechanism (completion-port wake-ups) is different.

Steps, on Windows:

  • Micro-benchmark TCP vs Named Pipe for MCP-shaped workloads (mirror the macOS methodology: release build, 20+ iterations, median and p95).
  • If the regression is material for those workloads, investigate read-side tuning — read buffer sizing and the poll_read strategy for NamedPipeClient.
  • Note the pinned engine caveat: the macOS IPC figures were taken on an unversioned local hyperd, so any comparison should use the pinned 0.0.26479 engine.

Not blocking

PR A (daemon engine over IPC) can land on its CI evidence. These are follow-ups, not merge gates. Absolute performance is not an MCP requirement, so a modest Windows read regression is acceptable — this issue exists to quantify it and decide whether tuning is warranted, not to hold the transport change.

Provenance

Identified during the IPC transport evaluation and the PR #295 review; both workers were on macOS and explicitly could not verify Windows behaviour (cross-compilation for Windows fails locally on ring's C build). Verified against main after #295/#298/#289 landed.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions