agents-bridge 0.3.10 → 0.3.12

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 (78) hide show
  1. package/dist/agents/cli-runner.d.ts.map +1 -1
  2. package/dist/agents/cli-runner.js +5 -29
  3. package/dist/agents/cli-runner.js.map +1 -1
  4. package/dist/agents/codex-app-server-runtime.d.ts.map +1 -1
  5. package/dist/agents/codex-app-server-runtime.js +4 -3
  6. package/dist/agents/codex-app-server-runtime.js.map +1 -1
  7. package/dist/agents/model-auto-binding.d.ts.map +1 -1
  8. package/dist/agents/model-auto-binding.js +4 -5
  9. package/dist/agents/model-auto-binding.js.map +1 -1
  10. package/dist/agents/model-control-files.d.ts +3 -2
  11. package/dist/agents/model-control-files.d.ts.map +1 -1
  12. package/dist/agents/model-control-files.js +53 -12
  13. package/dist/agents/model-control-files.js.map +1 -1
  14. package/dist/agents/model-device-secret.d.ts +10 -0
  15. package/dist/agents/model-device-secret.d.ts.map +1 -0
  16. package/dist/agents/model-device-secret.js +47 -0
  17. package/dist/agents/model-device-secret.js.map +1 -0
  18. package/dist/agents/platform-spawn.d.ts +2 -0
  19. package/dist/agents/platform-spawn.d.ts.map +1 -0
  20. package/dist/agents/platform-spawn.js +4 -0
  21. package/dist/agents/platform-spawn.js.map +1 -0
  22. package/dist/agents/process-tree.d.ts +4 -0
  23. package/dist/agents/process-tree.d.ts.map +1 -0
  24. package/dist/agents/process-tree.js +46 -0
  25. package/dist/agents/process-tree.js.map +1 -0
  26. package/dist/agents/trusted-launcher.d.ts.map +1 -1
  27. package/dist/agents/trusted-launcher.js +7 -3
  28. package/dist/agents/trusted-launcher.js.map +1 -1
  29. package/dist/agents/windows-model-control-security.d.ts +10 -2
  30. package/dist/agents/windows-model-control-security.d.ts.map +1 -1
  31. package/dist/agents/windows-model-control-security.js +160 -25
  32. package/dist/agents/windows-model-control-security.js.map +1 -1
  33. package/dist/channels/botlink.d.ts.map +1 -1
  34. package/dist/channels/botlink.js +3 -1
  35. package/dist/channels/botlink.js.map +1 -1
  36. package/dist/cli/cmd-start.d.ts.map +1 -1
  37. package/dist/cli/cmd-start.js +21 -12
  38. package/dist/cli/cmd-start.js.map +1 -1
  39. package/dist/cli/cmd-stop.d.ts.map +1 -1
  40. package/dist/cli/cmd-stop.js +2 -1
  41. package/dist/cli/cmd-stop.js.map +1 -1
  42. package/dist/cli/cmd-update.d.ts +1 -0
  43. package/dist/cli/cmd-update.d.ts.map +1 -1
  44. package/dist/cli/cmd-update.js +3 -2
  45. package/dist/cli/cmd-update.js.map +1 -1
  46. package/dist/cli/initialize-agent-runtimes.d.ts +4 -0
  47. package/dist/cli/initialize-agent-runtimes.d.ts.map +1 -0
  48. package/dist/cli/initialize-agent-runtimes.js +41 -0
  49. package/dist/cli/initialize-agent-runtimes.js.map +1 -0
  50. package/dist/cli/temporary-files.d.ts +8 -0
  51. package/dist/cli/temporary-files.d.ts.map +1 -0
  52. package/dist/cli/temporary-files.js +43 -0
  53. package/dist/cli/temporary-files.js.map +1 -0
  54. package/dist/cli/update-check.d.ts.map +1 -1
  55. package/dist/cli/update-check.js +3 -2
  56. package/dist/cli/update-check.js.map +1 -1
  57. package/dist/cloud/main.js +2 -0
  58. package/dist/cloud/main.js.map +1 -1
  59. package/dist/config/attachment-handoff.d.ts.map +1 -1
  60. package/dist/config/attachment-handoff.js +12 -8
  61. package/dist/config/attachment-handoff.js.map +1 -1
  62. package/dist/config/paths.d.ts.map +1 -1
  63. package/dist/config/paths.js +2 -1
  64. package/dist/config/paths.js.map +1 -1
  65. package/dist/config/platform-paths.d.ts +6 -0
  66. package/dist/config/platform-paths.d.ts.map +1 -0
  67. package/dist/config/platform-paths.js +29 -0
  68. package/dist/config/platform-paths.js.map +1 -0
  69. package/dist/config/zod-schema.d.ts +10 -10
  70. package/dist/config/zod-schema.d.ts.map +1 -1
  71. package/dist/config/zod-schema.js +2 -1
  72. package/dist/config/zod-schema.js.map +1 -1
  73. package/dist/runtime-activity-snapshot.d.ts.map +1 -1
  74. package/dist/runtime-activity-snapshot.js +2 -0
  75. package/dist/runtime-activity-snapshot.js.map +1 -1
  76. package/package.json +8 -3
  77. package/scripts/inspect-model-device-secret.mjs +23 -0
  78. package/scripts/windows-smoke.mjs +211 -0
@@ -1,9 +1,11 @@
1
1
  import { constants } from 'node:fs';
2
- import { lstat, mkdir, open, realpath, rename, unlink } from 'node:fs/promises';
2
+ import { link, lstat, mkdir, open, realpath, rename, unlink } from 'node:fs/promises';
3
3
  import { dirname, resolve } from 'node:path';
4
4
  import { randomUUID } from 'node:crypto';
5
+ import { AGENTS_STATE_DIR } from '../config/paths.js';
5
6
  import { ensureWindowsModelControlSecurity, sameWindowsModelControlPath } from './windows-model-control-security.js';
6
7
  const MAX_MODEL_CONTROL_FILE_BYTES = 64 * 1024;
8
+ const pendingFileOperations = new Map();
7
9
  function expectedUid() {
8
10
  return typeof process.geteuid === 'function' ? process.geteuid() : typeof process.getuid === 'function' ? process.getuid() : undefined;
9
11
  }
@@ -12,6 +14,25 @@ function expectedUid() {
12
14
  export function createModelControlFileAccess({ platform = process.platform, windowsSecurity = ensureWindowsModelControlSecurity, } = {}) {
13
15
  const windows = platform === 'win32';
14
16
  const noFollow = windows ? 0 : constants.O_NOFOLLOW;
17
+ // Serialize only the same file, including the short exclusive-publish link
18
+ // window. Independent Agent files still run concurrently; no global IO lock.
19
+ async function withFileLock(path, operation) {
20
+ const key = (windows ? 'win32:' + resolve(path).toLowerCase() : 'posix:' + resolve(path));
21
+ const previous = pendingFileOperations.get(key) ?? Promise.resolve();
22
+ let release;
23
+ const gate = new Promise(resolveGate => { release = resolveGate; });
24
+ const tail = previous.then(() => gate);
25
+ pendingFileOperations.set(key, tail);
26
+ await previous;
27
+ try {
28
+ return await operation();
29
+ }
30
+ finally {
31
+ release();
32
+ if (pendingFileOperations.get(key) === tail)
33
+ pendingFileOperations.delete(key);
34
+ }
35
+ }
15
36
  async function ensureSecureModelControlDirectory(path) {
16
37
  const directory = resolve(path);
17
38
  await mkdir(directory, { recursive: true, mode: 0o700 });
@@ -26,8 +47,12 @@ export function createModelControlFileAccess({ platform = process.platform, wind
26
47
  const canonical = await realpath(directory);
27
48
  if (windows ? !sameWindowsModelControlPath(canonical, directory) : canonical !== directory)
28
49
  throw new Error('INSECURE_MODEL_CONTROL_DIRECTORY_PATH');
29
- if (windows)
30
- await windowsSecurity(directory);
50
+ if (windows) {
51
+ // Only this Bridge's direct per-Agent runtime directory is owned by us.
52
+ // The generic file helper must never rewrite an arbitrary parent's ACL.
53
+ const privateDirectory = sameWindowsModelControlPath(dirname(directory), resolve(AGENTS_STATE_DIR()));
54
+ await windowsSecurity(directory, 'directory', privateDirectory);
55
+ }
31
56
  }
32
57
  async function validateOpenFile(file, path) {
33
58
  const info = await file.stat();
@@ -47,7 +72,7 @@ export function createModelControlFileAccess({ platform = process.platform, wind
47
72
  const canonical = await realpath(path);
48
73
  if (!sameWindowsModelControlPath(canonical, resolve(path)))
49
74
  throw new Error('INSECURE_MODEL_CONTROL_FILE_PATH');
50
- await windowsSecurity(path);
75
+ await windowsSecurity(path, 'file');
51
76
  }
52
77
  }
53
78
  async function openExisting(path) {
@@ -60,12 +85,12 @@ export function createModelControlFileAccess({ platform = process.platform, wind
60
85
  }
61
86
  return open(path, constants.O_RDONLY | noFollow);
62
87
  }
63
- async function readSecureModelControlFile(path) {
88
+ async function readSecureModelControlFileBuffer(path) {
64
89
  await ensureSecureModelControlDirectory(dirname(path));
65
90
  const file = await openExisting(path);
66
91
  try {
67
92
  await validateOpenFile(file, path);
68
- return await file.readFile('utf8');
93
+ return await file.readFile();
69
94
  }
70
95
  finally {
71
96
  await file.close();
@@ -88,19 +113,29 @@ export function createModelControlFileAccess({ platform = process.platform, wind
88
113
  if (Buffer.byteLength(contents, 'utf8') > MAX_MODEL_CONTROL_FILE_BYTES)
89
114
  throw new Error('MODEL_CONTROL_FILE_TOO_LARGE');
90
115
  await ensureSecureModelControlDirectory(dirname(path));
91
- const file = await open(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | noFollow, 0o600);
116
+ // Do not expose an empty final .device while preparing its Windows ACL.
117
+ // Only fully written, fsynced private content is published. link() fails
118
+ // with EEXIST instead of replacing an existing device identity.
119
+ const temporaryPath = `${path}.${randomUUID()}.create.tmp`;
120
+ const file = await open(temporaryPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | noFollow, 0o600);
92
121
  try {
93
- await validateOpenFile(file, path);
122
+ await validateOpenFile(file, temporaryPath);
94
123
  await file.writeFile(contents);
95
- await validateOpenFile(file, path);
124
+ await validateOpenFile(file, temporaryPath);
96
125
  await file.sync();
97
126
  }
98
127
  catch (error) {
99
128
  await file.close().catch(() => undefined);
100
- await unlink(path).catch(() => undefined);
129
+ await unlink(temporaryPath).catch(() => undefined);
101
130
  throw error;
102
131
  }
103
132
  await file.close();
133
+ try {
134
+ await link(temporaryPath, path);
135
+ }
136
+ finally {
137
+ await unlink(temporaryPath);
138
+ }
104
139
  await syncDirectory(dirname(path));
105
140
  }
106
141
  async function writeSecureModelControlFile(path, contents) {
@@ -143,7 +178,13 @@ export function createModelControlFileAccess({ platform = process.platform, wind
143
178
  }
144
179
  await syncDirectory(dirname(path));
145
180
  }
146
- return { ensureSecureModelControlDirectory, readSecureModelControlFile, createSecureModelControlFile, writeSecureModelControlFile };
181
+ return {
182
+ ensureSecureModelControlDirectory,
183
+ readSecureModelControlFileBuffer: (path) => withFileLock(path, () => readSecureModelControlFileBuffer(path)),
184
+ readSecureModelControlFile: (path) => withFileLock(path, async () => (await readSecureModelControlFileBuffer(path)).toString('utf8')),
185
+ createSecureModelControlFile: (path, contents) => withFileLock(path, () => createSecureModelControlFile(path, contents)),
186
+ writeSecureModelControlFile: (path, contents) => withFileLock(path, () => writeSecureModelControlFile(path, contents)),
187
+ };
147
188
  }
148
- export const { ensureSecureModelControlDirectory, readSecureModelControlFile, createSecureModelControlFile, writeSecureModelControlFile, } = createModelControlFileAccess();
189
+ export const { ensureSecureModelControlDirectory, readSecureModelControlFile, readSecureModelControlFileBuffer, createSecureModelControlFile, writeSecureModelControlFile, } = createModelControlFileAccess();
149
190
  //# sourceMappingURL=model-control-files.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-control-files.js","sourceRoot":"","sources":["../../src/agents/model-control-files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-control-files.js","sourceRoot":"","sources":["../../src/agents/model-control-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /** Metadata only: callers must never log the credential or a derived hash. */
2
+ export declare function inspectModelDeviceSecret(raw: Buffer): {
3
+ bytes: number;
4
+ encoding: string;
5
+ characters: number;
6
+ reason: string;
7
+ valid: boolean;
8
+ };
9
+ export declare function parseModelDeviceSecret(raw: Buffer): string;
10
+ //# sourceMappingURL=model-device-secret.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-device-secret.d.ts","sourceRoot":"","sources":["../../src/agents/model-device-secret.ts"],"names":[],"mappings":"AAwBA,8EAA8E;AAC9E,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM;;;;;;EAOnD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM1D"}
@@ -0,0 +1,47 @@
1
+ const validSecret = (value) => /^[a-f0-9]{64}$/.test(value);
2
+ function decodedSecret(raw) {
3
+ let encoding = 'utf8';
4
+ // Accept UTF-16 only when there is an explicit BOM or an unambiguous ASCII
5
+ // NUL pattern. Never strip arbitrary NULs or repair/rotate corrupt secrets.
6
+ if (raw.length >= 2 && raw[0] === 0xff && raw[1] === 0xfe)
7
+ encoding = 'utf16le';
8
+ else if (raw.length >= 2 && raw[0] === 0xfe && raw[1] === 0xff)
9
+ encoding = 'utf16be';
10
+ else if (raw.length >= 128 && raw.length % 2 === 0) {
11
+ const isAscii16 = (little) => {
12
+ for (let i = 0; i < raw.length; i += 2) {
13
+ if (raw[i + (little ? 1 : 0)] !== 0 || raw[i + (little ? 0 : 1)] > 0x7f)
14
+ return false;
15
+ }
16
+ return true;
17
+ };
18
+ if (isAscii16(true))
19
+ encoding = 'utf16le';
20
+ else if (isAscii16(false))
21
+ encoding = 'utf16be';
22
+ }
23
+ try {
24
+ const label = encoding === 'utf8' ? 'utf-8' : encoding === 'utf16le' ? 'utf-16le' : 'utf-16be';
25
+ return { text: new TextDecoder(label, { fatal: true }).decode(raw).trim(), encoding, validEncoding: true };
26
+ }
27
+ catch {
28
+ return { text: '', encoding, validEncoding: false };
29
+ }
30
+ }
31
+ /** Metadata only: callers must never log the credential or a derived hash. */
32
+ export function inspectModelDeviceSecret(raw) {
33
+ const decoded = decodedSecret(raw);
34
+ const reason = !decoded.validEncoding ? 'invalid_encoding'
35
+ : decoded.text.length === 0 ? 'empty'
36
+ : decoded.text.length !== 64 ? 'invalid_length'
37
+ : !validSecret(decoded.text) ? 'invalid_hex' : 'valid';
38
+ return { bytes: raw.length, encoding: decoded.encoding, characters: decoded.text.length, reason, valid: reason === 'valid' };
39
+ }
40
+ export function parseModelDeviceSecret(raw) {
41
+ const metadata = inspectModelDeviceSecret(raw);
42
+ if (!metadata.valid) {
43
+ throw new Error(`INVALID_MODEL_DEVICE_SECRET: reason=${metadata.reason} bytes=${metadata.bytes} encoding=${metadata.encoding} characters=${metadata.characters}; existing file preserved, no identity reset`);
44
+ }
45
+ return decodedSecret(raw).text;
46
+ }
47
+ //# sourceMappingURL=model-device-secret.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-device-secret.js","sourceRoot":"","sources":["../../src/agents/model-device-secret.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const spawn: typeof import("child_process").spawn;
2
+ //# sourceMappingURL=platform-spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-spawn.d.ts","sourceRoot":"","sources":["../../src/agents/platform-spawn.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,KAAK,sCAAmB,CAAA"}
@@ -0,0 +1,4 @@
1
+ import crossSpawn from 'cross-spawn';
2
+ // Retain Node's overloads/stream types and cross-spawn's Windows shim escaping.
3
+ export const spawn = crossSpawn.spawn;
4
+ //# sourceMappingURL=platform-spawn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-spawn.js","sourceRoot":"","sources":["../../src/agents/platform-spawn.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAA;AAEpC,gFAAgF;AAChF,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ export declare function terminateProcess(pid: number, signal?: NodeJS.Signals, platform?: NodeJS.Platform): Promise<void>;
3
+ export declare function terminateChildProcess(child: ChildProcess): void;
4
+ //# sourceMappingURL=process-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-tree.d.ts","sourceRoot":"","sources":["../../src/agents/process-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGhE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,OAAmB,EAAE,QAAQ,kBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAc5H;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAM/D"}
@@ -0,0 +1,46 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { win32 } from 'node:path';
3
+ export function terminateProcess(pid, signal = 'SIGTERM', platform = process.platform) {
4
+ if (!Number.isSafeInteger(pid) || pid <= 0)
5
+ return Promise.reject(new Error('Invalid owned process id'));
6
+ if (platform !== 'win32') {
7
+ try {
8
+ process.kill(pid, signal);
9
+ return Promise.resolve();
10
+ }
11
+ catch (error) {
12
+ return Promise.reject(error);
13
+ }
14
+ }
15
+ // Node kills only the cmd.exe shim on Windows; taskkill /T also stops the
16
+ // owned CLI descendant. Never pass a process name, wildcard, or a shell.
17
+ return new Promise((resolve, reject) => {
18
+ execFile(win32.join(process.env.SystemRoot || 'C:\\Windows', 'System32', 'taskkill.exe'), ['/PID', String(pid), '/T', '/F'], { windowsHide: true }, error => {
19
+ if (!error) {
20
+ resolve();
21
+ return;
22
+ }
23
+ try {
24
+ process.kill(pid, 0);
25
+ }
26
+ catch (gone) {
27
+ reject(gone);
28
+ return;
29
+ }
30
+ reject(error);
31
+ });
32
+ });
33
+ }
34
+ export function terminateChildProcess(child) {
35
+ if (child.exitCode !== null || child.signalCode !== null)
36
+ return;
37
+ if (process.platform !== 'win32' || !child.pid) {
38
+ child.kill();
39
+ return;
40
+ }
41
+ void terminateProcess(child.pid).catch(() => {
42
+ if (child.exitCode === null && child.signalCode === null)
43
+ child.kill();
44
+ });
45
+ }
46
+ //# sourceMappingURL=process-tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-tree.js","sourceRoot":"","sources":["../../src/agents/process-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAqB,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AAEjC,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,SAAyB,SAAS,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ;IAC3G,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAA;IACxG,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAAC,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAAC,CAAC;IAC5G,CAAC;IACD,0EAA0E;IAC1E,yEAAyE;IACzE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,aAAa,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,EAAE;YAC1J,IAAI,CAAC,KAAK,EAAE,CAAC;gBAAC,OAAO,EAAE,CAAC;gBAAC,OAAM;YAAC,CAAC;YACjC,IAAI,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YAAC,CAAC;YAAC,OAAO,IAAI,EAAE,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAAC,OAAM;YAAC,CAAC;YAClE,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAmB;IACvD,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;QAAE,OAAM;IAChE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAAC,OAAM;IAAC,CAAC;IACxE,KAAK,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QAC1C,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;YAAE,KAAK,CAAC,IAAI,EAAE,CAAA;IACxE,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"trusted-launcher.d.ts","sourceRoot":"","sources":["../../src/agents/trusted-launcher.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CACxB,GAAG,YAAY,CAoBf"}
1
+ {"version":3,"file":"trusted-launcher.d.ts","sourceRoot":"","sources":["../../src/agents/trusted-launcher.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;IACtB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CACxB,GAAG,YAAY,CAuBf"}
@@ -1,17 +1,21 @@
1
1
  import { createHash, randomUUID } from 'node:crypto';
2
- import { basename, relative, resolve } from 'node:path';
2
+ import { basename, relative, resolve, sep } from 'node:path';
3
3
  export function resolveTrustedSpawn(input) {
4
4
  const cwd = resolve(input.cwd ?? process.cwd());
5
5
  const launcherSocket = process.env.RUNTIME_LAUNCHER_SOCKET;
6
6
  if (!launcherSocket) {
7
- return { command: input.command, args: input.args, cwd, env: input.env ?? process.env, shell: process.platform === 'win32' };
7
+ // Consumers use cross-spawn for Windows npm shims. Enabling shell here
8
+ // would bypass its escaping and break paths/user arguments containing spaces.
9
+ return { command: input.command, args: input.args, cwd, env: input.env ?? process.env, shell: false };
8
10
  }
11
+ if (process.platform === 'win32')
12
+ throw new Error('TRUSTED_RUNTIME_LAUNCHER_REQUIRES_LINUX');
9
13
  const profile = profileForCommand(input.command);
10
14
  if (!profile)
11
15
  throw new Error('CLI executable is not authorized by the trusted launcher');
12
16
  const workspace = resolve(process.env.WORKSPACE_ROOT ?? '/workspace');
13
17
  const cwdRel = relative(workspace, cwd) || '.';
14
- if (cwdRel === '..' || cwdRel.startsWith(`..${process.platform === 'win32' ? '\\' : '/'}`)) {
18
+ if (cwdRel === '..' || cwdRel.startsWith(`..${sep}`)) {
15
19
  throw new Error('CLI working directory is outside the trusted workspace');
16
20
  }
17
21
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"trusted-launcher.js","sourceRoot":"","sources":["../../src/agents/trusted-launcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trusted-launcher.js","sourceRoot":"","sources":["../../src/agents/trusted-launcher.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,12 @@
1
1
  export declare function sameWindowsModelControlPath(left: string, right: string): boolean;
2
- export declare function validateWindowsModelControlAcl(value: unknown): void;
3
- export declare function ensureWindowsModelControlSecurity(path: string): Promise<void>;
2
+ export declare function validateWindowsModelControlAcl(value: unknown, kind?: 'directory' | 'file'): void;
3
+ type AclTarget = {
4
+ path: string;
5
+ kind: 'directory' | 'file';
6
+ privateDirectory: boolean;
7
+ };
8
+ /** Coalesce simultaneous checks, never reuse an ACL result or skip a target. */
9
+ export declare function createWindowsModelControlSecurity(runBatch?: (targets: AclTarget[]) => Promise<unknown>): (path: string, kind?: "directory" | "file", privateDirectory?: boolean) => Promise<void>;
10
+ export declare const ensureWindowsModelControlSecurity: (path: string, kind?: "directory" | "file", privateDirectory?: boolean) => Promise<void>;
11
+ export {};
4
12
  //# sourceMappingURL=windows-model-control-security.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"windows-model-control-security.d.ts","sourceRoot":"","sources":["../../src/agents/windows-model-control-security.ts"],"names":[],"mappings":"AAiCA,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAuBnE;AAED,wBAAsB,iCAAiC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBnF"}
1
+ {"version":3,"file":"windows-model-control-security.d.ts","sourceRoot":"","sources":["../../src/agents/windows-model-control-security.ts"],"names":[],"mappings":"AAiHA,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,WAAW,GAAG,MAAe,GAAG,IAAI,CA+BxG;AAED,KAAK,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,CAAA;AAiBxF,gFAAgF;AAChF,wBAAgB,iCAAiC,CAAC,QAAQ,GAAE,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,OAAO,CAAC,OAAO,CAAgB,IAsC3G,MAAM,MAAM,EAAE,OAAM,WAAW,GAAG,MAAe,EAAE,0BAAwB,KAAG,OAAO,CAAC,IAAI,CAAC,CAQpG;AAED,eAAO,MAAM,iCAAiC,SAV9B,MAAM,SAAQ,WAAW,GAAG,MAAM,iCAAsC,OAAO,CAAC,IAAI,CAUhB,CAAA"}
@@ -6,14 +6,78 @@ const TRUSTED_SYSTEM_SIDS = new Set(['S-1-5-18', 'S-1-5-32-544']); // SYSTEM, Ad
6
6
  // Use SIDs rather than localized account names. Inspect inherited ACEs too; a
7
7
  // Unix mode returned by stat on Windows says nothing about the actual DACL.
8
8
  const INSPECT_ACL = `
9
+ function Inspect-ControlAcl($target, $kind, $privateDirectory) {
9
10
  $ErrorActionPreference = 'Stop'
10
- $item = Get-Item -LiteralPath $env:AGENTS_BRIDGE_ACL_TARGET -Force
11
+ $ProgressPreference = 'SilentlyContinue'
12
+ [Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
13
+ $item = Get-Item -LiteralPath $target -Force
11
14
  $cursor = $item
12
15
  while ($null -ne $cursor) {
13
16
  if (($cursor.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw 'MODEL_CONTROL_REPARSE_POINT' }
14
17
  if ($cursor -is [IO.DirectoryInfo]) { $cursor = $cursor.Parent } else { $cursor = $cursor.Directory }
15
18
  }
16
- $acl = Get-Acl -LiteralPath $env:AGENTS_BRIDGE_ACL_TARGET
19
+ $acl = $item.GetAccessControl([Security.AccessControl.AccessControlSections]'Access,Owner,Group')
20
+ $current = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
21
+ $owner = $acl.GetOwner([Security.Principal.SecurityIdentifier]).Value
22
+ function Set-PrivateControlAccess($existing, $kind) {
23
+ # Rebuild only the Access section: preserve owner/group/audit unchanged.
24
+ # preserveInheritance=true retains inherited ACEs in memory, so deleting
25
+ # only explicit Allow entries cannot reliably privatize an inherited DACL.
26
+ if ($kind -eq 'directory') {
27
+ $private = [Security.AccessControl.DirectorySecurity]::new()
28
+ $inheritance = [Security.AccessControl.InheritanceFlags]'ContainerInherit,ObjectInherit'
29
+ } else {
30
+ $private = [Security.AccessControl.FileSecurity]::new()
31
+ $inheritance = [Security.AccessControl.InheritanceFlags]::None
32
+ }
33
+ $private.SetAccessRuleProtection($true, $false)
34
+ foreach ($rule in @($existing.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier]))) {
35
+ if ($rule.AccessControlType -eq [Security.AccessControl.AccessControlType]::Deny) {
36
+ # Materialize inherited denies as explicit rules with the exact access
37
+ # mask and propagation flags. AccessRuleFactory avoids constructor mask
38
+ # normalization (notably Synchronize on Deny rules).
39
+ $deny = $private.AccessRuleFactory($rule.IdentityReference, [int]$rule.FileSystemRights, $false, $rule.InheritanceFlags, $rule.PropagationFlags, [Security.AccessControl.AccessControlType]::Deny)
40
+ [void]$private.AddAccessRule($deny)
41
+ }
42
+ }
43
+ foreach ($sid in @($current, 'S-1-5-18', 'S-1-5-32-544')) {
44
+ $identity = [Security.Principal.SecurityIdentifier]::new($sid)
45
+ $rule = [Security.AccessControl.FileSystemAccessRule]::new($identity, [Security.AccessControl.FileSystemRights]::FullControl, $inheritance, [Security.AccessControl.PropagationFlags]::None, [Security.AccessControl.AccessControlType]::Allow)
46
+ [void]$private.AddAccessRule($rule)
47
+ }
48
+ # Persist the fresh object directly: only AccessRulesModified is set.
49
+ # Set-Acl copies a complete descriptor and can request SeSecurityPrivilege
50
+ # even when this operation only needs WRITE_DAC on our own state directory.
51
+ $item.SetAccessControl($private)
52
+ }
53
+ $repairAttempted = $false
54
+ if ($kind -eq 'directory' -and $privateDirectory -eq $true) {
55
+ # The caller opts in only for a direct Agent state directory under this
56
+ # Bridge's agents root. Never repair arbitrary parents or workspaces.
57
+ if ($item -isnot [IO.DirectoryInfo]) { throw 'MODEL_CONTROL_INVALID_DIRECTORY' }
58
+ $needsPrivacy = $false
59
+ foreach ($rule in @($acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier]))) {
60
+ if ($rule.AccessControlType -eq [Security.AccessControl.AccessControlType]::Allow -and $rule.IdentityReference.Value -notin @($current, 'S-1-5-18', 'S-1-5-32-544') -and ($rule.PropagationFlags -band [Security.AccessControl.PropagationFlags]::InheritOnly) -eq 0 -and (([long]$rule.FileSystemRights -band 4294967295) -band 1609432918) -ne 0) { $needsPrivacy = $true }
61
+ }
62
+ if ($needsPrivacy) {
63
+ if ($owner -ne $current) { throw 'MODEL_CONTROL_UNTRUSTED_DIRECTORY_OWNER' }
64
+ $repairAttempted = $true
65
+ Set-PrivateControlAccess $acl 'directory'
66
+ $acl = $item.GetAccessControl([Security.AccessControl.AccessControlSections]'Access,Owner,Group')
67
+ }
68
+ }
69
+ if ($kind -eq 'file') {
70
+ if ($item -isnot [IO.FileInfo] -or $owner -notin @($current, 'S-1-5-18', 'S-1-5-32-544')) { throw 'MODEL_CONTROL_UNTRUSTED_OWNER' }
71
+ $needsPrivacy = $false
72
+ foreach ($rule in @($acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier]))) {
73
+ if ($rule.AccessControlType -eq [Security.AccessControl.AccessControlType]::Allow -and $rule.IdentityReference.Value -notin @($current, 'S-1-5-18', 'S-1-5-32-544') -and [long]$rule.FileSystemRights -ne 0) { $needsPrivacy = $true }
74
+ }
75
+ if ($needsPrivacy) {
76
+ $repairAttempted = $true
77
+ Set-PrivateControlAccess $acl 'file'
78
+ $acl = $item.GetAccessControl([Security.AccessControl.AccessControlSections]'Access,Owner,Group')
79
+ }
80
+ }
17
81
  $rules = @($acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier]) | ForEach-Object {
18
82
  @{
19
83
  sid = $_.IdentityReference.Value
@@ -26,13 +90,29 @@ $rules = @($acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentif
26
90
  currentSid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
27
91
  ownerSid = $acl.GetOwner([Security.Principal.SecurityIdentifier]).Value
28
92
  rules = $rules
29
- } | ConvertTo-Json -Depth 4 -Compress
93
+ repairAttempted = $repairAttempted
94
+ }
95
+ }
96
+ $ErrorActionPreference = 'Stop'
97
+ $ProgressPreference = 'SilentlyContinue'
98
+ [Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)
99
+ $requests = @(ConvertFrom-Json -InputObject $env:AGENTS_BRIDGE_ACL_REQUESTS)
100
+ $results = @(foreach ($request in $requests) {
101
+ try {
102
+ $snapshot = Inspect-ControlAcl $request.path $request.kind $request.privateDirectory
103
+ @{ index = $request.index; ok = $true; snapshot = $snapshot }
104
+ } catch {
105
+ # Only the Node side's fixed marker allowlist may reach logs.
106
+ @{ index = $request.index; ok = $false; error = $_.Exception.Message }
107
+ }
108
+ })
109
+ ConvertTo-Json -InputObject $results -Depth 8 -Compress
30
110
  `;
31
111
  export function sameWindowsModelControlPath(left, right) {
32
112
  return win32.normalize(left).toLowerCase() === win32.normalize(right).toLowerCase();
33
113
  }
34
- export function validateWindowsModelControlAcl(value) {
35
- const invalid = () => new Error('INSECURE_MODEL_CONTROL_WINDOWS_ACL');
114
+ export function validateWindowsModelControlAcl(value, kind = 'file') {
115
+ const invalid = (detail = 'invalid ACL data') => new Error(`INSECURE_MODEL_CONTROL_WINDOWS_ACL: ${kind}: ${detail}`);
36
116
  if (!value || typeof value !== 'object')
37
117
  throw invalid();
38
118
  const acl = value;
@@ -41,7 +121,7 @@ export function validateWindowsModelControlAcl(value) {
41
121
  throw invalid();
42
122
  const trusted = new Set([acl.currentSid, ...TRUSTED_SYSTEM_SIDS]);
43
123
  if (!trusted.has(acl.ownerSid))
44
- throw invalid();
124
+ throw invalid(`untrusted owner ${acl.ownerSid}`);
45
125
  let effectiveAllow = false;
46
126
  for (const entry of acl.rules) {
47
127
  if (!entry || typeof entry !== 'object')
@@ -49,13 +129,21 @@ export function validateWindowsModelControlAcl(value) {
49
129
  const rule = entry;
50
130
  if (typeof rule.sid !== 'string' || typeof rule.allow !== 'boolean'
51
131
  || typeof rule.inheritOnly !== 'boolean' || typeof rule.rights !== 'number'
52
- || !Number.isSafeInteger(rule.rights) || rule.rights < 0)
132
+ || !Number.isSafeInteger(rule.rights) || rule.rights < -0x80000000 || rule.rights > 0xffffffff)
53
133
  throw invalid();
54
134
  if (!rule.allow || rule.rights === 0)
55
135
  continue;
56
136
  // Inherit-only grants still expose newly created state/temporary files.
57
- if (!trusted.has(rule.sid) && !(rule.sid === 'S-1-3-0' && rule.inheritOnly))
58
- throw invalid();
137
+ if (!trusted.has(rule.sid) && !(rule.sid === 'S-1-3-0' && rule.inheritOnly)) {
138
+ // Match the POSIX directory policy: listing/traversal is safe; creating,
139
+ // replacing, deleting or changing permissions is not. Inherited file
140
+ // grants are removed by the private-file policy before accessing bytes.
141
+ // ReadData/ReadEA/Execute/ReadAttributes/ReadControl/Synchronize plus
142
+ // GenericRead/GenericExecute. Reject unknown rights as well as writes.
143
+ const outsideReadRights = (rule.rights >>> 0) & ~0xa01200a9;
144
+ if (kind === 'file' || (!rule.inheritOnly && outsideReadRights !== 0))
145
+ throw invalid(`unsafe allow ${rule.sid} rights=${rule.rights}`);
146
+ }
59
147
  if (!rule.inheritOnly)
60
148
  effectiveAllow = true;
61
149
  }
@@ -64,23 +152,70 @@ export function validateWindowsModelControlAcl(value) {
64
152
  if (!effectiveAllow)
65
153
  throw invalid();
66
154
  }
67
- export async function ensureWindowsModelControlSecurity(path) {
155
+ const unavailable = () => new Error('MODEL_CONTROL_WINDOWS_ACL_UNAVAILABLE: Windows PowerShell ACL inspection failed');
156
+ const SAFE_MARKERS = ['MODEL_CONTROL_UNTRUSTED_DIRECTORY_OWNER', 'MODEL_CONTROL_UNTRUSTED_OWNER', 'MODEL_CONTROL_REPARSE_POINT', 'MODEL_CONTROL_INVALID_DIRECTORY'];
157
+ async function inspectBatch(targets) {
68
158
  const executable = win32.join(process.env.SystemRoot || 'C:\\Windows', 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe');
69
- let snapshot;
70
- try {
71
- const { stdout } = await execute(executable, [
72
- '-NoLogo', '-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(INSPECT_ACL, 'utf16le').toString('base64'),
73
- ], {
74
- env: { ...process.env, AGENTS_BRIDGE_ACL_TARGET: path },
75
- windowsHide: true, timeout: 10_000, maxBuffer: 128 * 1024,
76
- });
77
- snapshot = JSON.parse(stdout.replace(/^\uFEFF/, '').trim());
78
- }
79
- catch {
80
- // Do not include shell output, environment, or a control-file path in logs.
81
- // Fail closed if PowerShell/ACL inspection is unavailable.
82
- throw new Error('MODEL_CONTROL_WINDOWS_ACL_UNAVAILABLE: Windows PowerShell ACL inspection failed');
159
+ const { stdout } = await execute(executable, [
160
+ '-NoLogo', '-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(INSPECT_ACL, 'utf16le').toString('base64'),
161
+ ], {
162
+ env: { ...process.env, AGENTS_BRIDGE_ACL_REQUESTS: JSON.stringify(targets.map((target, index) => ({ ...target, index }))) },
163
+ // One short-lived process, at most three independently checked targets.
164
+ windowsHide: true, timeout: 10_000 * targets.length, maxBuffer: 384 * 1024,
165
+ });
166
+ return JSON.parse(stdout.replace(/^\uFEFF/, '').trim());
167
+ }
168
+ /** Coalesce simultaneous checks, never reuse an ACL result or skip a target. */
169
+ export function createWindowsModelControlSecurity(runBatch = inspectBatch) {
170
+ const queue = [];
171
+ let draining = false;
172
+ async function drain() {
173
+ while (queue.length) {
174
+ // Filesystem callbacks for three Agents need not arrive in the same
175
+ // event-loop turn. A bounded10ms collection window amortizes process
176
+ // startup without caching results or waiting indefinitely for peers.
177
+ if (queue.length < 3)
178
+ await new Promise(resolve => setTimeout(resolve, 10));
179
+ const batch = queue.splice(0, 3);
180
+ try {
181
+ const raw = await runBatch(batch.map(({ path, kind, privateDirectory }) => ({ path, kind, privateDirectory })));
182
+ // Validate correlation/completeness before settling any request.
183
+ if (!Array.isArray(raw) || raw.length !== batch.length || raw.some((entry, index) => !entry || entry.index !== index || typeof entry.ok !== 'boolean' ||
184
+ (!entry.ok && typeof entry.error !== 'string')))
185
+ throw unavailable();
186
+ const results = raw;
187
+ batch.forEach((target, index) => {
188
+ const result = results[index];
189
+ if (!result.ok) {
190
+ const marker = SAFE_MARKERS.find(marker => result.error.includes(marker));
191
+ target.reject(marker ? new Error(marker) : unavailable());
192
+ return;
193
+ }
194
+ try {
195
+ validateWindowsModelControlAcl(result.snapshot, target.kind);
196
+ target.resolve();
197
+ }
198
+ catch (error) {
199
+ const attempted = result.snapshot?.repairAttempted === true;
200
+ target.reject(new Error(`${error.message}; privateDirectory=${target.privateDirectory} repairAttempted=${attempted}`));
201
+ }
202
+ });
203
+ }
204
+ catch {
205
+ // Never surface shell output, paths, environment or credentials.
206
+ batch.forEach(target => target.reject(unavailable()));
207
+ }
208
+ }
209
+ draining = false;
83
210
  }
84
- validateWindowsModelControlAcl(snapshot);
211
+ return (path, kind = 'file', privateDirectory = false) => new Promise((resolve, reject) => {
212
+ queue.push({ path, kind, privateDirectory, resolve, reject });
213
+ if (!draining) {
214
+ draining = true;
215
+ // Only one bounded PowerShell process is active at a time.
216
+ setImmediate(() => { void drain(); });
217
+ }
218
+ });
85
219
  }
220
+ export const ensureWindowsModelControlSecurity = createWindowsModelControlSecurity();
86
221
  //# sourceMappingURL=windows-model-control-security.js.map