@sysid/sandbox-runtime-improved 0.0.61-sysid.1 → 0.0.64-sysid.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.
- package/README.md +76 -15
- package/dist/cli.js +12 -18
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/sandbox/credential-mask-files.d.ts +100 -15
- package/dist/sandbox/credential-mask-files.d.ts.map +1 -1
- package/dist/sandbox/credential-mask-files.js +172 -20
- package/dist/sandbox/credential-mask-files.js.map +1 -1
- package/dist/sandbox/http-proxy.d.ts +1 -1
- package/dist/sandbox/http-proxy.d.ts.map +1 -1
- package/dist/sandbox/http-proxy.js +20 -0
- package/dist/sandbox/http-proxy.js.map +1 -1
- package/dist/sandbox/linux-sandbox-utils.d.ts +5 -0
- package/dist/sandbox/linux-sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/linux-sandbox-utils.js +29 -19
- package/dist/sandbox/linux-sandbox-utils.js.map +1 -1
- package/dist/sandbox/linux-violation-monitor.d.ts +48 -0
- package/dist/sandbox/linux-violation-monitor.d.ts.map +1 -0
- package/dist/sandbox/linux-violation-monitor.js +156 -0
- package/dist/sandbox/linux-violation-monitor.js.map +1 -0
- package/dist/sandbox/macos-sandbox-utils.js +3 -3
- package/dist/sandbox/macos-sandbox-utils.js.map +1 -1
- package/dist/sandbox/mitm-ca.d.ts +52 -1
- package/dist/sandbox/mitm-ca.d.ts.map +1 -1
- package/dist/sandbox/mitm-ca.js +143 -11
- package/dist/sandbox/mitm-ca.js.map +1 -1
- package/dist/sandbox/mitm-leaf.d.ts +1 -1
- package/dist/sandbox/mitm-leaf.d.ts.map +1 -1
- package/dist/sandbox/mitm-leaf.js +21 -32
- package/dist/sandbox/mitm-leaf.js.map +1 -1
- package/dist/sandbox/sandbox-config.d.ts +231 -40
- package/dist/sandbox/sandbox-config.d.ts.map +1 -1
- package/dist/sandbox/sandbox-config.js +161 -32
- package/dist/sandbox/sandbox-config.js.map +1 -1
- package/dist/sandbox/sandbox-manager.d.ts +1 -1
- package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
- package/dist/sandbox/sandbox-manager.js +331 -252
- package/dist/sandbox/sandbox-manager.js.map +1 -1
- package/dist/sandbox/sandbox-utils.d.ts +13 -0
- package/dist/sandbox/sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/sandbox-utils.js +32 -7
- package/dist/sandbox/sandbox-utils.js.map +1 -1
- package/dist/sandbox/windows-sandbox-utils.d.ts +353 -297
- package/dist/sandbox/windows-sandbox-utils.d.ts.map +1 -1
- package/dist/sandbox/windows-sandbox-utils.js +516 -396
- package/dist/sandbox/windows-sandbox-utils.js.map +1 -1
- package/dist/utils/shell-quote.d.ts +27 -0
- package/dist/utils/shell-quote.d.ts.map +1 -0
- package/dist/utils/shell-quote.js +47 -0
- package/dist/utils/shell-quote.js.map +1 -0
- package/package.json +1 -3
- package/vendor/seccomp/arm64/apply-seccomp +0 -0
- package/vendor/seccomp/x64/apply-seccomp +0 -0
|
@@ -1,67 +1,67 @@
|
|
|
1
1
|
export { containsGlobCharsWin, stripExtendedPathPrefix, } from './sandbox-utils.js';
|
|
2
2
|
import type { SandboxDependencyCheck } from './linux-sandbox-utils.js';
|
|
3
|
+
import type { SrtWinConfig } from './sandbox-config.js';
|
|
3
4
|
/**
|
|
4
5
|
* Windows sandbox backend.
|
|
5
6
|
*
|
|
6
7
|
* Network isolation is enforced by `srt-win.exe` — a Rust helper that
|
|
7
|
-
*
|
|
8
|
-
* keyed on that
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* provisions a dedicated `srt-sandbox` local user account, installs a
|
|
9
|
+
* machine-wide WFP filter set keyed on that account's SID, and
|
|
10
|
+
* provides an `exec` subcommand that spawns the target via a two-hop
|
|
11
|
+
* launch (broker → `CreateProcessWithLogonW(runner)` → runner →
|
|
12
|
+
* restricted-token child) under `srt-sandbox`. The sandboxed child
|
|
13
|
+
* reaches the host only via the JS mux proxy, which the caller
|
|
14
|
+
* passes in via `--env`.
|
|
15
|
+
*
|
|
16
|
+
* The separate-user account structurally closes the surrogate-spawn
|
|
17
|
+
* class (schtasks, `PROC_THREAD_ATTRIBUTE_PARENT_PROCESS`, BITS,
|
|
18
|
+
* RunAs="Interactive User" COM): the child's token carries a
|
|
19
|
+
* different user SID, so it cannot reach real-user processes, tasks
|
|
20
|
+
* register under `srt-sandbox`, and the user-SID WFP filter fences
|
|
21
|
+
* `srt-sandbox` egress regardless of how the child was spawned.
|
|
12
22
|
*
|
|
13
23
|
* This module is a thin wrapper around the `srt-win` CLI; all status
|
|
14
|
-
* comes from live enumeration
|
|
15
|
-
* token-membership check; WFP via providerData-tag enumeration under
|
|
16
|
-
* the configured sublayer). There is no marker file.
|
|
24
|
+
* comes from live enumeration. There is no marker file.
|
|
17
25
|
*
|
|
18
|
-
* Filesystem
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* allow-list on its immediate parent directory, with restore state
|
|
22
|
-
* sealed by an inert hash-ACE marker so the on-disk SD is
|
|
23
|
-
* self-authenticating. See {@link stampWindowsAcl}.
|
|
26
|
+
* Filesystem rules (`denyRead`/`denyWrite`/`allowRead`/`allowWrite`)
|
|
27
|
+
* are enforced via additive explicit ACEs for `<sb-SID>` — see
|
|
28
|
+
* {@link grantWindowsAcl} / {@link stampWindowsAcl}.
|
|
24
29
|
*/
|
|
25
|
-
export declare const DEFAULT_WINDOWS_GROUP_NAME = "sandbox-runtime-net";
|
|
26
30
|
export declare const DEFAULT_WINDOWS_PROXY_PORT_RANGE: readonly [number, number];
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* use for domain groups or where name resolution is unreliable.
|
|
34
|
-
*/
|
|
35
|
-
groupSid?: string;
|
|
36
|
-
}
|
|
37
|
-
export type WindowsGroupStatus = 'absent' | 'created-not-on-token' | 'ready';
|
|
38
|
-
export interface WindowsGroupStatusResult {
|
|
39
|
-
state: WindowsGroupStatus;
|
|
40
|
-
sid?: string;
|
|
41
|
-
warning?: string;
|
|
42
|
-
error?: string;
|
|
43
|
-
}
|
|
44
|
-
export type WindowsWfpStatus = 'absent' | 'installed';
|
|
31
|
+
/**
|
|
32
|
+
* `cannot-read` is the graceful-degrade state when BFE enumeration
|
|
33
|
+
* is access-denied (it is admin-gated). The non-elevated readiness
|
|
34
|
+
* check is {@link verifyWindowsWfpEgress}, not this enum.
|
|
35
|
+
*/
|
|
36
|
+
export type WindowsWfpStatus = 'absent' | 'installed' | 'cannot-read';
|
|
45
37
|
export interface WindowsWfpStatusResult {
|
|
46
38
|
state: WindowsWfpStatus;
|
|
39
|
+
/** Live filter count from BFE enum; `0` on `cannot-read`. */
|
|
47
40
|
filters: number;
|
|
48
|
-
/** `[low, high]`
|
|
41
|
+
/** `[low, high]` for the loopback PERMIT, when known. */
|
|
49
42
|
portRange?: [number, number];
|
|
50
|
-
/**
|
|
51
|
-
* Number of user-SID-keyed filters present (subset of `filters`).
|
|
52
|
-
* Zero on installs that predate the sandbox-user provisioning
|
|
53
|
-
* step, or when only `wfp install` (group set) was run.
|
|
54
|
-
*/
|
|
55
|
-
userFilters: number;
|
|
56
43
|
/** Sandbox-user SID read from the first user-keyed filter tag. */
|
|
57
44
|
userSid?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Populated only on `cannot-read` (BFE enumeration is admin-gated;
|
|
47
|
+
* a non-elevated caller can't read it). The non-elevated readiness
|
|
48
|
+
* check is {@link verifyWindowsWfpEgress}, not this enum.
|
|
49
|
+
*/
|
|
50
|
+
hint?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Result of `srt-win wfp verify` on success (exit 0, `blocked`) —
|
|
54
|
+
* see {@link verifyWindowsWfpEgress}. Any other outcome throws, so
|
|
55
|
+
* the tri-state is unobservable on the return path.
|
|
56
|
+
*/
|
|
57
|
+
export interface WindowsWfpVerifyResult {
|
|
58
|
+
target: string;
|
|
59
|
+
/** Runner's stderr (carries the `BLOCKED (…)` diagnostic line). */
|
|
60
|
+
stderr: string;
|
|
58
61
|
}
|
|
59
62
|
/**
|
|
60
63
|
* State of the `srt-sandbox` local account that `srt-win install`
|
|
61
|
-
* provisions. The sandboxed child
|
|
62
|
-
* account; for now it is reported alongside the group/WFP status
|
|
63
|
-
* so callers can surface a "re-run install" diagnostic when the
|
|
64
|
-
* account is missing.
|
|
64
|
+
* provisions. The sandboxed child runs **as** this account.
|
|
65
65
|
*/
|
|
66
66
|
export interface WindowsSandboxUserStatus {
|
|
67
67
|
/** The `srt-sandbox` local account exists. */
|
|
@@ -85,6 +85,12 @@ export interface WindowsSandboxUserStatus {
|
|
|
85
85
|
credPresent: boolean;
|
|
86
86
|
/** Setup marker schema version, when the marker row exists. */
|
|
87
87
|
markerVersion?: number;
|
|
88
|
+
/**
|
|
89
|
+
* The calling (real) user's SID — the broker's identity, surfaced
|
|
90
|
+
* for diagnostics. The DENY-ACE trustee is `srt-sandbox`'s SID
|
|
91
|
+
* ({@link sid}), not this. Always present.
|
|
92
|
+
*/
|
|
93
|
+
realUserSid: string;
|
|
88
94
|
/**
|
|
89
95
|
* SHA-1 thumbprint of the install-time CA, when one was
|
|
90
96
|
* installed via `srt-win user trust-ca`. Uppercase hex.
|
|
@@ -94,18 +100,17 @@ export interface WindowsSandboxUserStatus {
|
|
|
94
100
|
caCertPem?: string;
|
|
95
101
|
}
|
|
96
102
|
/**
|
|
97
|
-
* Inner shell to run `command` under, inside the
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* {@link wrapCommandWithSandboxWindows}.
|
|
103
|
+
* Inner shell to run `command` under, inside the sandbox. The
|
|
104
|
+
* discriminant picks both the executable and the flag shape (`/c`
|
|
105
|
+
* vs `-Command` vs `-c`); see {@link wrapCommandWithSandboxWindows}.
|
|
101
106
|
*
|
|
102
107
|
* For `kind: 'bash'`, `path` is the absolute Git Bash executable
|
|
103
108
|
* (no fixed install location). It MUST originate from trusted host
|
|
104
109
|
* configuration (user settings / install detection), NEVER from
|
|
105
110
|
* workspace or repository content — the inner shell runs INSIDE the
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
111
|
+
* sandbox so an unexpected path is not a sandbox-escape vector, but
|
|
112
|
+
* it would still be an arbitrary-exec footgun if sourced from
|
|
113
|
+
* untrusted input.
|
|
109
114
|
*/
|
|
110
115
|
export type WindowsBinShell = {
|
|
111
116
|
kind: 'cmd';
|
|
@@ -129,94 +134,95 @@ export type WindowsBinShell = {
|
|
|
129
134
|
export declare function parseWindowsBinShell(raw?: string): WindowsBinShell;
|
|
130
135
|
export interface WindowsSandboxParams {
|
|
131
136
|
command: string;
|
|
132
|
-
group: WindowsGroupRef;
|
|
133
137
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* fence). When omitted, srt-win uses its compile-time default
|
|
138
|
-
* GUID — same as `srt-win install` with no `--sublayer-guid`.
|
|
138
|
+
* JS HTTP proxy port — fed to `generateProxyEnvVars` for the env
|
|
139
|
+
* overlay. With the in-process proxy this is the mux front-end
|
|
140
|
+
* port (same as `socksProxyPort`).
|
|
139
141
|
*/
|
|
140
|
-
sublayerGuid?: string;
|
|
141
|
-
/** JS HTTP proxy port — fed to `generateProxyEnvVars` for the returned env. */
|
|
142
142
|
httpProxyPort?: number;
|
|
143
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* JS SOCKS proxy port — fed to `generateProxyEnvVars` for the env
|
|
145
|
+
* overlay. With the in-process proxy this is the mux front-end
|
|
146
|
+
* port (same as `httpProxyPort`).
|
|
147
|
+
*/
|
|
144
148
|
socksProxyPort?: number;
|
|
145
149
|
/** Per-session proxy auth token; embedded in proxy env URLs. */
|
|
146
150
|
proxyAuthToken?: string;
|
|
147
151
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
*
|
|
157
|
-
* (`mode: 'mask'`). Applied BEFORE the proxy assignments for the
|
|
158
|
-
* same precedence reason as {@link unsetEnvVars}.
|
|
152
|
+
* `mode: 'mask'` credential env vars — sentinel values the
|
|
153
|
+
* sandboxed child should see in place of the real credentials.
|
|
154
|
+
* Threaded through the `--env` overlay so the runner forwards
|
|
155
|
+
* them into the child's fresh profile env (the broker's own
|
|
156
|
+
* environment never reaches the child, so an `env -u`-style
|
|
157
|
+
* scrub is structurally moot — there is no `unsetEnvVars`).
|
|
158
|
+
* Applied BEFORE the proxy assignments so the sandbox's own
|
|
159
|
+
* proxy plumbing survives even if a caller masks one of those
|
|
160
|
+
* names — same precedence as macOS/Linux.
|
|
159
161
|
*/
|
|
160
162
|
setEnvVars?: Readonly<Record<string, string>>;
|
|
161
163
|
/**
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* directories and fenced files before spawning the child — the
|
|
166
|
-
* OS then refuses delete/rename of those, which the file's DACL
|
|
167
|
-
* alone cannot prevent. Omit for an exec with no file-deny
|
|
168
|
-
* session active.
|
|
169
|
-
*/
|
|
170
|
-
holderPid?: number;
|
|
171
|
-
/**
|
|
172
|
-
* Per-exec read-deny paths, stamped under the `srt-win exec`
|
|
173
|
-
* process's own PID and restored after the child exits. Same
|
|
164
|
+
* Per-exec read-deny paths, applied via an additive
|
|
165
|
+
* `(D;OICI;FA;;;<sb-SID>)` ACE under the `srt-win exec`
|
|
166
|
+
* process's own PID and released after the child exits. Same
|
|
174
167
|
* disk-first chokepoint as the session-level
|
|
175
168
|
* {@link stampWindowsAcl}; same fail-closed semantics (exec
|
|
176
169
|
* fails if any path cannot be stamped).
|
|
177
170
|
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* `
|
|
181
|
-
* glob
|
|
182
|
-
*
|
|
183
|
-
* drop it and run the child with the file readable.
|
|
171
|
+
* Normalized concrete paths — globs expanded by the caller via
|
|
172
|
+
* {@link expandWindowsFsPaths}, the same as session-level.
|
|
173
|
+
* `srt-win exec`'s `canonicalize_ace_targets` hard-fails on a
|
|
174
|
+
* glob (it never expands), so a `*`/`?` reaching this field is
|
|
175
|
+
* a caller bug.
|
|
184
176
|
*/
|
|
185
177
|
denyRead?: readonly string[];
|
|
186
178
|
/** Per-exec write-deny paths — see {@link denyRead}. */
|
|
187
179
|
denyWrite?: readonly string[];
|
|
188
180
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* fences `srt-sandbox` egress regardless of how the child was
|
|
200
|
-
* spawned.
|
|
181
|
+
* Working directory the child starts in. Fed to
|
|
182
|
+
* {@link buildGitConfigEnv} as a `safe.directory` entry so git
|
|
183
|
+
* inside the sandbox accepts the real-user-owned working tree.
|
|
184
|
+
* Default: `process.cwd()`.
|
|
185
|
+
*
|
|
186
|
+
* `srt-win exec` has no `--cwd` flag — the child's working
|
|
187
|
+
* directory is whatever the caller passes as the spawn `{cwd:}`
|
|
188
|
+
* option (broker `current_dir()` → runner `lpCurrentDirectory` →
|
|
189
|
+
* child inherits). This field must match that spawn option so
|
|
190
|
+
* `safe.directory` covers where git actually runs.
|
|
201
191
|
*/
|
|
202
|
-
|
|
192
|
+
cwd?: string;
|
|
203
193
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
194
|
+
* Session-level write-granted paths (the resolved
|
|
195
|
+
* `filesystem.allowWrite` set). Each becomes a `safe.directory`
|
|
196
|
+
* entry — see {@link buildGitConfigEnv}.
|
|
197
|
+
*/
|
|
198
|
+
allowWrite?: readonly string[];
|
|
199
|
+
/**
|
|
200
|
+
* Path to the TLS-termination trust bundle (the MITM CA + system
|
|
201
|
+
* roots) — fed to {@link generateProxyEnvVars} so the child's
|
|
202
|
+
* `NODE_EXTRA_CA_CERTS` / `CURL_CA_BUNDLE` / `SSL_CERT_FILE` /
|
|
203
|
+
* etc. point at it. Backslashes are normalised to forward slashes
|
|
204
|
+
* before emission so the value survives msys2 env conversion AND
|
|
205
|
+
* is accepted by native tools.
|
|
206
|
+
*
|
|
207
|
+
* The env-var layer covers OpenSSL-backed clients (msys2 curl,
|
|
208
|
+
* openssl-backed git, node, python, cargo). Schannel/.NET clients
|
|
209
|
+
* that read the Windows certificate store exclusively (System32
|
|
210
|
+
* `curl.exe`, `Invoke-WebRequest`, Go-built tools) trust via the
|
|
211
|
+
* separate `srt-win user trust-ca` / {@link windowsTrustCa}
|
|
212
|
+
* install-time write into the sandbox user's `CurrentUser\Root`.
|
|
210
213
|
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
* fail with `ACCESS_DENIED` on the bundle. The schannel-level
|
|
216
|
-
* trust set via {@link windowsTrustCa} is the only CA-trust path
|
|
217
|
-
* for the two-hop launch until working-tree/profile grants land.
|
|
214
|
+
* The caller is responsible for the sandbox user having read
|
|
215
|
+
* access to this path — `sandbox-manager.ts`'s `initialize()`
|
|
216
|
+
* pushes it into the session's `acl grant` read-set alongside the
|
|
217
|
+
* working-tree grants.
|
|
218
218
|
*/
|
|
219
219
|
caCertPath?: string;
|
|
220
|
+
/**
|
|
221
|
+
* Resolved `srt-win` spawn descriptor — from
|
|
222
|
+
* {@link resolveSrtWin}. Omit to resolve the packaged vendor
|
|
223
|
+
* binary at call time.
|
|
224
|
+
*/
|
|
225
|
+
srtWin?: SrtWinSpawn;
|
|
220
226
|
/**
|
|
221
227
|
* Inner shell. Defaults to `{ kind: 'cmd' }`. The child's post-`/c`
|
|
222
228
|
* (or `-Command` / `-c`) content is **passthrough** — `&` chains,
|
|
@@ -229,19 +235,21 @@ export interface WindowsSandboxParams {
|
|
|
229
235
|
binShell?: WindowsBinShell;
|
|
230
236
|
}
|
|
231
237
|
/**
|
|
232
|
-
* Locate `srt-win.exe`. Resolution order:
|
|
233
|
-
* 1. `
|
|
234
|
-
* 2. `<root>/vendor/srt-win/{arch}/srt-win.exe` (prebuilt — published npm
|
|
238
|
+
* Locate the packaged `srt-win.exe`. Resolution order:
|
|
239
|
+
* 1. `<root>/vendor/srt-win/{arch}/srt-win.exe` (prebuilt — published npm
|
|
235
240
|
* package, or after `npm run build:srt-win` locally).
|
|
236
|
-
*
|
|
241
|
+
* 2. `<root>/vendor/srt-win-src/target/release/srt-win.exe` (local
|
|
237
242
|
* `cargo build --release` fallback for development).
|
|
238
|
-
* 4. `<root>/vendor/srt-win/target/release/srt-win.exe` (transitional:
|
|
239
|
-
* stale local build from before the srt-win-src rename).
|
|
240
243
|
*
|
|
241
244
|
* `<root>` is {@link repoRoot} — `__dirname/../..`, which resolves to the
|
|
242
245
|
* repo root from `src/sandbox/` and `dist/sandbox/` alike, and to the
|
|
243
246
|
* package root when installed under `node_modules`.
|
|
244
247
|
*
|
|
248
|
+
* Callers that ship their own binary (or a multicall binary that
|
|
249
|
+
* routes on `argv[1] == `{@link SRT_WIN_DISPATCH_ARG1}) pass
|
|
250
|
+
* `windows.srtWin` instead of relying on this lookup — see
|
|
251
|
+
* {@link resolveSrtWin}.
|
|
252
|
+
*
|
|
245
253
|
* Resolution via the optional `@anthropic-ai/sandbox-runtime-win32-*`
|
|
246
254
|
* platform packages is added separately.
|
|
247
255
|
*
|
|
@@ -249,46 +257,105 @@ export interface WindowsSandboxParams {
|
|
|
249
257
|
*/
|
|
250
258
|
export declare function getSrtWinPath(): string;
|
|
251
259
|
/**
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
260
|
+
* `argv[1]` sentinel a multicall embedder's dispatcher matches
|
|
261
|
+
* against to route into `srt_win::run_from_args`. Mirrors the Rust
|
|
262
|
+
* `srt_win::SRT_WIN_DISPATCH_ARG1`; the two MUST stay in sync.
|
|
263
|
+
* `run_from_args` strips it before clap, so the standalone binary
|
|
264
|
+
* accepts it harmlessly.
|
|
265
|
+
*/
|
|
266
|
+
export declare const SRT_WIN_DISPATCH_ARG1 = "--srt-win";
|
|
267
|
+
/**
|
|
268
|
+
* Resolved `srt-win` spawn descriptor — the executable to load plus
|
|
269
|
+
* the leading arguments that carry the dispatch sentinel. Threaded
|
|
270
|
+
* to every spawn site so {@link resolveSrtWin} runs once (at
|
|
271
|
+
* `initialize()`) instead of re-`stat`ing on every helper call.
|
|
272
|
+
*/
|
|
273
|
+
export type SrtWinSpawn = Readonly<{
|
|
274
|
+
exe: string;
|
|
275
|
+
prependArgs: readonly string[];
|
|
276
|
+
}>;
|
|
277
|
+
/**
|
|
278
|
+
* Resolve the `srt-win` spawn target from config. When `cfg.path` is
|
|
279
|
+
* set it is used verbatim (no fallback to the packaged binary — an
|
|
280
|
+
* explicit override is a directive, not a hint) and
|
|
281
|
+
* {@link SRT_WIN_DISPATCH_ARG1} is prepended so a multicall
|
|
282
|
+
* dispatcher routes on `argv[1]`. When unset, falls back to
|
|
283
|
+
* {@link getSrtWinPath} with no sentinel (the packaged binary
|
|
284
|
+
* doesn't need it; `run_from_args` would strip it anyway).
|
|
257
285
|
*/
|
|
258
|
-
export declare function
|
|
286
|
+
export declare function resolveSrtWin(cfg?: SrtWinConfig): SrtWinSpawn;
|
|
259
287
|
/**
|
|
260
|
-
* Query the WFP filter set under the given sublayer
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
* filters installed by other tooling without the
|
|
288
|
+
* Query the WFP filter set under the given sublayer via live BFE
|
|
289
|
+
* enumeration. `installed` means at least one srt-win-tagged
|
|
290
|
+
* `block-user` filter is present. Detection is **tag-based**
|
|
291
|
+
* (providerData JSON); filters installed by other tooling without the
|
|
292
|
+
* tag are not counted.
|
|
293
|
+
*
|
|
294
|
+
* BFE enumeration is admin-gated — a non-elevated caller gets
|
|
295
|
+
* `state:"cannot-read"` with a `hint` (not an error). The
|
|
296
|
+
* non-elevated readiness check is {@link verifyWindowsWfpEgress}.
|
|
264
297
|
*/
|
|
265
298
|
export declare function getWindowsWfpStatus(opts?: {
|
|
266
299
|
sublayerGuid?: string;
|
|
300
|
+
srtWin?: SrtWinSpawn;
|
|
267
301
|
}): WindowsWfpStatusResult;
|
|
302
|
+
/**
|
|
303
|
+
* Behavioral proof that the WFP egress fence is active for the
|
|
304
|
+
* sandbox user. Binds a local listener on an ephemeral loopback port
|
|
305
|
+
* outside the WFP loopback-permit range, then spawns `srt-win
|
|
306
|
+
* runner` as the sandbox user (via `CreateProcessWithLogonW`) to
|
|
307
|
+
* attempt a direct TCP connect to it. The WFP block-user filter
|
|
308
|
+
* fires at `ALE_AUTH_CONNECT` — before any packet leaves — so an
|
|
309
|
+
* active fence yields WSAEACCES immediately and a missing fence lets
|
|
310
|
+
* the connect through (the kernel completes the handshake against
|
|
311
|
+
* the listening socket's backlog; no event-loop tick required, so
|
|
312
|
+
* the synchronous `runSrtWin` is safe). Does not require elevation
|
|
313
|
+
* and does not depend on any external host.
|
|
314
|
+
*
|
|
315
|
+
* `initialize()` calls this once per session, so a stale install
|
|
316
|
+
* (sandbox user provisioned but filters since removed) fails closed
|
|
317
|
+
* at session start instead of running every exec with full egress.
|
|
318
|
+
*
|
|
319
|
+
* @param opts.target overrides the probe target (skips the local
|
|
320
|
+
* listener bind).
|
|
321
|
+
* @param opts.proxyPortRange the WFP loopback-permit range the
|
|
322
|
+
* listener must avoid. Default
|
|
323
|
+
* {@link DEFAULT_WINDOWS_PROXY_PORT_RANGE}.
|
|
324
|
+
* @throws on any outcome other than `blocked` (exit 0).
|
|
325
|
+
*/
|
|
326
|
+
export declare function verifyWindowsWfpEgress(opts?: {
|
|
327
|
+
target?: string;
|
|
328
|
+
proxyPortRange?: readonly [number, number];
|
|
329
|
+
srtWin?: SrtWinSpawn;
|
|
330
|
+
}): Promise<WindowsWfpVerifyResult>;
|
|
268
331
|
/**
|
|
269
332
|
* Query the sandbox user account's provisioning state. Each field
|
|
270
333
|
* is independently observed so a half-provisioned install (e.g.
|
|
271
334
|
* user exists but credential file missing) is distinguishable.
|
|
272
335
|
* Does not require elevation.
|
|
273
336
|
*/
|
|
274
|
-
export declare function getWindowsSandboxUserStatus(
|
|
337
|
+
export declare function getWindowsSandboxUserStatus(opts?: {
|
|
338
|
+
srtWin?: SrtWinSpawn;
|
|
339
|
+
}): WindowsSandboxUserStatus;
|
|
275
340
|
/**
|
|
276
341
|
* Read back the persistent MITM CA the sandbox was installed with
|
|
277
342
|
* (via `srt-win user trust-ca` / {@link windowsTrustCa}).
|
|
278
343
|
* Returns `null` when no CA was installed. The PEM is what `srt-win
|
|
279
344
|
* user status` reconstructs from the DER stored in `state.db`.
|
|
280
345
|
*
|
|
281
|
-
* On Windows
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
346
|
+
* On Windows, `tlsTerminate` requires this CA to be present in the
|
|
347
|
+
* sandbox user's `CurrentUser\Root` (schannel-level trust is an
|
|
348
|
+
* install-time concern, not per-session); the host calls this from
|
|
349
|
+
* `initialize()` to fail early with an actionable message when it
|
|
350
|
+
* isn't.
|
|
286
351
|
*
|
|
287
352
|
* @param status pass an already-fetched
|
|
288
353
|
* {@link getWindowsSandboxUserStatus} result to avoid a second
|
|
289
354
|
* `srt-win user status` spawn.
|
|
290
355
|
*/
|
|
291
|
-
export declare function getWindowsSandboxCaCert(status?: WindowsSandboxUserStatus
|
|
356
|
+
export declare function getWindowsSandboxCaCert(status?: WindowsSandboxUserStatus, opts?: {
|
|
357
|
+
srtWin?: SrtWinSpawn;
|
|
358
|
+
}): {
|
|
292
359
|
pem: string;
|
|
293
360
|
thumb: string;
|
|
294
361
|
} | null;
|
|
@@ -302,17 +369,16 @@ export declare function getWindowsSandboxCaCert(status?: WindowsSandboxUserStatu
|
|
|
302
369
|
*
|
|
303
370
|
* The CA has a separate lifecycle from {@link installWindowsSandbox}
|
|
304
371
|
* — install provisions the account/filters and never touches the CA;
|
|
305
|
-
* call this AFTER install when `tlsTerminate` will be used
|
|
306
|
-
* `windows.asSandboxUser`.
|
|
372
|
+
* call this AFTER install when `tlsTerminate` will be used.
|
|
307
373
|
*
|
|
308
374
|
* @throws when the sandbox user is not provisioned, the file is not a
|
|
309
375
|
* parseable X.509 certificate, or the registry write into the
|
|
310
376
|
* sandbox user's hive fails.
|
|
311
377
|
*/
|
|
312
|
-
export declare function windowsTrustCa(caCertPath: string
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
378
|
+
export declare function windowsTrustCa(caCertPath: string, opts?: {
|
|
379
|
+
srtWin?: SrtWinSpawn;
|
|
380
|
+
}): void;
|
|
381
|
+
export interface WindowsInstallOptions {
|
|
316
382
|
/** WFP sublayer GUID. Omit for srt-win's compile-time default. */
|
|
317
383
|
sublayerGuid?: string;
|
|
318
384
|
/**
|
|
@@ -321,17 +387,23 @@ export interface WindowsInstallOptions extends WindowsGroupRef {
|
|
|
321
387
|
* Default {@link DEFAULT_WINDOWS_PROXY_PORT_RANGE}.
|
|
322
388
|
*/
|
|
323
389
|
proxyPortRange?: readonly [number, number];
|
|
390
|
+
/**
|
|
391
|
+
* Name for the sandbox user account (created if absent, adopted
|
|
392
|
+
* if it already exists as a local user). Default `srt-sandbox`.
|
|
393
|
+
*/
|
|
394
|
+
sandboxUser?: string;
|
|
324
395
|
/**
|
|
325
396
|
* Replace an existing install whose configuration differs
|
|
326
|
-
* (different
|
|
327
|
-
* Without this, install refuses with "already
|
|
328
|
-
* different config" rather than silently
|
|
397
|
+
* (different port range or sandbox-user name under the same
|
|
398
|
+
* sublayer). Without this, install refuses with "already
|
|
399
|
+
* installed with different config" rather than silently
|
|
400
|
+
* overwriting.
|
|
329
401
|
*/
|
|
330
402
|
force?: boolean;
|
|
403
|
+
/** Resolved `srt-win` spawn descriptor — from {@link resolveSrtWin}. */
|
|
404
|
+
srtWin?: SrtWinSpawn;
|
|
331
405
|
}
|
|
332
406
|
export interface WindowsInstallResult {
|
|
333
|
-
/** Post-install group state. */
|
|
334
|
-
group: WindowsGroupStatusResult;
|
|
335
407
|
/** Post-install WFP state. */
|
|
336
408
|
wfp: WindowsWfpStatusResult;
|
|
337
409
|
/** Post-install sandbox-user state. */
|
|
@@ -344,187 +416,169 @@ export interface WindowsInstallResult {
|
|
|
344
416
|
cancelled?: true;
|
|
345
417
|
}
|
|
346
418
|
/**
|
|
347
|
-
* One-shot install:
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
419
|
+
* One-shot install: provisions the `srt-sandbox` user account and
|
|
420
|
+
* installs the user-SID-keyed WFP filter set — all in a single
|
|
421
|
+
* self-elevating process (one UAC prompt). Idempotent; re-running
|
|
422
|
+
* rotates the sandbox user's password.
|
|
351
423
|
*
|
|
352
|
-
* Network for the calling user is **not disrupted
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
* filter-1 (PERMIT group-enabled) takes over for the broker; only
|
|
357
|
-
* `srt-win exec` children (group flipped deny-only) fall through to
|
|
358
|
-
* the loopback/BLOCK filters.
|
|
424
|
+
* Network for the calling user is **not disrupted**: the filters key
|
|
425
|
+
* on the `srt-sandbox` user's SID, so the broker, services, and
|
|
426
|
+
* every other principal fall through to default-permit. No logout
|
|
427
|
+
* is required.
|
|
359
428
|
*
|
|
360
|
-
* Returns the post-call
|
|
361
|
-
* UAC prompt this returns `{cancelled: true, …}` rather
|
|
362
|
-
* throwing — cancellation is a user choice, not an error.
|
|
429
|
+
* Returns the post-call WFP + sandbox-user state. If the user
|
|
430
|
+
* cancels the UAC prompt this returns `{cancelled: true, …}` rather
|
|
431
|
+
* than throwing — cancellation is a user choice, not an error.
|
|
363
432
|
*
|
|
364
|
-
* @throws on
|
|
365
|
-
*
|
|
366
|
-
*
|
|
433
|
+
* @throws on user/WFP creation failure, or if filters already exist
|
|
434
|
+
* under `sublayerGuid` with a different port range and `force` is
|
|
435
|
+
* not set.
|
|
367
436
|
*/
|
|
368
437
|
export declare function installWindowsSandbox(opts?: WindowsInstallOptions): WindowsInstallResult;
|
|
369
438
|
/**
|
|
370
|
-
* Remove the WFP filter set under `sublayerGuid`
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
* **Does NOT delete the discriminator group** — group membership is
|
|
374
|
-
* persistent user state and removing it would force every user to
|
|
375
|
-
* re-do the logout dance on the next install. Call
|
|
376
|
-
* {@link deleteWindowsGroup} explicitly if you want full teardown.
|
|
377
|
-
*
|
|
378
|
-
* **Does** remove the `srt-sandbox` account, its credential file,
|
|
379
|
-
* and the setup marker, unless `keepUser` is set — the credential
|
|
380
|
-
* is useless without the account and vice versa, so they're
|
|
381
|
-
* treated as one unit.
|
|
439
|
+
* Remove the WFP filter set under `sublayerGuid` and the
|
|
440
|
+
* `srt-sandbox` account, its credential file, and the setup marker
|
|
441
|
+
* (one UAC prompt). Idempotent.
|
|
382
442
|
*
|
|
383
443
|
* @returns `{cancelled: true}` if the user dismissed UAC.
|
|
384
444
|
*/
|
|
385
445
|
export declare function uninstallWindowsSandbox(opts?: {
|
|
386
446
|
sublayerGuid?: string;
|
|
387
447
|
keepUser?: boolean;
|
|
448
|
+
srtWin?: SrtWinSpawn;
|
|
388
449
|
}): {
|
|
389
450
|
cancelled?: true;
|
|
390
451
|
};
|
|
391
452
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
* {@link installWindowsSandbox} instead; this exists for
|
|
402
|
-
* enterprise/CI flows that manage group and WFP separately.
|
|
403
|
-
* **Requires elevation.** Idempotent.
|
|
404
|
-
*/
|
|
405
|
-
export declare function createWindowsGroup(ref: WindowsGroupRef & {
|
|
406
|
-
userSid?: string;
|
|
407
|
-
}): void;
|
|
408
|
-
/**
|
|
409
|
-
* Granular primitive: install the machine-wide WFP filter set
|
|
410
|
-
* under `sublayerGuid` keyed on the group SID. Most callers should
|
|
411
|
-
* use {@link installWindowsSandbox} instead; this exists for
|
|
412
|
-
* enterprise/CI flows that manage group and WFP separately.
|
|
413
|
-
* **Requires elevation.** Idempotent — re-running replaces any
|
|
414
|
-
* existing srt-win-tagged filters under that sublayer.
|
|
415
|
-
*/
|
|
416
|
-
export declare function createWindowsWfp(ref: WindowsGroupRef & {
|
|
417
|
-
sublayerGuid?: string;
|
|
418
|
-
proxyPortRange?: readonly [number, number];
|
|
419
|
-
}): void;
|
|
420
|
-
/**
|
|
421
|
-
* Per-file outcome from `srt-win acl restore --json`. `status:
|
|
422
|
-
* "restored"` covers both `Restored` and `AlreadyOriginal` on the
|
|
423
|
-
* Rust side (the host doesn't need to distinguish them); every
|
|
424
|
-
* other status keeps the snapshot row (fail-closed) and is
|
|
425
|
-
* surfaced to the user as an anomaly to investigate. Mirrors
|
|
426
|
-
* `restore_entry()` in `vendor/srt-win-src/src/main.rs`.
|
|
427
|
-
*/
|
|
428
|
-
export interface WindowsAclPathOutcome {
|
|
429
|
-
path: string;
|
|
430
|
-
status: 'restored' | 'relocated' | 'missing' | 'leftChanged' | 'leftUnreadable' | 'originalSdTampered' | 'originalSdLost' | 'stampedUnrecognized';
|
|
431
|
-
/** Hex `FILE_ID_INFO` recorded at stamp time. Present when `status ≠ "restored"`. */
|
|
432
|
-
expectedFileId?: string;
|
|
433
|
-
/** Where the protected file was found by `file_id`. Only on `relocated`. */
|
|
434
|
-
movedTo?: string;
|
|
435
|
-
/** `true` whenever `status ≠ "restored"` — the snapshot row was kept (restore not confirmed). */
|
|
436
|
-
leftStamped?: boolean;
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Per-parent-directory outcome from `srt-win acl restore --json`.
|
|
440
|
-
* `stillHeld` is normal (another active session still references
|
|
441
|
-
* a file under this directory). Mirrors `parent_entries_from()` +
|
|
442
|
-
* `ParentRestoreOutcome::as_str()` in `vendor/srt-win-src/src/`.
|
|
453
|
+
* Resolve any Windows filesystem-config path list — `allowRead`/
|
|
454
|
+
* `allowWrite` grants and `denyRead`/`denyWrite` stamps — to
|
|
455
|
+
* concrete existing paths via the single platform-aware
|
|
456
|
+
* {@link normalizePathForSandbox} chokepoint (Linux/macOS parity:
|
|
457
|
+
* point-in-time expansion at session initialize, not per-exec).
|
|
458
|
+
* Glob patterns are expanded; non-glob paths are normalized and
|
|
459
|
+
* returned 1:1. Missing paths are dropped (statSync probe).
|
|
460
|
+
* Directory targets are accepted — the additive sandbox-user ACE
|
|
461
|
+
* carries `(OI)(CI)` so it covers the subtree.
|
|
443
462
|
*/
|
|
444
|
-
export
|
|
445
|
-
path: string;
|
|
446
|
-
status: 'restored' | 'alreadyOriginal' | 'stillHeld' | 'leftChanged' | 'missing' | 'leftStamped';
|
|
447
|
-
/** Underlying error for `leftStamped`. */
|
|
448
|
-
error?: string;
|
|
449
|
-
}
|
|
450
|
-
/** Top-level shape of `srt-win acl restore --json`. */
|
|
451
|
-
export interface WindowsAclRestoreResult {
|
|
452
|
-
paths: WindowsAclPathOutcome[];
|
|
453
|
-
parents: WindowsAclParentOutcome[];
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Expand the `denyRead`/`denyWrite` input set to a flat list of
|
|
457
|
-
* existing FILE paths for `srt-win acl stamp`.
|
|
458
|
-
*
|
|
459
|
-
* Every input goes through {@link normalizePathForSandbox} (the
|
|
460
|
-
* single Windows-aware chokepoint: `\\?\`/UNC-strip, drive-letter
|
|
461
|
-
* case-fold, ~-expand, realpath). Globs (`*`/`?` only — `[`/`]`
|
|
462
|
-
* are legal Win32 filename chars) expand via the shared walker
|
|
463
|
-
* with case-insensitive matching (point-in-time: a file appearing
|
|
464
|
-
* after this returns is NOT covered). Each candidate is checked
|
|
465
|
-
* with one `statSync({throwIfNoEntry:false})`: missing → drop
|
|
466
|
-
* (the protection model covers files present at session start);
|
|
467
|
-
* directory → reject (the file stamp applies a per-file DACL plus
|
|
468
|
-
* a per-parent-directory allow-list; stamping a directory itself
|
|
469
|
-
* would touch every child); file → keep.
|
|
470
|
-
*/
|
|
471
|
-
export declare function expandWindowsFsDenyPaths(patterns: readonly string[]): string[];
|
|
463
|
+
export declare function expandWindowsFsPaths(patterns: readonly string[]): string[];
|
|
472
464
|
export interface WindowsAclStampOptions {
|
|
473
|
-
|
|
474
|
-
/** Files the sandboxed child must not read. */
|
|
465
|
+
/** Paths the sandboxed child must not read. */
|
|
475
466
|
denyRead: readonly string[];
|
|
476
|
-
/**
|
|
467
|
+
/** Paths the sandboxed child must not write (read stays allowed). */
|
|
477
468
|
denyWrite: readonly string[];
|
|
469
|
+
/** SID of the dedicated sandbox user — {@link WindowsSandboxUserStatus.sid}. */
|
|
470
|
+
sandboxUserSid: string;
|
|
478
471
|
/** Long-lived host PID the holds are tied to. Default: this process. */
|
|
479
472
|
holderPid?: number;
|
|
473
|
+
/** Resolved `srt-win` spawn descriptor — from {@link resolveSrtWin}. */
|
|
474
|
+
srtWin?: SrtWinSpawn;
|
|
480
475
|
}
|
|
481
476
|
/**
|
|
482
|
-
* Apply the file-deny
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
477
|
+
* Apply the file-deny ACE set for one host session: an additive
|
|
478
|
+
* `(D;OICI;mask;;;<sb-SID>)` on the target plus a
|
|
479
|
+
* `(D;OICI;FILE_DELETE_CHILD;;;<sb-SID>)` on the parent — no
|
|
480
|
+
* PROTECTED rewrite, no SD snapshot. Idempotent and refcounted via
|
|
481
|
+
* srt-win's `working_aces` table.
|
|
486
482
|
*
|
|
487
|
-
* Inputs are passed verbatim to `srt-win` (which canonicalizes
|
|
488
|
-
* rejects
|
|
489
|
-
*
|
|
490
|
-
* pre-expand via {@link expandWindowsFsDenyPaths}.
|
|
483
|
+
* Inputs are passed verbatim to `srt-win` (which canonicalizes and
|
|
484
|
+
* rejects globs). Callers that accept globs should pre-expand via
|
|
485
|
+
* {@link expandWindowsFsPaths}.
|
|
491
486
|
*
|
|
492
487
|
* @throws on exit ≠ 0 — including exit 2 (one or more inputs
|
|
493
488
|
* skipped). srt-win stamps the resolvable inputs before exiting
|
|
494
489
|
* 2, so on throw the caller should call {@link restoreWindowsAcl}
|
|
495
|
-
* to release whatever WAS stamped
|
|
496
|
-
* means tearing down a partial setup).
|
|
490
|
+
* to release whatever WAS stamped.
|
|
497
491
|
*/
|
|
498
492
|
export declare function stampWindowsAcl(opts: WindowsAclStampOptions): void;
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
493
|
+
/**
|
|
494
|
+
* Per-path outcome from `srt-win acl restore --json` /
|
|
495
|
+
* `revoke --json`. The status set is intentionally loose: the
|
|
496
|
+
* pre-/post- same-user-removal `srt-win` builds emit different
|
|
497
|
+
* vocabularies for `restore` (`restored`/`leftChanged`/… vs
|
|
498
|
+
* `revoked`/`stillHeld`/…). Callers (`reset()`) only log these,
|
|
499
|
+
* so the union is whatever the binary on PATH says.
|
|
500
|
+
*/
|
|
501
|
+
export interface WindowsAclAceOutcome {
|
|
502
|
+
path: string;
|
|
503
|
+
status: string;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Release this holder's deny ACEs and remove the sandbox-user ACE
|
|
507
|
+
* on any path whose refcount falls to zero. Best-effort (does not
|
|
508
|
+
* throw on per-path anomalies); returns per-path outcomes for the
|
|
509
|
+
* caller to surface. Returns `undefined` only when `srt-win`
|
|
510
|
+
* itself failed (no JSON to parse).
|
|
511
|
+
*/
|
|
512
|
+
export declare function restoreWindowsAcl(opts: {
|
|
513
|
+
sandboxUserSid: string;
|
|
514
|
+
holderPid?: number;
|
|
515
|
+
srtWin?: SrtWinSpawn;
|
|
516
|
+
}): WindowsAclAceOutcome[] | undefined;
|
|
517
|
+
export interface WindowsAclGrantOptions {
|
|
518
|
+
/** Paths to grant `MODIFY_NO_FDC` on (the working tree, `allowWrite`). */
|
|
519
|
+
write: readonly string[];
|
|
520
|
+
/** Paths to grant `FILE_GENERIC_READ|EXECUTE` on (`allowRead`). */
|
|
521
|
+
read: readonly string[];
|
|
522
|
+
/** SID of the dedicated sandbox user — {@link WindowsSandboxUserStatus.sid}. */
|
|
523
|
+
sandboxUserSid: string;
|
|
524
|
+
/** Long-lived host PID the holds are tied to. Default: this process. */
|
|
502
525
|
holderPid?: number;
|
|
526
|
+
/** Resolved `srt-win` spawn descriptor — from {@link resolveSrtWin}. */
|
|
527
|
+
srtWin?: SrtWinSpawn;
|
|
503
528
|
}
|
|
504
529
|
/**
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
530
|
+
* Apply per-session additive `(OI)(CI)` ALLOW ACEs for the sandbox
|
|
531
|
+
* user on each path. The sandbox user has no inherent rights on
|
|
532
|
+
* real-user-owned files; this is what makes the working tree (and
|
|
533
|
+
* explicit `allowRead`/`allowWrite` paths) reachable from the
|
|
534
|
+
* child. Idempotent and refcounted via srt-win's `working_aces`
|
|
535
|
+
* table.
|
|
510
536
|
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
* than block teardown.
|
|
537
|
+
* @throws on exit ≠ 0. On throw the caller should call
|
|
538
|
+
* {@link revokeWindowsAcl} to release whatever WAS granted.
|
|
514
539
|
*/
|
|
515
|
-
export declare function
|
|
540
|
+
export declare function grantWindowsAcl(opts: WindowsAclGrantOptions): void;
|
|
516
541
|
/**
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
542
|
+
* Release this holder's grants and remove the sandbox-user ACE on
|
|
543
|
+
* any path whose refcount falls to zero. Best-effort (does not
|
|
544
|
+
* throw); logs anomalies.
|
|
520
545
|
*/
|
|
521
|
-
export declare
|
|
546
|
+
export declare function revokeWindowsAcl(opts: {
|
|
547
|
+
sandboxUserSid: string;
|
|
548
|
+
holderPid?: number;
|
|
549
|
+
srtWin?: SrtWinSpawn;
|
|
550
|
+
}): WindowsAclAceOutcome[] | undefined;
|
|
522
551
|
/**
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
552
|
+
* Build the `GIT_CONFIG_COUNT` / `GIT_CONFIG_KEY_<n>` /
|
|
553
|
+
* `GIT_CONFIG_VALUE_<n>` env-var set for the sandboxed child.
|
|
554
|
+
*
|
|
555
|
+
* Emits:
|
|
556
|
+
* - `safe.directory=<dir>` for each entry in `safeDirs` (or one
|
|
557
|
+
* `safe.directory=*` when the list is long) — the working tree
|
|
558
|
+
* is owned by the real user, so git running as `srt-sandbox`
|
|
559
|
+
* refuses with "detected dubious ownership" without it.
|
|
560
|
+
* - `http.schannelUseSSLCAInfo=true` and
|
|
561
|
+
* `http.schannelCheckRevoke=false` when `schannelCa` — makes
|
|
562
|
+
* git's default (schannel) backend honor `GIT_SSL_CAINFO`
|
|
563
|
+
* without `-c http.sslBackend=openssl`. Revocation is disabled
|
|
564
|
+
* because CryptoAPI CRL/OCSP fetches ignore proxy env and would
|
|
565
|
+
* be WFP-fenced.
|
|
566
|
+
*
|
|
567
|
+
* Composes with an existing `GIT_CONFIG_COUNT` in `baseEnv` by
|
|
568
|
+
* continuing its numbering; the returned `GIT_CONFIG_COUNT` is the
|
|
569
|
+
* new total. Under the two-hop launch the broker's own environment
|
|
570
|
+
* never reaches the child, so `baseEnv` is the caller-supplied
|
|
571
|
+
* overlay ({@link WindowsSandboxParams.setEnvVars}), not
|
|
572
|
+
* `process.env`.
|
|
573
|
+
*
|
|
574
|
+
* Paths are emitted with forward slashes so the value survives
|
|
575
|
+
* msys2's env conversion untouched and native git accepts it.
|
|
526
576
|
*/
|
|
527
|
-
export declare
|
|
577
|
+
export declare function buildGitConfigEnv(opts: {
|
|
578
|
+
safeDirs: readonly string[];
|
|
579
|
+
schannelCa: boolean;
|
|
580
|
+
baseEnv?: Readonly<Record<string, string | undefined>>;
|
|
581
|
+
}): Record<string, string>;
|
|
528
582
|
/**
|
|
529
583
|
* Build the spawn descriptor for running `command` inside the Windows
|
|
530
584
|
* sandbox: an `argv` array plus the `env` to spawn it with.
|
|
@@ -538,9 +592,10 @@ export declare const WINDOWS_ACL_PARENT_OK: Set<"restored" | "missing" | "leftCh
|
|
|
538
592
|
* Proxy configuration is single-sourced by {@link generateProxyEnvVars}
|
|
539
593
|
* (the same canonical builder used on macOS/Linux). `srt-win exec`
|
|
540
594
|
* takes no `--http-proxy` / `--socks-proxy` flags and synthesizes no
|
|
541
|
-
* proxy env
|
|
542
|
-
*
|
|
543
|
-
*
|
|
595
|
+
* proxy env. The two-hop runner starts with the SANDBOX user's
|
|
596
|
+
* profile env (`USERPROFILE`/`TEMP` isolated) and overlays exactly
|
|
597
|
+
* what we pass as `--env` — built here from the broker's `PATH` plus
|
|
598
|
+
* the generated proxy set.
|
|
544
599
|
*/
|
|
545
600
|
export declare function wrapCommandWithSandboxWindows(p: WindowsSandboxParams): {
|
|
546
601
|
argv: string[];
|
|
@@ -548,13 +603,14 @@ export declare function wrapCommandWithSandboxWindows(p: WindowsSandboxParams):
|
|
|
548
603
|
};
|
|
549
604
|
/**
|
|
550
605
|
* Install instructions, surfaced verbatim in error messages.
|
|
551
|
-
* Tailored to the observed group state: if the install already
|
|
552
|
-
* ran (`created-not-on-token`), only the logout is missing.
|
|
553
606
|
*/
|
|
554
|
-
export declare function windowsInstallInstructions(
|
|
607
|
+
export declare function windowsInstallInstructions(sublayerGuid: string | undefined): string;
|
|
555
608
|
/**
|
|
556
609
|
* Check the Windows backend is ready to sandbox. Errors block
|
|
557
610
|
* `initialize()`; warnings are informational.
|
|
558
611
|
*/
|
|
559
|
-
export declare function checkWindowsDependencies(
|
|
612
|
+
export declare function checkWindowsDependencies(opts?: {
|
|
613
|
+
sublayerGuid?: string;
|
|
614
|
+
srtWin?: SrtWinSpawn;
|
|
615
|
+
}): SandboxDependencyCheck;
|
|
560
616
|
//# sourceMappingURL=windows-sandbox-utils.d.ts.map
|