Files
deepseek-harness/packages/sandbox/sandbox-windows-acl/tests/workspace-sid.spec.ts
T
Huanqi Cao 5fea4b7c4b feat(sandbox): derive the windows-acl write SID per workspace, not per session
The per-session random write SID forced a full tree propagation per
session per server lifetime (minutes on large workspaces). The write
SID is now the per-workspace identity derived from the canonical
workspace path (workspaceWriteSid: sha256 -> S-1-4-x-y), stored
nowhere: the workspace-root ACE materializes once per workspace per
machine and every later provision hits the exact-ACE skip.

- workspace ACEs are STANDING (never revoked - the reuse cache); temp
  ACEs stay revocable (disposed with the provider), so an inheritable
  ACE never outlives its session's temp dir on the ambient temp root
- AclSandbox requires the write SID under workspace-write; read-only
  parses/grants nothing; the runner derives the SID itself (the
  --write-sid flag's presence still marks the seam-managed contract)
- the acl-session record drops writeSid (sessionId/workspace/tempDir
  remain): the SID-tamper surface and its validation are gone
- sandbox-local holds two grant maps: standing workspace grants and
  revocable per-session temp grants

Docs (README pair, design note pair, catalogs, type-equiv) and the
acl-session/grant/acl/probe/runner suites updated; workspace-sid.spec
pins the derivation contract.
2026-08-09 10:44:35 +08:00

31 lines
1.3 KiB
TypeScript

/**
* workspaceWriteSid tests: the per-workspace write identity is deterministic
* (the same canonical path always derives the same SID — the property the
* cross-session grant reuse rests on), orphan-shaped, distinct across
* workspaces, and byte-sensitive (the canonical path is the caller's
* contract; an alias spelling derives a second identity, self-healing at
* the cost of one extra tree propagation).
*/
import { describe, expect, it } from 'vitest'
import { workspaceWriteSid } from '../src/index.ts'
describe('workspaceWriteSid', () => {
it('derives a stable orphan-shaped SID per workspace path', () => {
const first = workspaceWriteSid('C:\\Users\\agent\\repo')
const second = workspaceWriteSid('C:\\Users\\agent\\repo')
expect(first).toBe(second)
expect(first).toMatch(/^S-1-4-\d+-\d+$/u)
})
it('derives distinct identities for distinct workspaces', () => {
expect(workspaceWriteSid('C:\\Users\\agent\\repo-a')).not.toBe(workspaceWriteSid('C:\\Users\\agent\\repo-b'))
})
it('is byte-sensitive: the canonical path is the caller\'s contract (an alias spelling derives a second identity)', () => {
expect(workspaceWriteSid('C:\\Repo')).not.toBe(workspaceWriteSid('c:\\repo'))
expect(workspaceWriteSid('C:\\Repo\\')).not.toBe(workspaceWriteSid('C:\\Repo'))
})
})