/** * Windows owner-SID and DACL verification for the session temp tree. * * POSIX proves ownership of an existing temp component with a uid comparison * and a mode check. Node exposes neither on Windows — `lstatSync` reports * uid/gid 0 — so this module reads the real security descriptor through a * PowerShell `Get-Acl` subprocess and decides from SIDs alone: the owner must * be a trusted principal and every access-allowed ACE must grant only trusted * principals. Names are never compared; two accounts can share a display name, * but never a SID. * * A subprocess per directory creation would sit on the spill hot path, so a * successful verification is cached per canonical path per process, keyed to * the directory's metadata identity — creation time, NTFS change time, and * last-write time. A directory swapped underneath the path carries a fresh * creation time, and an in-place DACL edit bumps the change time, so either * forces a fresh descriptor read rather than trust from a stale check (see * `verifyWindowsDirectorySecurity`). Failures are not cached: a refusal means * "no spill file this time", and a transient read failure must not disable * persistence for the rest of the process. */ /** One DACL entry with its trustee resolved to a literal SID. */ export interface WindowsAccessRule { /** True for an access-allowed entry, false for access-denied. */ allow: boolean; /** The SID the entry applies to. */ sid: string; } /** What the security read produces: the caller's SID plus the descriptor. */ export interface WindowsDirectorySecurity { /** SID of the current process token's user. */ currentSid: string; /** SID owning the directory. */ ownerSid: string; /** The DACL portion of the descriptor in SDDL form (may be empty). */ dacl: string; /** * Every DACL entry with its trustee as a literal SID (`GetAccessRules` * resolves domain-relative SDDL abbreviations such as `LA` that a * name-side parse cannot). The SDDL string above cross-checks that these * rules describe the whole DACL: only plain allow/deny ACE types, one * rule per ACE. */ accessRules: readonly WindowsAccessRule[]; } /** * Decide whether a directory's descriptor is safe to adopt. * * Returns a refusal reason, or `undefined` when the directory is owned by a * trusted principal and its DACL grants access to trusted principals only. * Exported as a pure function so the decision table is testable on any host. */ export declare function evaluateWindowsDirectorySecurity(security: WindowsDirectorySecurity): string | undefined; /** Test seam: why the most recent `readWindowsDirectorySecurity` returned `undefined`. */ export declare function getLastWindowsSecurityReadFailureForTesting(): string | undefined; /** * Read the security descriptor of `path`, or `undefined` when it cannot be * read (access denied, missing PowerShell, timeout). Callers treat * `undefined` as unverifiable and refuse the directory. */ export declare function readWindowsDirectorySecurity(path: string): WindowsDirectorySecurity | undefined; type SecurityReader = (path: string) => WindowsDirectorySecurity | undefined; /** * Verify `path` as adoptable, returning the refusal reason when it is not. * * The subprocess read sits on the spill path, so a successful verification * is cached for the life of the process while the directory's metadata * identity (creation, change, and last-write times) is unchanged. A swapped * directory or an in-place DACL edit changes that identity and forces a * fresh read; so does creating a file inside the directory, which trades one * bounded subprocess per spill for never trusting a stale descriptor. The * symlink/directory checks in `session-temp-dir.ts` still run on every use. * A failure is never cached, so a transient read error does not permanently * disable spills. */ export declare function verifyWindowsDirectorySecurity(path: string): string | undefined; /** Test seam: substitute the descriptor reader; pass `undefined` to restore. */ export declare function setWindowsDirectorySecurityReaderForTesting(reader: SecurityReader | undefined): void; /** Test seam: forget verified paths so a suite can re-drive verification. */ export declare function resetWindowsDirectorySecurityStateForTesting(): void; export {}; //# sourceMappingURL=windows-directory-security.d.ts.map