/** * Global-salt subsystem for the CLEO API key KDF. * * @task T348 * @epic T310 * @why ADR-037 §5 — API key KDF uses machine-key + global-salt + agentId. * global-salt must persist across process restarts but is machine-local. * @what Atomic first-run generation, memoized read, permission/size validation. */ /** Filename for the global salt file under CLEO home. */ export declare const GLOBAL_SALT_FILENAME = "global-salt"; /** Required size of the global salt in bytes. */ export declare const GLOBAL_SALT_SIZE = 32; /** * Returns the absolute path to the global-salt file. * * @returns Absolute path: `{cleoHome}/global-salt` * * @task T348 * @epic T310 * * @example * ```typescript * const saltPath = getGlobalSaltPath(); * // Linux: "/home/user/.local/share/cleo/global-salt" * ``` */ export declare function getGlobalSaltPath(): string; /** * Returns the 32-byte global salt. Generates and persists atomically on first * call when the file does not exist. Subsequent calls return the memoized value. * * Never overwrites an existing salt — doing so would invalidate every stored * API key derived from it. * * @returns A 32-byte Buffer containing the global salt * @throws {Error} If the salt file exists with wrong size or wrong permissions * * @task T348 * @epic T310 * * @example * ```typescript * const salt = getGlobalSalt(); // Buffer(32) [...] * ``` */ export declare function getGlobalSalt(): Buffer; /** * Read (or generate on first use) the global salt of an EXPLICIT CLEO home, * bypassing the process memo. * * {@link getGlobalSalt} memoizes the salt of the ambient home for the process * lifetime. That is wrong for code that addresses a different home, or one * whose salt file was just replaced — a backup import that places the bundled * `global-salt` and then re-encrypts credentials under it (T12326). Same * generation and validation rules as {@link getGlobalSalt}. * * @param cleoHome - Absolute CLEO home directory. * @returns The 32-byte salt stored at `/global-salt`. * @throws {Error} If the salt file exists with wrong size or wrong permissions. * @task T12326 */ export declare function loadGlobalSaltAt(cleoHome: string): Buffer; /** * Read and validate the global salt of an explicit CLEO home WITHOUT ever * creating it. Read paths that must not mint key material use this. * * @param cleoHome - Absolute CLEO home directory. * @returns The 32-byte salt, or `null` when `/global-salt` does not exist. * @throws {Error} If the salt file exists with wrong size or wrong permissions. * @task T12867 */ export declare function readGlobalSaltAt(cleoHome: string): Buffer | null; /** * Create a secret file only if it does not exist, never replacing one that * another process created first. The bytes are written to a private temp * file and hard-linked into place, so the target appears complete or not at * all. Where hard links are unavailable, the target is created with the * exclusive `wx` flag instead. * * @param filePath - Target path. * @param data - The secret bytes. * @param mode - File mode (for example `0o600`). * @returns `true` when this call created the file, `false` when it already existed. * @task T12867 */ export declare function createSecretFileExclusive(filePath: string, data: Buffer, mode: number): boolean; /** * Delete temp files that {@link createSecretFileExclusive} left behind for * `filePath` (`..<12 hex>.tmp`) when a process crashed between the * link and the unlink. Such a file is a second hard link to the live secret. * Only files older than a minute are removed, so a concurrent creator's * in-flight temp file is never touched. Best effort. * * @param filePath - The secret file (for example `/machine-key`). * @task T12867 */ export declare function sweepStaleSecretTemps(filePath: string): void; /** * Runtime validation helper for startup integrity checks. * * Throws if the salt file exists but is malformed (wrong size or permissions). * Safe to call when the file does not yet exist — returns silently in that case * because first-run generation is handled lazily by `getGlobalSalt()`. * * @throws {Error} If the salt file exists with wrong size or wrong permissions * * @task T348 * @epic T310 * * @example * ```typescript * // Called at process startup to catch accidental salt corruption early * validateGlobalSalt(); * ``` */ export declare function validateGlobalSalt(): void; /** * Clears the in-process memoization cache so tests can exercise the * first-call generation path independently. * * @internal TEST ONLY — do NOT export through internal.ts or re-export * from any public barrel. This symbol must never appear in production call paths. * * @task T348 * @epic T310 */ export declare function __clearGlobalSaltCache(): void; //# sourceMappingURL=global-salt.d.ts.map