dshbase

Plugin directory / Security / topolyte-windows-acl

topolyte-windows-acl

Verified · install-tested on dsh Ranecc

✓ Actively maintained 2 contributors Builds on 6 official DSH packages

View on GitHub ↗ ← Back to plugin directory

0Stars
0Forks
0Open issues
—Language
2026-08-19Last push
Cross-platformPlatform

What it does

Windows ACL write-restriction sandbox provider for DeepSeek Harness with non-blocking workspace-grant materialization.

✅
Our take
Works — verified, early-stage project

Windows ACL write-restriction sandbox provider for DeepSeek Harness with non-blocking workspace-grant materialization. It installs cleanly and boots without issues in our testing. It's early-stage but functional.

“Verified” means our automated CI actually ran dsh plugin add in a clean profile and it booted — nothing more. Feature descriptions and version compatibility are the author’s claims. This is not a security audit and not an endorsement of third-party code.

README

@topolyte/windows-acl

Windows ACL write-restriction sandbox provider for DeepSeek Harness
with non-blocking workspace-grant materialization.

The official windows-acl backend materializes a workspace's standing write ACE
synchronously inside confine(): on a large workspace the eager
inheritable-ACE propagation (SetNamedSecurityInfoW) walks the whole tree for
minutes on the Node event loop, freezing the entire server (all sessions,
HTTP, RPC) on first use. This package fixes that — the tree walk runs in a
grant-cli child process, fire-and-forget, so the first provision never
freezes a command spawn.

Installs on the official harness as a ctx.sandbox replacement via the
Cordis bundle-patch mechanism — no fork required. The provider is
Windows-only by construction; on Linux/macOS the bundle patch leaves the
official platform-neutral sandbox chain (bwrap/landlock/seatbelt) untouched and
this provider's row is inserted disabled — install is a safe no-op there, so
the same one-liner works on every platform.

What it does

  • Non-blocking authorization — the workspace's standing write ACE is
    materialized out-of-band by a grant-cli child process (spawn, not
    spawnSync); concurrent first-time calls for one workspace coalesce onto a
    single helper spawn, and workspace roots are canonicalized
    (realpathSync.native, per the official workspaceWriteSid contract) so
    every spelling of one directory shares one in-flight grant, one SID, and one
    failure counter.
  • Fail-closed, no early child starts — a workspace-write command is not
    started until its grant is confirmed: while the grant
    is preparing or failed, confine() refuses with SandboxUnavailableError
    (never a freeze, never a silent half-authorized run); once it stands, the
    exact-ACE skip makes every later provision O(1).
  • Standing / revocable lifecycle preserved — the workspace ACE is the
    cross-session reuse cache (never revoked); each session/workspace pair gets a
    random private temp directory with its own capability SID, revoked on
    provider dispose.
  • prewarm config — start the walk at boot for known workspaces, shrinking
    the fail-closed window before the first command.
  • Bounded retry — a per-workspace consecutive-failure counter
    (maxGrantRetries, default 3): past the cap the workspace is pinned to
    failed and automatic retries stop (fail-closed, never a freeze); an
    operator or agent resets it with retryWorkspaceGrant.
  • Explicit grant state — workspaceGrantState(root) reports
    preparing / ready / failed, so agents/executors can distinguish states
    instead of guessing.
  • Settle-aware shutdown — provider dispose waits for every in-flight
    grant-cli helper to settle before revoking temp ACEs, so a helper still
    walking the tree is never orphaned or revoked mid-flight.
  • Built on the official @deepseek-ai/dsh-sandbox-windows-acl primitives
    (AclWriteGrant, workspaceWriteSid, tempWriteSid) and the official
    SandboxProvider base class — the full official sandbox semantics are
    inherited.

Install

From the npm registry (after npm publish — the same one-liner as any plugin):

dsh plugin --profile <name> add @topolyte/windows-acl

First install on a fresh profile: pnpm 11 blocks koffi's postinstall
build script by default (ERR_PNPM_IGNORED_BUILDS: Ignored build scripts: koffi@3.1.5). Allow it once in the profile's pnpm-workspace.yaml:

allowBuilds:
  koffi: true

This is pnpm 11's universal behavior for native-module dependencies — the
upstream windows-acl backend requires the same approval.

From a GitHub release tarball (no registry needed — download the .tgz
attached to the release):

dsh plugin --profile <name> add topolyte-windows-acl-0.2.0.tgz

From a local checkout:

dsh plugin --profile <name> add /path/to/@topolyte/windows-acl

The bundle's cordis.patch.yml disables the official @deepseek-ai/dsh-sandbox-local
row and inserts this provider under its own id (topolyte-sandbox) — both
actions gated on process.platform === 'win32' — so on Windows it becomes the
only live ctx.sandbox service, while on Linux/macOS the official row stays
live and this row is inserted disabled (never selected as ctx.sandbox).
Configure the workspaces to pre-warm at boot:

- insert:
    - id: sandbox
      name: '@topolyte/windows-acl'
      config:
        prewarm:
          - C:/path/to/your/workspace

How it works

tool-pwsh / tool-bash
  └─ confine() ──► TopolyteWindowsAclProvider (extends SandboxProvider)
       ├─ kickOffWorkspaceGrant(root)      spawn grant-cli child (never awaited)
       │     └─ grant-cli: AclWriteGrant.add(root, standing)  ← full-tree walk HERE
       ├─ workspaceGrantState(root)        preparing / ready / failed
       │     └─ not ready → SandboxUnavailableError (command not started)
       └─ runner argv: --workspace --temp --mode --write-sid --temp-write-sid

The expensive grantWrite → SetNamedSecurityInfoW eager inheritance walk runs
in the grant-cli child process, so the harness event loop never blocks.

Grant lifecycle (preparing / ready / failed)

The out-of-process design is a state-machine change (per the community repair
invariants in the DeepSeek Harness Handbook):
no child may run before the grant is confirmed. Each workspace root moves
through three explicit states, exposed via workspaceGrantState(root):

stateDiagram-v2
    [*] --> preparing: kickOffWorkspaceGrant (grant-cli child spawned)
    preparing --> ready: helper exit 0 → standing ACE stands
    preparing --> failed: helper exit 127 × maxGrantRetries
    failed --> preparing: retryWorkspaceGrant() resets the counter
    ready --> ready: exact-ACE skip (O(1) per command)
    ready --> [*]: provider dispose (standing ACE stays; temp ACEs revoked)
  • preparing — the grant is walking in the background (minutes on a large
    tree); confine() refuses to start the command with SandboxUnavailableError.
    Agents either retry, await ensureWorkspaceGrant(root), or rely on a
    prewarmed workspace that was started at boot.
  • ready — the standing ACE is confirmed; every later provision hits the
    exact-ACE skip and is O(1).
  • failed — maxGrantRetries consecutive grant failures (default 3) pin the
    workspace here: automatic retries stop and commands stay refused until an
    operator or agent calls retryWorkspaceGrant(root).

Measured impact

First vs subsequent workspace provision latency

Scaling curve and event-loop responsiveness

Measured on synthetic trees (1k–30k files, rounds=7, first-add measured on 3
independent dirs per scale; scripts/bench-acl-deep.ts, raw report
docs/bench-acl-deep.json). To cross-validate on a real monorepo (e.g. the
deepseek-harness checkout itself), run
pnpm exec node --import tsx/esm scripts/bench-acl-deep.ts --real <path> --report docs/bench-acl-deep-real.json
— note it writes a standing write ACE (never revoked) to that directory.

Files Sync first median (server freeze) First min/max Subsequent median (skip) Async stall max / p50 Confirm cold (fail-closed window) Confirm prewarmed
1,000 202.2ms 196.1/245.3 0.8ms 86.5/15.7ms 597.7ms 342.1ms
5,000 1,173.2ms 974.7/1,237.0 1.0ms 79.1/15.5ms 1,641.1ms 325.3ms
10,000 1,931.8ms 1,862.4/2,470.9 0.7ms 70.9/15.5ms 3,027.8ms 358.8ms
20,000 5,015.3ms 4,511.1/5,314.1 0.8ms 74.8/15.6ms 6,223.8ms 356.7ms
30,000 7,574.6ms 7,241.8/8,072.1 0.6ms 117.6/15.6ms 8,919.4ms 345.1ms
  • The sync first provision follows a power law t = 0.133·n^1.06 (R² = 0.995)
    — statistically ~O(file count) — and is a whole-server freeze: a 5ms
    setInterval fires ZERO times for the duration.
  • Every later provision is flat at 0.6–1.0ms median (exact-ACE skip),
    tree-size independent — the gap a user feels grows from ~250x at 1k files to
    ~12,600x at 30k. Honest caveat: the skip is not strict O(1) — roughly 1 in
    10–20 later provisions falls back to the full-tree merge path (the
    hasExactGrant implausible-ACL guard) and takes ~the first-add wall clock
    again. On the official sync path that tail is a server freeze on the event
    loop; with this package it happens inside the grant-cli child, so the
    server's responsiveness is unaffected either way.
  • With this package the same first-tree walk runs in the grant-cli child; the
    server's largest event-loop gap is ~70–120ms (child-spawn cold start, p50
    flat at ~15ms) and does not grow with tree size.
  • Fail-closed confirm window: while the grant is preparing, confine()
    refuses the command (SandboxUnavailableError). That refusal lasts
    confirm cold — child spawn + full-tree propagation (0.6s at 1k → 8.9s at
    30k), all off the event loop. A prewarmed workspace (standing ACE already
    landed) cuts it to confirm prewarmed, a flat ~325–360ms of Node/tsx cold
    start with the tree walk skipped — tree-size independent.

Why (the mechanism behind the numbers)

  • grant.add(root, true) calls SetNamedSecurityInfoW with OI|CI inheritance.
    The kernel eagerly re-applies the inheritable ACE to every live
    descendant
    — one synchronous call, linear in file count, on the event
    loop. That is the freeze.
  • The exact-root-ACE skip (hasExactGrant) is not an optimization but a guard:
    re-applying the identical ACE would re-trigger the same O(n) walk. When the
    guard misses it re-walks (see the long-tail caveat above).
  • Moving the walk into the grant-cli child (spawn, not spawnSync) keeps
    that O(n) cost off the event loop; the main thread only pays the spawn
    syscall (~70–120ms, p50 ~15ms), regardless of tree size.

Test

# unit tests
pnpm --filter @topolyte/windows-acl exec vitest run

# real end-to-end (ACL semantics via icacls; spawns real grant-cli + runner)
pnpm --filter @topolyte/windows-acl exec node --import tsx/esm scripts/e2e-acl.ts

Why not a fork / PR

The upstream maintainers are aware of the ACL cost (see the "eager inheritance;
minutes on large workspaces" note in the official acl.ts) but do not accept
PRs. This package ships the same fix as an independent, installable plugin so
any official-harness user gets the non-blocking behavior without maintaining a
fork.

Third-party notices

This package builds on, and in no way modifies, the following upstream projects
(their licenses apply to the linked sources, not to this package's own code):

  • DeepSeek Harness (MIT) —
    SandboxProvider base class and the dsh plugin/bundle runtime this plugin
    plugs into (@deepseek-ai/dsh-sandbox, @deepseek-ai/dsh-sandbox-windows-acl,
    @deepseek-ai/dsh-sandbox-local).
  • Cordis (MIT) — the plugin/bundle
    container (ctx, plugin, bundle-patch layers).
  • koffi (MIT) — the FFI layer used by the
    upstream windows-acl backend for SetNamedSecurityInfoW; not a direct
    dependency here but transitively exercised by the ACL primitives we reuse.
  • Win32 API SetNamedSecurityInfoW
    — Microsoft docs reference for the inherited-ACE propagation semantics this
    fix avoids.

All reuse is via the official packages' published public APIs and type
declarations; no upstream source is vendored or copied into this repository.

Contributing

Contributions are welcome but should stay within the package's narrow scope:
non-blocking Windows ACL sandboxing for DeepSeek Harness. Before opening a PR,
please:

  1. Keep every change on a real code path — no empty skeletons, no
    not-implemented stubs, no hardcoded values.
  2. Preserve the fail-closed invariant: a missing standing ACE must deny, never
    freeze, and never silently widen the grant.
  3. Add or update tests: unit tests (vitest run) and, for ACL semantics, the
    real end-to-end script (scripts/e2e-acl.ts, Win32-only, asserts via
    icacls).
  4. Verify with pnpm --filter @topolyte/windows-acl exec vitest run before
    submitting.

Report bugs and upstream concerns via GitHub issues rather than forks; this
package deliberately avoids forking the official harness.

License

MIT

Install

🧩 Let your agent install it (recommended)

Install the catalog once, then DeepSeek Harness can find and install any plugin from this site automatically:

dsh plugin add dshbase-catalog

Then say "install topolyte-windows-acl for me" — your agent finds it in the directory and installs it. Docs: dshbase-catalog · verified packs.

This plugin is GitHub source (not published to npm) — install it straight from the repo:

Web profile:

dsh plugin --profile web add github:Ranecc/topolyte-windows-acl

Headless (CLI) profile:

dsh plugin --profile headless add github:Ranecc/topolyte-windows-acl

Test report

Verified: L1 install + L2 load + L3 runtime from GitHub source on dsh 0.1.0-rc.6.

Security: not yet scanned — our daily static scan will cover it shortly.

Share this badge

More in Security

Browse all 7819 plugins →