@orcareplay/core 0.3.1-main.g2d7bd68 → 0.4.0

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/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './blobs.js';
2
2
  export * from './fetch.js';
3
3
  export * from './graph.js';
4
4
  export * from './paths.js';
5
+ export * from './private-files.js';
5
6
  export * from './reader.js';
6
7
  export * from './redaction.js';
7
8
  export * from './writer.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export * from './blobs.js';
2
2
  export * from './fetch.js';
3
3
  export * from './graph.js';
4
4
  export * from './paths.js';
5
+ export * from './private-files.js';
5
6
  export * from './reader.js';
6
7
  export * from './redaction.js';
7
8
  export * from './writer.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYhE;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5D;AA6BD,yDAAyD;AACzD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAc7D;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAevF"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8ChE;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5D;AA6BD,yDAAyD;AACzD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAc7D;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAevF"}
package/dist/paths.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import { RUN_ID_PATTERN } from '@orcareplay/schema';
4
+ import { assertPrivatePathIdentity, privatePathIdentity, restrictToOwner, } from './private-files.js';
4
5
  export function orcaDir(cwd) {
5
6
  return join(cwd, '.orca');
6
7
  }
@@ -23,8 +24,41 @@ export function runsDir(cwd) {
23
24
  */
24
25
  export async function ensureRunsDir(cwd) {
25
26
  const dir = runsDir(cwd);
26
- await mkdir(dir, { recursive: true, mode: 0o700 });
27
- const ignore = join(orcaDir(cwd), '.gitignore');
27
+ const orca = orcaDir(cwd);
28
+ if (process.platform === 'win32') {
29
+ // Secure the container before creating the store inside it. Ownership is checked as well:
30
+ // removing a foreign owner's ACE alone would leave it able to restore its own access.
31
+ await mkdir(orca, { recursive: true, mode: 0o700 });
32
+ const orcaWas = await privatePathIdentity(orca);
33
+ await restrictToOwner(orca, 0o700);
34
+ await assertPrivatePathIdentity(orca, orcaWas);
35
+ await mkdir(dir, { recursive: true, mode: 0o700 });
36
+ // Check again after making the container non-empty. These checks detect replacement during
37
+ // setup; they do not lock ancestors against an account that can keep replacing them later.
38
+ await assertPrivatePathIdentity(orca, orcaWas);
39
+ const dirWas = await privatePathIdentity(dir);
40
+ await restrictToOwner(dir, 0o700);
41
+ await assertPrivatePathIdentity(dir, dirWas);
42
+ }
43
+ else {
44
+ // POSIX, unchanged: only when this call created it, which is what passing `mode` to mkdir
45
+ // already meant. Every file beneath gets its own 0600 from the writer regardless, so the
46
+ // directory's mode is not load-bearing, and one the user has deliberately opened up is theirs
47
+ // to have opened up. `chmod` follows a symlink here, and pointing a store at another disk is
48
+ // an ordinary thing to do, so there is no link check either.
49
+ const created = (await mkdir(dir, { recursive: true, mode: 0o700 })) !== undefined;
50
+ // Swallowed, the way `sync.ts` swallows the same call three times over. `mkdir`'s mode is a
51
+ // request a filesystem without permissions ignores; `chmod` on that same filesystem fails. And
52
+ // `ensureRunsDir` is the first thing `record`, `attach`, `replay`, `pull` and `quickstart` all
53
+ // do, so making it fatal would abort every one of them on an exFAT or vfat workspace that
54
+ // worked before. What it buys is narrow enough to be worth losing there: umask can only clear
55
+ // bits, so `mkdir(0o700)` is already at most 0700 and this only restores what an exotic one
56
+ // took away. On Windows, where the mode is discarded and the ACL is the whole protection, the
57
+ // branch above stays fatal.
58
+ if (created)
59
+ await restrictToOwner(dir, 0o700).catch(() => undefined);
60
+ }
61
+ const ignore = join(orca, '.gitignore');
28
62
  if (!(await stat(ignore).catch(() => null))) {
29
63
  await writeFile(ignore, '# Recordings hold source, shell output and workspace snapshots. Not for committing.\n*\n', { mode: 0o600, flag: 'wx' }).catch(() => undefined);
30
64
  }
package/dist/paths.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Keep a path to its owner — in the currency the filesystem actually has.
3
+ *
4
+ * `chmod(path, 0o600)` on Windows sets the read-only attribute and nothing else. The mode bits are
5
+ * a POSIX idea; what the file really gets is the ACL it inherits from wherever it was written, and
6
+ * under a workspace on `C:\` that is:
7
+ *
8
+ * ```
9
+ * NT AUTHORITY\Authenticated Users:(I)(M) ← any authenticated account may rewrite it
10
+ * BUILTIN\Users:(I)(RX) ← any local account may read it
11
+ * ```
12
+ *
13
+ * For a trace that is bad. For the run CA's private key it is the whole point of the feature
14
+ * undone: that key signs the certificates the agent has been told to trust for the life of the
15
+ * run, so whoever reads it can impersonate every intercepted host to that agent, and whoever
16
+ * writes it can substitute a CA of their own. For `config.json` it is a gateway API key sitting
17
+ * in a file the machine can read.
18
+ *
19
+ * So on Windows the promise is kept with an ACL: everything already on it is taken away — the
20
+ * inherited entries and the explicit ones alike — and the only trustees left are the owner,
21
+ * SYSTEM and Administrators. That is the rule OpenSSH for Windows enforces on its
22
+ * own private keys, and it is the closest the platform comes to 0600 — under which root can still
23
+ * read the file too.
24
+ *
25
+ * Callers keep whatever error policy they had: this throws where `chmod` threw.
26
+ */
27
+ export declare function restrictToOwner(path: string, mode: 0o600 | 0o700): Promise<void>;
28
+ /** The entry itself, without following a junction; bigint preserves the complete NTFS file ID. */
29
+ export interface PrivatePathIdentity {
30
+ dev: bigint;
31
+ ino: bigint;
32
+ }
33
+ export declare function privatePathIdentity(path: string): Promise<PrivatePathIdentity>;
34
+ export declare function assertPrivatePathIdentity(path: string, was: PrivatePathIdentity): Promise<void>;
35
+ /** Never recursively clean up a replacement belonging to somebody else. */
36
+ export declare function removePrivateDirectory(path: string, was: PrivatePathIdentity): Promise<void>;
37
+ //# sourceMappingURL=private-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-files.d.ts","sourceRoot":"","sources":["../src/private-files.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDtF;AAED,kGAAkG;AAClG,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAKpF;AAED,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,2EAA2E;AAC3E,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,IAAI,CAAC,CAOf"}
@@ -0,0 +1,349 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { randomBytes } from 'node:crypto';
3
+ import { lstatSync, rmSync } from 'node:fs';
4
+ import { chmod, lstat, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
5
+ import { tmpdir } from 'node:os';
6
+ import { isAbsolute, join } from 'node:path';
7
+ import { promisify } from 'node:util';
8
+ const run = promisify(execFile);
9
+ /**
10
+ * Keep a path to its owner — in the currency the filesystem actually has.
11
+ *
12
+ * `chmod(path, 0o600)` on Windows sets the read-only attribute and nothing else. The mode bits are
13
+ * a POSIX idea; what the file really gets is the ACL it inherits from wherever it was written, and
14
+ * under a workspace on `C:\` that is:
15
+ *
16
+ * ```
17
+ * NT AUTHORITY\Authenticated Users:(I)(M) ← any authenticated account may rewrite it
18
+ * BUILTIN\Users:(I)(RX) ← any local account may read it
19
+ * ```
20
+ *
21
+ * For a trace that is bad. For the run CA's private key it is the whole point of the feature
22
+ * undone: that key signs the certificates the agent has been told to trust for the life of the
23
+ * run, so whoever reads it can impersonate every intercepted host to that agent, and whoever
24
+ * writes it can substitute a CA of their own. For `config.json` it is a gateway API key sitting
25
+ * in a file the machine can read.
26
+ *
27
+ * So on Windows the promise is kept with an ACL: everything already on it is taken away — the
28
+ * inherited entries and the explicit ones alike — and the only trustees left are the owner,
29
+ * SYSTEM and Administrators. That is the rule OpenSSH for Windows enforces on its
30
+ * own private keys, and it is the closest the platform comes to 0600 — under which root can still
31
+ * read the file too.
32
+ *
33
+ * Callers keep whatever error policy they had: this throws where `chmod` threw.
34
+ */
35
+ export async function restrictToOwner(path, mode) {
36
+ if (process.platform !== 'win32') {
37
+ await chmod(path, mode);
38
+ return;
39
+ }
40
+ const icacls = system32('icacls.exe');
41
+ const inherit = mode === 0o700 ? '(OI)(CI)' : '';
42
+ const was = await privatePathIdentity(path);
43
+ // Finish the ownership and descriptor lookups before changing permissions. A lookup failure
44
+ // leaves the original ACL intact; a verification failure below refuses to use the narrowed path.
45
+ const keep = [await currentAccountSid(), SYSTEM, ADMINISTRATORS];
46
+ const ours = await requireTrustedOwner(path, keep);
47
+ await assertPrivatePathIdentity(path, was);
48
+ const foreign = (await explicitTrustees(icacls, path)).filter((trustee) => !ours.has(trustee));
49
+ // One invocation, and every part of it narrows.
50
+ //
51
+ // `/inheritance:r` removes only the ACEs carrying the inherited flag, and `/grant:r` replaces
52
+ // previously granted explicit permissions *for the trustees it names* — so an explicit ACE for
53
+ // anybody else survives both, keeping its `(OI)(CI)` on a directory and passing itself to
54
+ // everything written afterwards. Measured: grant BUILTIN\Users explicitly, then restrict, and
55
+ // `(A;;FA;;;BU)` is still on the DACL. "Replace all child object permissions" turns inherited
56
+ // ACEs into explicit ones, and so do `robocopy /SEC` and a tree carried between machines, so
57
+ // this is an ordinary shape rather than an exotic one. Hence naming them for removal.
58
+ //
59
+ // `/reset` would be the obvious way to clear them and is the wrong one: it replaces the DACL
60
+ // with whatever the *parent* hands down, so between it and the grant the path holds the
61
+ // parent's ACL — and a parent is not something this function gets to assume anything about. On
62
+ // every Windows command the store root would spend that window readable by whoever the
63
+ // workspace allowed, and anything created inside it would keep that permanently, since icacls
64
+ // does not re-propagate to children later. Measured too, on a real store.
65
+ await run(icacls, [
66
+ path,
67
+ '/inheritance:r',
68
+ ...foreign.flatMap((trustee) => ['/remove', `*${trustee}`]),
69
+ '/grant:r',
70
+ ...grantsFor(keep, inherit),
71
+ '/q',
72
+ ]);
73
+ // And then read it back, because everything above rests on having understood a descriptor that
74
+ // this file's own parser has now been wrong about twice. The check is deliberately not that
75
+ // parser: it matches the whole descriptor, anchored, against the shape this function writes, so
76
+ // an ACE of a type nobody anticipated fails it rather than being skipped by it.
77
+ //
78
+ // Nothing is escaped into the pattern because nothing needs to be — a trustee here is a SID or
79
+ // one of SDDL's two-letter abbreviations, and both are `[A-Za-z0-9-]`.
80
+ const written = await descriptorOf(icacls, path);
81
+ if (!asWritten(ours).test(written)) {
82
+ throw new Error(`the ACL orca wrote to ${path} is not the one it asked for: ${JSON.stringify(written)}`);
83
+ }
84
+ await assertPrivatePathIdentity(path, was);
85
+ }
86
+ export async function privatePathIdentity(path) {
87
+ const entry = await lstat(path, { bigint: true });
88
+ if (entry.isSymbolicLink())
89
+ throw new Error(`${path} is a link, refusing to secure its target`);
90
+ if (entry.ino === 0n)
91
+ throw new Error(`${path} has no usable file identity`);
92
+ return { dev: entry.dev, ino: entry.ino };
93
+ }
94
+ export async function assertPrivatePathIdentity(path, was) {
95
+ const now = await privatePathIdentity(path);
96
+ if (now.dev !== was.dev || now.ino !== was.ino) {
97
+ throw new Error(`${path} was replaced while orca was securing it`);
98
+ }
99
+ }
100
+ /** Never recursively clean up a replacement belonging to somebody else. */
101
+ export async function removePrivateDirectory(path, was) {
102
+ try {
103
+ await assertPrivatePathIdentity(path, was);
104
+ await rm(path, { recursive: true, force: true });
105
+ }
106
+ catch {
107
+ // A missing or substituted entry is no longer ours to remove.
108
+ }
109
+ }
110
+ /**
111
+ * A foreign owner retains WRITE_DAC even after its last ACE is removed. Read the actual owner,
112
+ * not the DACL's trustees. Windows PowerShell's .NET API works without Get-Acl/module autoload,
113
+ * elevation, or localized account names. The path is data in the child environment, never code.
114
+ */
115
+ async function requireTrustedOwner(path, trusted) {
116
+ const script = `
117
+ $ErrorActionPreference = 'Stop'
118
+ $acl = [System.IO.File]::GetAccessControl($env:ORCA_PRIVATE_PATH, [System.Security.AccessControl.AccessControlSections]::Owner)
119
+ $acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value
120
+ $descriptor = [System.Security.AccessControl.RawSecurityDescriptor]::new('D:(A;;FA;;;' + $env:ORCA_PRIVATE_SID + ')')
121
+ $descriptor.GetSddlForm([System.Security.AccessControl.AccessControlSections]::Access)
122
+ `;
123
+ const { stdout } = await run(system32('WindowsPowerShell/v1.0/powershell.exe'), [
124
+ '-NoLogo',
125
+ '-NoProfile',
126
+ '-NonInteractive',
127
+ '-EncodedCommand',
128
+ Buffer.from(script, 'utf16le').toString('base64'),
129
+ ], {
130
+ env: { ...process.env, ORCA_PRIVATE_PATH: path, ORCA_PRIVATE_SID: trusted[0] },
131
+ windowsHide: true,
132
+ });
133
+ const [owner = '', accountDescriptor = ''] = stdout.trim().split(/\r?\n/);
134
+ if (!trusted.includes(owner)) {
135
+ throw new Error(`${path} has an untrusted owner (${owner}); refusing to store private data`);
136
+ }
137
+ // Windows may serialize the current account as an abbreviation, e.g. LA for the built-in
138
+ // Administrator. Ask Windows for this SID's spelling; accepting LA for every user would grant
139
+ // trust to a different account, and guessing from an RID alone would confuse local/domain SIDs.
140
+ const spelling = /^D:\(A;;FA;;;([A-Z]{2}|S-1-[\d-]+)\)$/.exec(accountDescriptor)?.[1];
141
+ if (!spelling)
142
+ throw new Error(`could not read the SDDL spelling of ${trusted[0]}`);
143
+ return new Set([...trusted, 'SY', 'BA', spelling]);
144
+ }
145
+ /**
146
+ * The grants a narrowing asks for, and the shape its result has to come back in.
147
+ *
148
+ * Shared by `restrictToOwner` and `aclScratch` because they are the same job and drifted apart
149
+ * once already: the second was written with `/inheritance:r` and `/grant:r` and neither the
150
+ * read-back nor the reasoning eighty lines above about why exiting 0 is not an answer.
151
+ *
152
+ * Nothing is escaped into the pattern because nothing needs to be — a trustee here is a SID or one
153
+ * of SDDL's two-letter abbreviations, and both are `[A-Za-z0-9-]`.
154
+ */
155
+ function grantsFor(trustees, inherit) {
156
+ return trustees.map((sid) => `*${sid}:${inherit}(F)`);
157
+ }
158
+ function asWritten(trustees) {
159
+ return new RegExp('^D:[A-Z]*P[A-Z]*(?:\\(A;[A-Z]*;[^;]*;;;(?:' + [...trustees].join('|') + ')\\))+$');
160
+ }
161
+ /**
162
+ * Who a path grants or denies *explicitly*, in whatever spelling icacls itself uses.
163
+ *
164
+ * Explicit only, because the inherited ones are already `/inheritance:r`'s job — and naming one of
165
+ * those alongside it fails the whole invocation. A directory under `%TEMP%` here carries inherited
166
+ * ACEs for accounts that no longer exist, and `/remove` on such a SID after inheritance has been
167
+ * stripped cannot map it to a name: `icacls … /inheritance:r /remove *<orphan>` exits 1332 and
168
+ * applies nothing. Removing only what `/inheritance:r` will leave behind avoids that by being the
169
+ * more accurate thing to ask for.
170
+ *
171
+ * As SDDL, via `/save`, because the names `icacls <path>` prints are localized. Returned verbatim
172
+ * rather than expanded to SIDs: `/remove` accepts `*BU` as readily as `*S-1-5-32-545`, and a
173
+ * lookup table of well-known abbreviations would silently pass through any entry it had missed —
174
+ * which for this function means a trustee that keeps its access.
175
+ */
176
+ async function explicitTrustees(icacls, path) {
177
+ const descriptor = await descriptorOf(icacls, path);
178
+ // (type;flags;rights;object_guid;inherit_object_guid;trustee[;condition]) — `ID` in the flags
179
+ // marks it inherited. The type is read as a field rather than as one character: `XA`/`XD` are
180
+ // conditional ACEs, `OA`/`OD` object ones, `AU`/`AL` audits, and a single-character type class
181
+ // matched none of them. The trustee stops at `;` as well as `)`, because a conditional ACE
182
+ // carries its expression after the trustee.
183
+ const aces = [...descriptor.matchAll(/\(([^;]*);([^;]*);[^;]*;[^;]*;[^;]*;([^;)]+)/g)];
184
+ return [...new Set(aces.filter((ace) => !ace[2].includes('ID')).map((ace) => ace[3]))];
185
+ }
186
+ /** The path's security descriptor, as SDDL. */
187
+ async function descriptorOf(icacls, path) {
188
+ const saved = join(await aclScratch(icacls), randomBytes(8).toString('hex'));
189
+ try {
190
+ await run(icacls, [path, '/save', saved]);
191
+ return await readDescriptor(saved, path);
192
+ }
193
+ finally {
194
+ await rm(saved, { force: true }).catch(() => undefined);
195
+ }
196
+ }
197
+ /**
198
+ * The descriptor out of what `icacls /save` wrote.
199
+ *
200
+ * UTF-16LE, and the descriptor is the last line: two lines for an ordinary path — the entry's
201
+ * name, then its descriptor — and one for a path with no name to give, such as a drive root.
202
+ *
203
+ * By position rather than by scanning for a `D:` prefix. A name line cannot carry one today, since
204
+ * `/save` writes the basename and a Windows filename cannot contain a colon, but that is a fact
205
+ * about a neighbouring tool rather than about this parse.
206
+ */
207
+ async function readDescriptor(saved, path) {
208
+ const lines = (await readFile(saved, 'utf16le'))
209
+ .split(/\r?\n/)
210
+ .map((line) => line.trim())
211
+ .filter(Boolean);
212
+ const descriptor = lines.at(-1) ?? '';
213
+ // Refused rather than read as "nothing to remove", which is what an unrecognised line would
214
+ // silently mean: every foreign trustee left in place, and `icacls` still exiting 0.
215
+ if (!/^[OGDS]:/.test(descriptor) || !descriptor.includes('(')) {
216
+ throw new Error(`could not read the ACL of ${path}: ${JSON.stringify(descriptor.slice(0, 80))}`);
217
+ }
218
+ return descriptor;
219
+ }
220
+ let scratch;
221
+ /**
222
+ * Somewhere private to write the descriptors this file reads back.
223
+ *
224
+ * `mkdtemp` discards its mode on Windows, so a scratch directory under `%TEMP%` takes whatever
225
+ * that hands down — measured here: two further local accounts, both with inheritable Modify. Every
226
+ * other temporary directory this feature mints is narrowed the moment it exists, and this one was
227
+ * not, which matters more rather than less: the file written into it is the *input to both halves
228
+ * of the only guard this function has* — the descriptor `explicitTrustees` decides the `/remove`
229
+ * list from, and the descriptor the read-back check compares against what was asked for.
230
+ * Substituting it hides a foreign trustee from the first and satisfies the second.
231
+ *
232
+ * Narrowed directly rather than through `restrictToOwner`, which reads a descriptor, which is read
233
+ * from here — that would recurse. `execFile` rejects on a non-zero exit, so a narrowing that did
234
+ * not apply is a throw rather than a descriptor read out of a directory anyone can write.
235
+ *
236
+ * One per process, with a random filename per call, so the cost is a single extra `icacls` for the
237
+ * life of the run rather than two on every path narrowed.
238
+ */
239
+ async function aclScratch(icacls) {
240
+ scratch ??= (async () => {
241
+ const keep = [await currentAccountSid(), SYSTEM, ADMINISTRATORS];
242
+ const dir = await mkdtemp(join(tmpdir(), 'orca-acl-'));
243
+ let was;
244
+ try {
245
+ was = await privatePathIdentity(dir);
246
+ const ours = await requireTrustedOwner(dir, keep);
247
+ await assertPrivatePathIdentity(dir, was);
248
+ // `mkdtemp` just made this, so it carries no explicit ACE to remove — measured: five, every
249
+ // one flagged inherited — and it cannot be a link. What it *can* be is swapped, in the gap
250
+ // between that call and this one, by an account with Modify on `%TEMP%`, which is the ACL
251
+ // measured here. `icacls` does not follow a reparse point, so the narrowing would land on
252
+ // the junction while every descriptor this module reads came out of the other directory.
253
+ // So it is vouched for and re-checked either side, exactly as `ensureRunsDir` does it.
254
+ await run(icacls, [dir, '/inheritance:r', '/grant:r', ...grantsFor(keep, '(OI)(CI)'), '/q']);
255
+ await assertPrivatePathIdentity(dir, was);
256
+ // Keep the directory non-empty between descriptor reads, so an empty-directory removal
257
+ // cannot replace it after setup. Recheck after this write too. As SECURITY.md explains,
258
+ // this is not a defense against arbitrary replacement of writable ancestors.
259
+ await writeFile(join(dir, 'in-use'), String(process.pid), { mode: 0o600, flag: 'wx' });
260
+ await assertPrivatePathIdentity(dir, was);
261
+ // And read back what was written, for the reason the sibling gives: `execFile` reports that
262
+ // icacls exited 0 and nothing more. Read straight rather than through `descriptorOf`, which
263
+ // writes into this directory and would await the promise it is running inside.
264
+ const saved = join(dir, 'verify');
265
+ await run(icacls, [dir, '/save', saved]);
266
+ const written = await readDescriptor(saved, dir);
267
+ await rm(saved, { force: true }).catch(() => undefined);
268
+ if (!asWritten(ours).test(written)) {
269
+ throw new Error(`the ACL orca wrote to ${dir} is not the one it asked for: ${written}`);
270
+ }
271
+ await assertPrivatePathIdentity(dir, was);
272
+ // Nothing sweeps an `orca-acl-` directory the way `sweepStaleTransports` sweeps the two
273
+ // named transports, so it takes itself with it rather than accumulating one per run.
274
+ process.on('exit', () => {
275
+ try {
276
+ const now = lstatSync(dir, { bigint: true });
277
+ if (!now.isSymbolicLink() && now.dev === was.dev && now.ino === was.ino) {
278
+ rmSync(dir, { recursive: true, force: true });
279
+ }
280
+ }
281
+ catch {
282
+ // Exiting anyway; a directory left in %TEMP% is not worth failing the exit over.
283
+ }
284
+ });
285
+ return dir;
286
+ }
287
+ catch (err) {
288
+ if (was)
289
+ await removePrivateDirectory(dir, was);
290
+ scratch = undefined;
291
+ throw err;
292
+ }
293
+ })();
294
+ return scratch;
295
+ }
296
+ const SYSTEM = 'S-1-5-18';
297
+ const ADMINISTRATORS = 'S-1-5-32-544';
298
+ /**
299
+ * By SID, never by name: `BUILTIN\Administrators` is localized on a localized Windows, and a grant
300
+ * naming a principal that does not resolve is a grant that silently matches nothing — which, after
301
+ * `/inheritance:r` has removed the rest, would leave the file with no usable ACE at all.
302
+ */
303
+ let sid;
304
+ async function currentAccountSid() {
305
+ sid ??= readSid().catch((err) => {
306
+ // Not cached as a rejection: a transient failure here would otherwise be permanent for the
307
+ // life of the process, and every later write would inherit the ACL we meant to replace.
308
+ sid = undefined;
309
+ throw err;
310
+ });
311
+ return sid;
312
+ }
313
+ async function readSid() {
314
+ const { stdout } = await run(system32('whoami.exe'), ['/user', '/fo', 'csv', '/nh']);
315
+ const found = /S-1-[\d-]+/.exec(stdout)?.[0];
316
+ if (!found)
317
+ throw new Error(`could not read this account's SID from: ${stdout.trim()}`);
318
+ return found;
319
+ }
320
+ /**
321
+ * Absolute rather than resolved through PATH. This runs in order to secure a private key, and a
322
+ * lookup that landed on someone else's `icacls.exe` — in the workspace being recorded, say — would
323
+ * hand that key to exactly the reader the call exists to shut out.
324
+ *
325
+ * Which is why there is no fallback. `'C:\Windows'` looks like one and is not: `\W` is not an
326
+ * escape, so that literal's value is `C:Windows`, and a path beginning with a drive letter and no
327
+ * separator is *drive-relative* — CreateProcess resolves it against the current directory on C:,
328
+ * which during a recording is the workspace. `Windows/System32/icacls.exe` is a storable git path,
329
+ * so the guess reintroduces exactly the hijack it was written against. Spelling it correctly would
330
+ * still be a guess, and wrong on a machine whose Windows is not on C:.
331
+ *
332
+ * `SystemRoot` is set by the OS in every normal process environment. Absent, something is wrong
333
+ * with how orca was launched, and refusing is the only answer that cannot be silently incorrect.
334
+ */
335
+ function system32(exe) {
336
+ const root = process.env['SystemRoot'];
337
+ // Absolute, not merely present. `SystemRoot=C:Windows` — the same drive-relative shape the
338
+ // comment above describes — would rebuild the workspace-relative lookup out of the environment
339
+ // instead of out of a literal, and a wrapper that sets the variable for orca's process is an
340
+ // ordinary thing to run into. `isAbsolute('C:Windows')` is false and `isAbsolute('C:\Windows')`
341
+ // is true, so this refuses exactly the values that would resolve against the current directory.
342
+ if (root === undefined || root === '' || !isAbsolute(root)) {
343
+ throw new Error(`cannot locate ${exe}: SystemRoot is ${root === undefined || root === '' ? 'not set' : `not an absolute path (${JSON.stringify(root)})`}, ` +
344
+ 'so there is no trustworthy path to it. orca will not fall back to a guess here — this ' +
345
+ 'call is what keeps a private key private.');
346
+ }
347
+ return join(root, 'System32', exe);
348
+ }
349
+ //# sourceMappingURL=private-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-files.js","sourceRoot":"","sources":["../src/private-files.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EACX,SAAS,EACT,QAAQ,EACR,OAAO,EACP,UAAU,EACX,MAAM,oBAAoB,CAAC;AAc5B,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,WAAW;;IAgBtB,OAAO;WAgBM,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAqCjF;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI;IAInC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,qFAAqF;IACrF,IAAI,GAAG,IAAI,MAAM,CAEhB;IAEK,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAmB5C,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAuElD"}
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EACX,SAAS,EACT,QAAQ,EACR,OAAO,EACP,UAAU,EACX,MAAM,oBAAoB,CAAC;AAc5B,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2EAA2E;AAC3E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,WAAW;;IAmBtB,OAAO;WAgBM,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAqCjF;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI;IAInC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,qFAAqF;IACrF,IAAI,GAAG,IAAI,MAAM,CAEhB;IAEK,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAsD5C,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CA0ElD"}
package/dist/writer.js CHANGED
@@ -26,6 +26,9 @@ export class TraceWriter {
26
26
  #started = process.hrtime.bigint();
27
27
  #startedAtMs = Date.now();
28
28
  #seq = 0;
29
+ /** Whether run.start reached disk, so run.end can tell an open run from an unopened one. */
30
+ #opened = false;
31
+ #closedEvent = false;
29
32
  #turn = 0;
30
33
  #git;
31
34
  #tail = Promise.resolve();
@@ -95,6 +98,37 @@ export class TraceWriter {
95
98
  async append(init) {
96
99
  if (this.#sealed)
97
100
  throw new Error(`run ${this.#runId} is closed`);
101
+ // SPEC §2.3: `run.start` AND `run.end` BRACKET THE RUN, EXACTLY ONE OF EACH.
102
+ //
103
+ // Nothing enforced that here, and three commands got it wrong in three different ways —
104
+ // `record --mcp-config` put a note at seq 0, `attach` wrote neither event, and a fork opened
105
+ // on `fork`. All three produced traces that look fine to `orca show`, `orca replay` and the
106
+ // viewer, and that no gateway will take:
107
+ //
108
+ // invalid trace: run.start at seq 1, must be seq 0
109
+ // invalid trace: 0 run.start and 1 run.end events (exactly one of each)
110
+ //
111
+ // The cost of finding out late is the whole recording: the user learns at `orca push`, after
112
+ // the agent session is over, that there is nothing to push. Refusing the write is the only
113
+ // point where the mistake is still cheap — it fails in the developer's own test run, at the
114
+ // line that wrote the wrong event, rather than in someone else's terminal a week later.
115
+ // Only the three a fragment cannot reach innocently. "seq 0 must BE run.start" would be the
116
+ // stronger rule and is wrong here: this writer is also how fixtures and conformance vectors
117
+ // are built, and a deliberate fragment is allowed to hold a few events and no bracket at all.
118
+ // These three are violations however the trace is meant to be used.
119
+ if (init.type === 'run.start' && this.#seq !== 0) {
120
+ throw new Error(`run.start belongs at seq 0 (spec §2.3); run ${this.#runId} tried to write it at seq ` +
121
+ `${this.#seq}, behind ${this.#opened ? 'a run.start that is already there' : 'events that were written first'}. ` +
122
+ 'Append it before any capture layer can write.');
123
+ }
124
+ if (init.type === 'run.end' && !this.#opened) {
125
+ throw new Error(`run ${this.#runId} has no run.start to close: the spec brackets a run with exactly one ` +
126
+ 'of each (spec §2.3), and a gateway refuses the push — "0 run.start and 1 run.end ' +
127
+ 'events". Append run.start as the run opens.');
128
+ }
129
+ if (init.type === 'run.end' && this.#closedEvent) {
130
+ throw new Error(`run ${this.#runId} already has a run.end; the spec allows exactly one`);
131
+ }
98
132
  // Clocks are read at call time so they describe the event, not the queue drain; seq is
99
133
  // assigned inside the queue so a rejected event leaves no hole in the dense order.
100
134
  const when = init.occurredAt ?? new Date();
@@ -175,6 +209,11 @@ export class TraceWriter {
175
209
  out.redacted = [...new Set(removed)];
176
210
  assertEvent(out);
177
211
  await this.#handle.write(`${JSON.stringify(out)}\n`);
212
+ // Set after the write, not before it: a bracket that failed to reach disk is not one.
213
+ if (out.type === 'run.start')
214
+ this.#opened = true;
215
+ if (out.type === 'run.end')
216
+ this.#closedEvent = true;
178
217
  this.#seq = seq + 1;
179
218
  return out;
180
219
  }
@@ -1 +1 @@
1
- {"version":3,"file":"writer.js","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orcareplay/core",
3
- "version": "0.3.1-main.g2d7bd68",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -17,7 +17,7 @@
17
17
  "dist"
18
18
  ],
19
19
  "dependencies": {
20
- "@orcareplay/plugin-api": "0.3.1-main.g2d7bd68",
21
- "@orcareplay/schema": "0.3.1-main.g2d7bd68"
20
+ "@orcareplay/plugin-api": "0.4.0",
21
+ "@orcareplay/schema": "0.4.0"
22
22
  }
23
23
  }