/** * Server-side per-session write grant: the ACE materialization half of the * sandbox seam's per-session grant reuse. The seam (sandbox-local) holds ONE * {@link AclWriteGrant} per session for the server process's lifetime — * created lazily at the session's first confined execution, reused (never * re-applied) for every later call, revoked on provider dispose. The durable * half (the session's SID and paths surviving a restart) lives in the * session log, owned by the seam; this module owns only the native half: the * parsed SID pointer and the standing ACEs. * * Fail-closed: `add` throws on any grant failure and the caller disposes the * instance (revoking every path granted so far); `dispose` revokes every * standing grant and reports every cleanup failure. * @module @deepseek-ai/dsh-sandbox-windows-acl/grant */ import type { Win32Bindings } from './ffi.ts'; /** * One write SID's server-lifetime grant materialization: the parsed SID * pointer plus every directory whose DACL currently carries its ACE. * Workspace paths are added STANDING (their ACEs are the cross-session reuse * cache and outlive the grant — dispose() skips revoking them, or the next * provision would re-propagate the whole tree); temp paths are revocable * (dispose() revokes them — an inheritable ACE must not outlive its * session's temp directory). Create with {@link AclWriteGrant.create}; * dispose revokes the revocable paths and frees the SID. */ export declare class AclWriteGrant { /** The write SID in SDDL string form. */ readonly writeSid: string; private readonly api; private readonly sidPtr; private readonly revocablePaths; private readonly standingPaths; private constructor(); /** * Parse the SID string and open the binding table (lazily, once per * server). Fail-closed: any failure throws — nothing is granted yet. * @param writeSid - the orphan write SID string (`S-1-4-x-y`). * @param api - optional already-resolved bindings (tests). * @returns the ready grant (no ACEs yet). */ static create(writeSid: string, api?: Win32Bindings): AclWriteGrant; /** * Grant the write ACE on one directory (idempotent: an already-standing * exact ACE skips the eager full-tree re-propagation — see * {@link grantWrite}) and record the path for {@link dispose} unless it is * standing. The path is recorded BEFORE the grant: a post-apply throw (a * LocalFree failure after SetNamedSecurityInfoW succeeded) must still * revoke it, and revoking an ungranted path is a no-op merge. Callers * treat a throw as a failed materialization and dispose the instance to * revoke the paths granted so far. * @param path - the directory whose DACL gains the grant. * @param standing - the ACE outlives this grant (the workspace reuse * cache; dispose() skips revoking it). Default false (revoked on * dispose — the temp-directory lifecycle). */ add(path: string, standing?: boolean): void; /** Every directory currently carrying the grant, in grant order. */ get paths(): readonly string[]; /** Revoke every revocable grant (standing ACEs stay) and free the SID; reports every cleanup failure. */ dispose(): void; } //# sourceMappingURL=grant.d.ts.map