@bo-agent/sandbox-windows-acl 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/lib/.tsbuildinfo +1 -0
  2. package/lib/acl.d.ts +83 -0
  3. package/lib/acl.d.ts.map +1 -0
  4. package/lib/acl.js +255 -0
  5. package/lib/acl.js.map +1 -0
  6. package/lib/errors.d.ts +15 -0
  7. package/lib/errors.d.ts.map +1 -0
  8. package/lib/errors.js +20 -0
  9. package/lib/errors.js.map +1 -0
  10. package/lib/ffi.d.ts +252 -0
  11. package/lib/ffi.d.ts.map +1 -0
  12. package/lib/ffi.js +382 -0
  13. package/lib/ffi.js.map +1 -0
  14. package/lib/grant.d.ts +60 -0
  15. package/lib/grant.d.ts.map +1 -0
  16. package/lib/grant.js +102 -0
  17. package/lib/grant.js.map +1 -0
  18. package/lib/index.d.ts +168 -0
  19. package/lib/index.d.ts.map +1 -0
  20. package/lib/index.js +349 -0
  21. package/lib/index.js.map +1 -0
  22. package/lib/invariant.d.ts +15 -0
  23. package/lib/invariant.d.ts.map +1 -0
  24. package/lib/invariant.js +17 -0
  25. package/lib/invariant.js.map +1 -0
  26. package/lib/path-boundary.d.ts +20 -0
  27. package/lib/path-boundary.d.ts.map +1 -0
  28. package/lib/path-boundary.js +37 -0
  29. package/lib/path-boundary.js.map +1 -0
  30. package/lib/runner.d.ts +47 -0
  31. package/lib/runner.d.ts.map +1 -0
  32. package/lib/runner.js +222 -0
  33. package/lib/runner.js.map +1 -0
  34. package/lib/spawn.d.ts +103 -0
  35. package/lib/spawn.d.ts.map +1 -0
  36. package/lib/spawn.js +307 -0
  37. package/lib/spawn.js.map +1 -0
  38. package/lib/token.d.ts +91 -0
  39. package/lib/token.d.ts.map +1 -0
  40. package/lib/token.js +200 -0
  41. package/lib/token.js.map +1 -0
  42. package/lib/win32-abi.d.ts +178 -0
  43. package/lib/win32-abi.d.ts.map +1 -0
  44. package/lib/win32-abi.js +230 -0
  45. package/lib/win32-abi.js.map +1 -0
  46. package/lib/workspace-sid.d.ts +41 -0
  47. package/lib/workspace-sid.d.ts.map +1 -0
  48. package/lib/workspace-sid.js +52 -0
  49. package/lib/workspace-sid.js.map +1 -0
  50. package/package.json +33 -0
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Windows ABI constants for the ACL-sandbox backend.
3
+ *
4
+ * Every value was verified against the actual MinGW Windows headers on this
5
+ * machine (C:\Strawberry\c\x86_64-w64-mingw32\include\) and cross-checked at
6
+ * runtime by verify/abi-probe.cpp (same numbers; static_asserts passed).
7
+ * Regenerate the probe with:
8
+ * g++ -std=c++20 -municode -O2 -o abi-probe.exe abi-probe.cpp -ladvapi32 && .\abi-probe.exe
9
+ *
10
+ * The port intentionally excludes two pieces of the original POC
11
+ * (github.com/huoyaoyuan/windows-acl-restrict-poc @ 10e4dfb), both verified
12
+ * empirically on Windows 11 build 26200:
13
+ * - S-1-2-1 (console logon SID) in the restricting list: the POC created it
14
+ * via CreateWellKnownSid(WinLocalLogonSid) which fails here with
15
+ * ERROR_INVALID_PARAMETER (87), leaving a garbage SID that makes
16
+ * CreateRestrictedToken fail with ERROR_INVALID_SID (1337); using the
17
+ * correct WinConsoleLogonSid does produce a valid S-1-2-1, but the child
18
+ * then still dies with STATUS_DLL_INIT_FAILED (0xC0000142) whenever
19
+ * CREATE_NO_WINDOW / CREATE_NEW_CONSOLE is used.
20
+ * - Console isolation: under this restriction scheme a hidden console is not
21
+ * attainable, so children share the host console (stdio redirection is
22
+ * pipe-based and unaffected).
23
+ * @module @bo-agent/sandbox-windows-acl/win32-abi
24
+ */
25
+ // ---- winnt.h ---------------------------------------------------------------
26
+ // TOKEN_* access rights (winnt.h lines ~3928)
27
+ /** TOKEN_ASSIGN_PRIMARY: required to create a process with the token (CreateProcessAsUser). */
28
+ export const TOKEN_ASSIGN_PRIMARY = 0x0001;
29
+ /** TOKEN_DUPLICATE: required to duplicate a token (DuplicateTokenEx). */
30
+ export const TOKEN_DUPLICATE = 0x0002;
31
+ /** TOKEN_QUERY: required to read token information (GetTokenInformation). */
32
+ export const TOKEN_QUERY = 0x0008;
33
+ /** TOKEN_ADJUST_DEFAULT: required to change a token's default DACL. */
34
+ export const TOKEN_ADJUST_DEFAULT = 0x0080;
35
+ // SID_AND_ATTRIBUTES.Attributes flags (winnt.h lines ~3446)
36
+ /**
37
+ * SE_GROUP_LOGON_ID: marks a token group SID as the logon SID (compared with
38
+ * `>>> 0` — the flag's high bit makes it negative as a signed 32-bit number).
39
+ */
40
+ export const SE_GROUP_LOGON_ID = 0xC0000000;
41
+ // Generic file access (winnt.h lines ~5893-5913):
42
+ // FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES
43
+ // | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE
44
+ /** STANDARD_RIGHTS_WRITE (== READ_CONTROL): the standard-rights component of generic write access. */
45
+ export const STANDARD_RIGHTS_WRITE = 0x00020000; // == READ_CONTROL
46
+ /** FILE_GENERIC_WRITE: every file-write permission bit plus SYNCHRONIZE. */
47
+ export const FILE_GENERIC_WRITE = 0x00120116;
48
+ /** DELETE: remove or rename the object (winnt.h line ~3009). */
49
+ export const DELETE = 0x00010000;
50
+ /** FILE_DELETE_CHILD: remove or rename a directory's children (winnt.h line ~5907). */
51
+ export const FILE_DELETE_CHILD = 0x0040;
52
+ // The POC granted FILE_GENERIC_WRITE minus READ_CONTROL, which displays as
53
+ // "Write" in Explorer/icacls (windows-acl-restrict-poc.cpp line 16). The
54
+ // sandbox grant adds DELETE and FILE_DELETE_CHILD so confined
55
+ // delete/rename/git operations inside the granted trees pass the token's
56
+ // access check too; Write+DELETE displays as "Modify" in icacls.
57
+ // WRITE_DAC/WRITE_OWNER stay OUT deliberately — granting them would let the
58
+ // child take ownership or rewrite DACLs and escape the allowlist (the
59
+ // security boundary).
60
+ /**
61
+ * GRANT_MASK: FILE_GENERIC_WRITE minus READ_CONTROL plus DELETE and
62
+ * FILE_DELETE_CHILD — the write+delete access mask the capability-SID ACEs grant
63
+ * (displays as "Modify" in Explorer/icacls). WRITE_DAC/WRITE_OWNER are
64
+ * deliberately excluded: they would let the confined child take ownership or
65
+ * rewrite DACLs.
66
+ */
67
+ export const GRANT_MASK = (FILE_GENERIC_WRITE | DELETE | FILE_DELETE_CHILD) & ~STANDARD_RIGHTS_WRITE; // 0x00110156
68
+ /**
69
+ * FILE_ALL_ACCESS (winnt.h line ~2789: STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE
70
+ * | 0x1FF): full file-object access. The mask of the ACE merged into the
71
+ * restricted token's DEFAULT DACL — the token holder must keep full access to
72
+ * every NEW object it creates (pipes included), and the ACE must name a
73
+ * restricting SID so the write pass-2 check passes at creation.
74
+ */
75
+ export const FILE_ALL_ACCESS = 0x1F01FF;
76
+ // CreateRestrictedToken flags (winnt.h lines ~4284)
77
+ /** DISABLE_MAX_PRIVILEGE: strip the token's maximum-privilege elevation so the confined child cannot escalate. */
78
+ export const DISABLE_MAX_PRIVILEGE = 0x1;
79
+ /** LUA_TOKEN: produce a limited-user (filtered admin) token. */
80
+ export const LUA_TOKEN = 0x4;
81
+ /** WRITE_RESTRICTED: intersect write access with the restricting SIDs' ACL grants — the sandbox's core mechanism. */
82
+ export const WRITE_RESTRICTED = 0x8;
83
+ // WELL_KNOWN_SID_TYPE (winnt.h lines ~3369-3407)
84
+ /** WinWorldSid: S-1-1-0 (Everyone) — the only well-known SID the restricted tokens use (keep-alive group; see token.ts). */
85
+ export const WinWorldSid = 1;
86
+ // TOKEN_INFORMATION_CLASS (winnt.h line ~3963: TokenUser=1, TokenGroups=2)
87
+ /** TokenGroups: GetTokenInformation class returning the token's group SIDs. */
88
+ export const TokenGroups = 2;
89
+ /** TokenDefaultDacl: the token's default DACL — the DACL every NEW object created without an explicit SD takes. */
90
+ export const TokenDefaultDacl = 6;
91
+ // SECURITY_INFORMATION (winnt.h line ~4293)
92
+ /** DACL_SECURITY_INFORMATION: read/write only the DACL of a security descriptor. */
93
+ export const DACL_SECURITY_INFORMATION = 0x00000004;
94
+ // PROCESS access rights (winnt.h lines ~4364)
95
+ /** PROCESS_QUERY_INFORMATION: read exit status and times of a process handle. */
96
+ export const PROCESS_QUERY_INFORMATION = 0x0400;
97
+ // ---- accctrl.h -------------------------------------------------------------
98
+ // SE_OBJECT_TYPE (accctrl.h line ~22: SE_UNKNOWN_OBJECT_TYPE=0, SE_FILE_OBJECT=1)
99
+ /** SE_FILE_OBJECT: the trustee path names a filesystem object. */
100
+ export const SE_FILE_OBJECT = 1;
101
+ // TRUSTEE_FORM / TRUSTEE_TYPE (accctrl.h lines ~38-55): both enums start at 0
102
+ /** TRUSTEE_IS_UNKNOWN: TRUSTEE_TYPE unknown (TrusteeForm carries the shape). */
103
+ export const TRUSTEE_IS_UNKNOWN = 0;
104
+ /** TRUSTEE_IS_SID: TRUSTEE_FORM — Trustee.ptstrName is a SID pointer. */
105
+ export const TRUSTEE_IS_SID = 0;
106
+ /** NO_MULTIPLE_TRUSTEE: Trustee.pMultipleTrustee is null. */
107
+ export const NO_MULTIPLE_TRUSTEE = 0;
108
+ // ACCESS_MODE (accctrl.h line ~127: NOT_USED_ACCESS=0, GRANT_ACCESS=1, REVOKE_ACCESS=4)
109
+ /** GRANT_ACCESS: SetEntriesInAclW adds the entry as an allow ACE. */
110
+ export const GRANT_ACCESS = 1;
111
+ /** REVOKE_ACCESS: SetEntriesInAclW removes the matching allow ACE. */
112
+ export const REVOKE_ACCESS = 4;
113
+ // grfInheritance (accctrl.h lines ~137-142)
114
+ /**
115
+ * SUB_CONTAINERS_AND_OBJECTS_INHERIT: the ACE applies to the directory, its
116
+ * subdirectories, and files (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE).
117
+ */
118
+ export const SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3; // == OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE
119
+ // ---- winbase.h -------------------------------------------------------------
120
+ /**
121
+ * STARTF_USESTDHANDLES: STARTUPINFOW dwFlags — the child uses the hStd*
122
+ * handles, required because Node clears stdio inheritability at startup.
123
+ */
124
+ export const STARTF_USESTDHANDLES = 0x00000100;
125
+ /** HANDLE_FLAG_INHERIT: SetHandleInformation flag re-enabling handle inheritance for the spawned child's stdio handles. */
126
+ export const HANDLE_FLAG_INHERIT = 0x1;
127
+ /** INFINITE: never-timeout wait value. */
128
+ export const INFINITE = 0xFFFFFFFF;
129
+ /** MAX_PATH: legacy path length bound. */
130
+ export const MAX_PATH = 260;
131
+ // winbase.h line ~410: the confined child starts suspended so the runner can
132
+ // assign it to the kill-on-close job before any of its code runs.
133
+ /** CREATE_SUSPENDED: create the child with its primary thread suspended until ResumeThread. */
134
+ export const CREATE_SUSPENDED = 0x4;
135
+ // winbase.h lines ~497-499: GetStdHandle selectors.
136
+ /** STD_INPUT_HANDLE: GetStdHandle selector for the standard input. */
137
+ export const STD_INPUT_HANDLE = -10;
138
+ /** STD_OUTPUT_HANDLE: GetStdHandle selector for the standard output. */
139
+ export const STD_OUTPUT_HANDLE = -11;
140
+ /** STD_ERROR_HANDLE: GetStdHandle selector for the standard error. */
141
+ export const STD_ERROR_HANDLE = -12;
142
+ // FormatMessageW flags (winbase.h lines ~1446-1469)
143
+ /** FORMAT_MESSAGE_FROM_SYSTEM: format the message from the system message table. */
144
+ export const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
145
+ /** FORMAT_MESSAGE_IGNORE_INSERTS: skip insert-sequence substitution. */
146
+ export const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
147
+ // ---- error codes -----------------------------------------------------------
148
+ /** ERROR_SUCCESS: the operation succeeded. */
149
+ export const ERROR_SUCCESS = 0;
150
+ /** ERROR_INSUFFICIENT_BUFFER: a size-probe call succeeded but needs a larger buffer. */
151
+ export const ERROR_INSUFFICIENT_BUFFER = 122;
152
+ /** ERROR_BROKEN_PIPE: the pipe's other end has closed. */
153
+ export const ERROR_BROKEN_PIPE = 109;
154
+ /** ERROR_NO_DATA: the pipe is being closed. */
155
+ export const ERROR_NO_DATA = 232;
156
+ /** ERROR_LOCK_VIOLATION: a byte-range lock conflicts with an existing lock (winerror.h line ~78). */
157
+ export const ERROR_LOCK_VIOLATION = 33;
158
+ // ---- lock files (fileapi.h / minwinbase.h / winnt.h) -----------------------
159
+ // CreateFileW dwDesiredAccess for the ACL lock files: plain read+write is
160
+ // enough to take byte-range locks.
161
+ /** GENERIC_READ: generic read access (winnt.h line ~3028). */
162
+ export const GENERIC_READ = 0x80000000;
163
+ /** GENERIC_WRITE: generic write access (winnt.h line ~3029). */
164
+ export const GENERIC_WRITE = 0x40000000;
165
+ // CreateFileW dwShareMode: the lock file is shared for read/write but NOT
166
+ // for delete — if a locked file could be deleted and recreated underneath the
167
+ // lock holder, two processes could hold "the same" lock on different files.
168
+ /** FILE_SHARE_READ: other opens may read (winnt.h line ~5949). */
169
+ export const FILE_SHARE_READ = 0x00000001;
170
+ /** FILE_SHARE_WRITE: other opens may write (winnt.h line ~5950). */
171
+ export const FILE_SHARE_WRITE = 0x00000002;
172
+ /** FILE_SHARE_DELETE: other opens may delete (winnt.h line ~5951) — deliberately NOT used for lock files. */
173
+ export const FILE_SHARE_DELETE = 0x00000004;
174
+ /** OPEN_ALWAYS: create the lock file if absent, open it otherwise (fileapi.h line ~21). */
175
+ export const OPEN_ALWAYS = 4;
176
+ // LockFileEx dwFlags (minwinbase.h lines ~180-181, included by winbase.h).
177
+ /** LOCKFILE_EXCLUSIVE_LOCK: request an exclusive byte-range lock. */
178
+ export const LOCKFILE_EXCLUSIVE_LOCK = 0x2;
179
+ /** LOCKFILE_FAIL_IMMEDIATELY: fail with ERROR_LOCK_VIOLATION instead of waiting. */
180
+ export const LOCKFILE_FAIL_IMMEDIATELY = 0x1;
181
+ // ACE_HEADER.AceType (winnt.h lines ~3449-3463)
182
+ /** ACCESS_ALLOWED_ACE_TYPE: an access-allowed ACE granting the mask to the trustee. */
183
+ export const ACCESS_ALLOWED_ACE_TYPE = 0;
184
+ // SID structure (winnt.h line ~280 SID_IDENTIFIER_AUTHORITY; line ~286
185
+ // #define SID_MAX_SUB_AUTHORITIES 15).
186
+ /** SID_MAX_SUB_AUTHORITIES: the most subauthorities a SID may carry. */
187
+ export const SID_MAX_SUB_AUTHORITIES = 15;
188
+ // ACE_HEADER.AceFlags (winnt.h lines ~3477-3524): inherited ACEs shown when
189
+ // reading a DACL are marked with this bit and are not part of the explicit
190
+ // DACL edits this module makes.
191
+ /** INHERITED_ACE: the ACE was inherited from the parent object, not stored explicitly. */
192
+ export const INHERITED_ACE = 0x10;
193
+ // ---- job object (winnt.h lines ~4859-4866, ~5138, ~5190-5199) --------------
194
+ // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: the child dies when the runner's last
195
+ // job handle closes — the orphan-child backstop for the runner design.
196
+ /** JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: the child dies when the runner's last job handle closes — the orphan-child backstop. */
197
+ export const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000;
198
+ // JOBOBJECTINFOCLASS: JobObjectBasicAccountingInformation=1, ..., ExtendedLimit=9.
199
+ /** JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS for the extended limit structure. */
200
+ export const JobObjectExtendedLimitInformation = 9;
201
+ // sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION), verified by abi-probe.
202
+ /** sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION), verified by abi-probe. */
203
+ export const JOBOBJECT_EXTENDED_LIMIT_SIZE = 144;
204
+ // LimitFlags offset inside JOBOBJECT_EXTENDED_LIMIT_INFORMATION
205
+ // (BasicLimitInformation@0 + PerProcessUserTimeLimit@0 + PerJobUserTimeLimit@8),
206
+ // verified by abi-probe.
207
+ /**
208
+ * LimitFlags offset inside JOBOBJECT_EXTENDED_LIMIT_INFORMATION
209
+ * (BasicLimitInformation@0 + PerProcessUserTimeLimit@0 +
210
+ * PerJobUserTimeLimit@8), verified by abi-probe.
211
+ */
212
+ export const JOBOBJECT_EXTENDED_LIMIT_FLAGS_OFFSET = 16;
213
+ // ---- ABI layout, verified by verify/abi-probe.cpp (x64) --------------------
214
+ /** SECURITY_MAX_SID_SIZE: maximum SID byte size. */
215
+ export const SECURITY_MAX_SID_SIZE = 68;
216
+ /** SID_AND_ATTRIBUTES stride: { PSID Sid @0 (8); DWORD Attributes @8 (4) } + pad. */
217
+ export const SID_AND_ATTRIBUTES_SIZE = 16;
218
+ /** TOKEN_GROUPS.Groups[] starts at offset 8 (GroupCount @0 + alignment). */
219
+ export const TOKEN_GROUPS_OFFSET = 8;
220
+ /** sizeof(EXPLICIT_ACCESS_W): perms@0 mode@4 inheritance@8 Trustee@16. */
221
+ export const EXPLICIT_ACCESS_W_SIZE = 48;
222
+ /** Trustee offset inside EXPLICIT_ACCESS_W. */
223
+ export const TRUSTEE_W_OFFSET = 16;
224
+ /** ptstrName offset inside TRUSTEE_W (=> 40 inside EXPLICIT_ACCESS_W). */
225
+ export const TRUSTEE_W_PTSTRNAME_OFFSET = 24;
226
+ /** sizeof(STARTUPINFOW), verified by abi-probe. */
227
+ export const STARTUPINFOW_SIZE = 104;
228
+ /** sizeof(PROCESS_INFORMATION), verified by abi-probe. */
229
+ export const PROCESS_INFORMATION_SIZE = 24;
230
+ //# sourceMappingURL=win32-abi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"win32-abi.js","sourceRoot":"","sources":["../src/win32-abi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The per-workspace write identity: a deterministic `S-1-4-x-y` SID derived
3
+ * from the canonical workspace path, whose ACEs form that workspace's write
4
+ * allowlist. Every confined execution of the same workspace — across
5
+ * sessions, server restarts, and calls — carries the SAME write SID, so the
6
+ * workspace-root ACE materializes once per workspace per machine (the
7
+ * grant's exact-ACE skip then makes every later provision O(1)) instead of
8
+ * once per session. The SID's power is defined solely by the ACEs that name
9
+ * it (which exist only on the workspace tree and the session's private temp
10
+ * directory), and only tokens minted for that workspace carry it — the SID
11
+ * string itself is not a secret. Temporary directories use a separate,
12
+ * per-directory identity from {@link tempWriteSid}; sharing the workspace
13
+ * identity with temp would let sibling sessions write one another's temp
14
+ * trees.
15
+ *
16
+ * The input MUST be the canonical workspace path (`realpathSync.native` on
17
+ * Windows — the sandbox-policy `resolveWorkspaceRoot` already applies it):
18
+ * canonicalization converges case/alias spellings, so two spellings of one
19
+ * workspace derive one SID; an as-spelled fallback path would mint a second
20
+ * identity for the same directory (self-healing, at the cost of one extra
21
+ * tree propagation). Renaming the workspace directory derives a new SID —
22
+ * the old standing ACEs are inert residue, and the next session re-propagates
23
+ * once.
24
+ * @module @bo-agent/sandbox-windows-acl/workspace-sid
25
+ */
26
+ /**
27
+ * Derive the workspace's write SID (`S-1-4-x-y`; subauthorities 30-bit,
28
+ * matching the workspace-capability shape the token and ACE layers carry).
29
+ * @param workspaceRoot - the canonical workspace path.
30
+ * @returns the SDDL string form.
31
+ */
32
+ export declare function workspaceWriteSid(workspaceRoot: string): string;
33
+ /**
34
+ * Derive one private temp directory's write SID. The random directory path
35
+ * is the capability identity; a fixed third subauthority domain-separates
36
+ * the result from every two-subauthority workspace SID.
37
+ * @param tempDir - the private temp directory's absolute path.
38
+ * @returns the SDDL string form.
39
+ */
40
+ export declare function tempWriteSid(tempDir: string): string;
41
+ //# sourceMappingURL=workspace-sid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-sid.d.ts","sourceRoot":"","sources":["../src/workspace-sid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAK/D;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKpD"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The per-workspace write identity: a deterministic `S-1-4-x-y` SID derived
3
+ * from the canonical workspace path, whose ACEs form that workspace's write
4
+ * allowlist. Every confined execution of the same workspace — across
5
+ * sessions, server restarts, and calls — carries the SAME write SID, so the
6
+ * workspace-root ACE materializes once per workspace per machine (the
7
+ * grant's exact-ACE skip then makes every later provision O(1)) instead of
8
+ * once per session. The SID's power is defined solely by the ACEs that name
9
+ * it (which exist only on the workspace tree and the session's private temp
10
+ * directory), and only tokens minted for that workspace carry it — the SID
11
+ * string itself is not a secret. Temporary directories use a separate,
12
+ * per-directory identity from {@link tempWriteSid}; sharing the workspace
13
+ * identity with temp would let sibling sessions write one another's temp
14
+ * trees.
15
+ *
16
+ * The input MUST be the canonical workspace path (`realpathSync.native` on
17
+ * Windows — the sandbox-policy `resolveWorkspaceRoot` already applies it):
18
+ * canonicalization converges case/alias spellings, so two spellings of one
19
+ * workspace derive one SID; an as-spelled fallback path would mint a second
20
+ * identity for the same directory (self-healing, at the cost of one extra
21
+ * tree propagation). Renaming the workspace directory derives a new SID —
22
+ * the old standing ACEs are inert residue, and the next session re-propagates
23
+ * once.
24
+ * @module @bo-agent/sandbox-windows-acl/workspace-sid
25
+ */
26
+ import { createHash } from 'node:crypto';
27
+ /**
28
+ * Derive the workspace's write SID (`S-1-4-x-y`; subauthorities 30-bit,
29
+ * matching the workspace-capability shape the token and ACE layers carry).
30
+ * @param workspaceRoot - the canonical workspace path.
31
+ * @returns the SDDL string form.
32
+ */
33
+ export function workspaceWriteSid(workspaceRoot) {
34
+ const digest = createHash('sha256').update(workspaceRoot, 'utf8').digest();
35
+ const first = (digest.readUInt32LE(0) % (2 ** 30 - 1)) + 1;
36
+ const second = (digest.readUInt32LE(4) % (2 ** 30 - 1)) + 1;
37
+ return `S-1-4-${first}-${second}`;
38
+ }
39
+ /**
40
+ * Derive one private temp directory's write SID. The random directory path
41
+ * is the capability identity; a fixed third subauthority domain-separates
42
+ * the result from every two-subauthority workspace SID.
43
+ * @param tempDir - the private temp directory's absolute path.
44
+ * @returns the SDDL string form.
45
+ */
46
+ export function tempWriteSid(tempDir) {
47
+ const digest = createHash('sha256').update('temp\0', 'utf8').update(tempDir, 'utf8').digest();
48
+ const first = (digest.readUInt32LE(0) % (2 ** 30 - 1)) + 1;
49
+ const second = (digest.readUInt32LE(4) % (2 ** 30 - 1)) + 1;
50
+ return `S-1-4-${first}-${second}-1`;
51
+ }
52
+ //# sourceMappingURL=workspace-sid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-sid.js","sourceRoot":"","sources":["../src/workspace-sid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAqB;IACrD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;IAC1E,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC3D,OAAO,SAAS,KAAK,IAAI,MAAM,EAAE,CAAA;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;IAC7F,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC3D,OAAO,SAAS,KAAK,IAAI,MAAM,IAAI,CAAA;AACrC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@bo-agent/sandbox-windows-acl",
3
+ "description": "Windows ACL write-restriction sandbox backend (restricted-token spawn with capability-SID write allowlist) for the standalone sandbox product",
4
+ "version": "0.0.1",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "types": "lib/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/index.d.ts",
11
+ "default": "./lib/index.js"
12
+ },
13
+ "./runner": {
14
+ "types": "./lib/runner.d.ts",
15
+ "default": "./lib/runner.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "files": [
20
+ "lib/"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "cordis": "^4.0.0-rc.10",
28
+ "koffi": "^3.1.0"
29
+ },
30
+ "peerDependencies": {
31
+ "cordis": "^4.0.0-rc.10"
32
+ }
33
+ }