vaultkeeper 0.6.0 → 0.7.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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/backend/registry.ts","../src/backend/file-backend.ts","../src/util/exec.ts","../src/backend/keychain-backend.ts","../src/backend/dpapi-backend.ts","../src/backend/secret-tool-backend.ts","../src/backend/one-password-constants.ts","../src/backend/one-password-backend.ts","../src/backend/yubikey-backend.ts","../src/backend/register-builtins.ts","../src/backend/types.ts","../src/identity/hash.ts","../src/identity/manifest.ts","../src/identity/trust.ts","../src/identity/session.ts","../src/config.ts","../src/keys/manager.ts","../src/jwe/token.ts","../src/jwe/claims.ts","../src/access/delegated-fetch.ts","../src/access/delegated-exec.ts","../src/access/controlled-direct.ts","../src/access/sign-util.ts","../src/access/delegated-sign.ts","../src/access/delegated-verify.ts","../src/doctor/checks.ts","../src/util/platform.ts","../src/doctor/runner.ts","../src/vault.ts"],"names":["path","os","resolve","path2","os2","getEntryPath","fs2","join","dirname","fileURLToPath","spawn","STORAGE_DIR_NAME","GCM_IV_BYTES","GCM_KEY_BYTES","getStorageDir","os3","fs3","crypto2","encryptGcm","decryptGcm","crypto3","path4","fs5","updated","path5","fs6","crypto4","isObject","PLACEHOLDER","replacePlaceholder","replaceInRecord","crypto5","crypto6","crypto7"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Error hierarchy for vaultkeeper.\n */\n\n/** Base error for all vaultkeeper errors. */\nexport class VaultError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'VaultError'\n }\n}\n\n// --- Backend Access Failures ---\n\n/**\n * Thrown when the backend keychain or credential store is locked and requires\n * user interaction (e.g. biometric prompt or password entry) before access can\n * be granted.\n */\nexport class BackendLockedError extends VaultError {\n /**\n * Whether the lock can be resolved through an interactive user prompt.\n * When `true`, callers may retry after prompting the user.\n */\n readonly interactive: boolean\n\n constructor(message: string, interactive: boolean) {\n super(message)\n this.name = 'BackendLockedError'\n this.interactive = interactive\n }\n}\n\n/**\n * Thrown when a hardware device (e.g. YubiKey or smart card) required for\n * authentication is not currently connected.\n */\nexport class DeviceNotPresentError extends VaultError {\n /**\n * How long (in milliseconds) the operation waited for the device before\n * giving up.\n */\n readonly timeoutMs: number\n\n constructor(message: string, timeoutMs: number) {\n super(message)\n this.name = 'DeviceNotPresentError'\n this.timeoutMs = timeoutMs\n }\n}\n\n/**\n * Thrown when the user explicitly denies an authorization request for a\n * secret access operation (e.g. cancels an OS permission dialog).\n */\nexport class AuthorizationDeniedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'AuthorizationDeniedError'\n }\n}\n\n/**\n * Thrown when no configured backend is available or reachable.\n * Inspect `reason` for a machine-readable cause and `attempted` for the list\n * of backend types that were tried.\n */\nexport class BackendUnavailableError extends VaultError {\n /**\n * Machine-readable reason code describing why the backend is unavailable\n * (e.g. `'none-enabled'`, `'all-failed'`).\n */\n readonly reason: string\n\n /**\n * The backend type identifiers that were attempted before this error was\n * thrown.\n */\n readonly attempted: string[]\n\n constructor(message: string, reason: string, attempted: string[]) {\n super(message)\n this.name = 'BackendUnavailableError'\n this.reason = reason\n this.attempted = attempted\n }\n}\n\n/**\n * Thrown when a required backend plugin (e.g. a third-party credential\n * manager) is not installed on the current system.\n */\nexport class PluginNotFoundError extends VaultError {\n /**\n * The plugin package or binary name that was not found.\n */\n readonly plugin: string\n\n /**\n * A URL pointing to installation instructions for the missing plugin.\n */\n readonly installUrl: string\n\n constructor(message: string, plugin: string, installUrl: string) {\n super(message)\n this.name = 'PluginNotFoundError'\n this.plugin = plugin\n this.installUrl = installUrl\n }\n}\n\n/**\n * Thrown when a requested secret does not exist in the backend store.\n */\nexport class SecretNotFoundError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'SecretNotFoundError'\n }\n}\n\n// --- JWE Lifecycle Failures ---\n\n/**\n * Thrown when a JWE token has passed its expiration time (`exp` claim).\n */\nexport class TokenExpiredError extends VaultError {\n /**\n * Whether the token can be refreshed by calling `setup()` again.\n * When `true`, the secret still exists in the backend and a new token can be\n * issued.\n */\n readonly canRefresh: boolean\n\n constructor(message: string, canRefresh: boolean) {\n super(message)\n this.name = 'TokenExpiredError'\n this.canRefresh = canRefresh\n }\n}\n\n/**\n * Thrown when the encryption key that was used to create a JWE has since been\n * rotated out of the grace period and can no longer be used for decryption.\n */\nexport class KeyRotatedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'KeyRotatedError'\n }\n}\n\n/**\n * Thrown when the encryption key referenced by a JWE's `kid` header has been\n * explicitly revoked and is no longer available for decryption.\n */\nexport class KeyRevokedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'KeyRevokedError'\n }\n}\n\n/**\n * Thrown when a JWE token has been explicitly blocked (e.g. after a single-use\n * token has already been consumed).\n */\nexport class TokenRevokedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'TokenRevokedError'\n }\n}\n\n/**\n * Thrown when a token with a finite `use` limit has been presented more times\n * than the limit allows.\n */\nexport class UsageLimitExceededError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'UsageLimitExceededError'\n }\n}\n\n// --- Identity and Trust Failures ---\n\n/**\n * Thrown when the hash of an executable no longer matches the previously\n * approved hash stored in the trust manifest (TOFU conflict).\n *\n * Callers must re-approve the executable before a new token can be issued for\n * it.\n */\nexport class IdentityMismatchError extends VaultError {\n /**\n * The hash that was recorded in the trust manifest at approval time.\n */\n readonly previousHash: string\n\n /**\n * The hash computed from the executable at the current moment.\n */\n readonly currentHash: string\n\n constructor(message: string, previousHash: string, currentHash: string) {\n super(message)\n this.name = 'IdentityMismatchError'\n this.previousHash = previousHash\n this.currentHash = currentHash\n }\n}\n\n// --- Access Pattern Failures ---\n\n/**\n * Thrown when a delegated `exec()` call fails due to a process-level error\n * (e.g. the command binary is not found or cannot be spawned).\n *\n * @public\n */\nexport class ExecError extends VaultError {\n /**\n * The command that failed to execute.\n */\n readonly command: string\n\n constructor(message: string, command: string) {\n super(message)\n this.name = 'ExecError'\n this.command = command\n }\n}\n\n/**\n * Thrown when a JWE string cannot be parsed because it is structurally\n * malformed (e.g. wrong number of segments, invalid Base64URL header,\n * or unparseable JSON header).\n *\n * @public\n */\nexport class InvalidTokenError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidTokenError'\n }\n}\n\n/**\n * Thrown when `SecretAccessor.read()` is called after the accessor has\n * already been consumed.\n *\n * @public\n */\nexport class AccessorConsumedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'AccessorConsumedError'\n }\n}\n\n// --- Infrastructure Failures ---\n\n/**\n * Thrown when a caller requests a signing/verification algorithm that is not\n * in the allowed set (e.g. `'md5'`).\n *\n * @public\n */\nexport class InvalidAlgorithmError extends VaultError {\n /**\n * The algorithm that was requested.\n */\n readonly algorithm: string\n\n /**\n * The set of algorithms that are allowed.\n */\n readonly allowed: string[]\n\n constructor(message: string, algorithm: string, allowed: string[]) {\n super(message)\n this.name = 'InvalidAlgorithmError'\n this.algorithm = algorithm\n this.allowed = allowed\n }\n}\n\n/**\n * Thrown during initialization when a required system dependency (e.g. OpenSSL\n * or a native credential helper) is missing or incompatible.\n */\nexport class SetupError extends VaultError {\n /**\n * The name of the dependency that caused the setup failure.\n */\n readonly dependency: string\n\n constructor(message: string, dependency: string) {\n super(message)\n this.name = 'SetupError'\n this.dependency = dependency\n }\n}\n\n/**\n * Thrown when a filesystem operation fails due to a permission or access\n * problem (e.g. the config directory is not writable).\n */\nexport class FilesystemError extends VaultError {\n /**\n * The absolute path of the file or directory that caused the error.\n */\n readonly path: string\n\n /**\n * The permission level that was required but not available\n * (e.g. `'read'`, `'write'`, `'execute'`).\n */\n readonly permission: string\n\n constructor(message: string, filePath: string, permission: string) {\n super(message)\n this.name = 'FilesystemError'\n this.path = filePath\n this.permission = permission\n }\n}\n\n/**\n * Thrown when a key rotation is requested while a previous rotation is still\n * within its grace period (i.e. the previous key has not yet been retired).\n */\nexport class RotationInProgressError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'RotationInProgressError'\n }\n}\n","/**\n * Registry for secret backend implementations.\n *\n * @remarks\n * The registry maintains a mapping of backend types to factory functions,\n * allowing dynamic creation of backends based on configuration.\n */\n\nimport type { SecretBackend, BackendFactory } from './types.js'\nimport type { BackendSetupFactory } from './setup-types.js'\nimport { BackendUnavailableError } from '../errors.js'\n\n/**\n * Registry for secret backend implementations.\n *\n * @remarks\n * The registry allows registration of custom backends and provides\n * a factory method to create backend instances from a type string.\n *\n * Note: This class is used as a namespace for static methods.\n * @public\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class BackendRegistry {\n private static backends = new Map<string, BackendFactory>()\n private static setups = new Map<string, BackendSetupFactory>()\n\n /**\n * Register a backend factory.\n * @param type - Backend type identifier\n * @param factory - Factory function to create backend instances\n */\n static register(type: string, factory: BackendFactory): void {\n this.backends.set(type, factory)\n }\n\n /**\n * Create a backend instance by type.\n * @param type - Backend type identifier\n * @param config - Optional backend configuration forwarded to the factory\n * @returns A SecretBackend instance\n * @throws {@link BackendUnavailableError} if the backend type is not registered\n */\n static create(type: string, config?: import('../types.js').BackendConfig): SecretBackend {\n const factory = this.backends.get(type)\n if (factory === undefined) {\n throw new BackendUnavailableError(\n `Unknown backend type: ${type}. ` +\n `Available types: ${Array.from(this.backends.keys()).join(', ')}`,\n 'unknown-type',\n Array.from(this.backends.keys()),\n )\n }\n return factory(config)\n }\n\n /**\n * Get all registered backend type identifiers.\n * @returns Array of backend type identifiers\n */\n static getTypes(): string[] {\n return Array.from(this.backends.keys())\n }\n\n /**\n * Returns backend types that are available on the current system.\n *\n * @remarks\n * Creates each registered backend via its factory, calls `isAvailable()`,\n * and returns only the type identifiers whose backend reports availability.\n * If a backend's `isAvailable()` call throws, that backend is excluded from\n * the result rather than propagating the error.\n *\n * @returns Promise resolving to an array of available backend type identifiers\n * @public\n */\n static async getAvailableTypes(): Promise<string[]> {\n const entries = Array.from(this.backends.entries())\n const results = await Promise.all(\n entries.map(async ([type, factory]) => {\n try {\n const backend = factory()\n const available = await backend.isAvailable()\n return available ? type : null\n } catch {\n return null\n }\n }),\n )\n return results.filter((type): type is string => type !== null)\n }\n\n /**\n * Register a setup factory for a backend type.\n * @param type - Backend type identifier\n * @param factory - Factory function that creates a setup generator\n */\n static registerSetup(type: string, factory: BackendSetupFactory): void {\n this.setups.set(type, factory)\n }\n\n /**\n * Get the setup factory for a backend type, if one is registered.\n * @param type - Backend type identifier\n * @returns The setup factory, or `undefined` if none is registered\n */\n static getSetup(type: string): BackendSetupFactory | undefined {\n return this.setups.get(type)\n }\n\n /**\n * Check whether a setup factory is registered for the given backend type.\n * @param type - Backend type identifier\n * @returns `true` if a setup factory is registered\n */\n static hasSetup(type: string): boolean {\n return this.setups.has(type)\n }\n\n /**\n * Clear all registered backend factories.\n * Intended for use in tests only.\n * @internal\n */\n static clearBackends(): void {\n this.backends.clear()\n }\n\n /**\n * Clear all registered setup factories.\n * Intended for use in tests only.\n * @internal\n */\n static clearSetups(): void {\n this.setups.clear()\n }\n}\n","/**\n * Encrypted file fallback backend implementation.\n *\n * @remarks\n * Stores secrets encrypted with AES-256-GCM using Node.js native crypto.\n * Each secret is stored as an individual encrypted file under\n * ~/.vaultkeeper/file/. A randomly generated key stored in a protected\n * file is used for encryption.\n *\n * Encrypted file format (all parts base64-encoded, colon-separated):\n * <iv>:<authTag>:<ciphertext>\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport * as crypto from 'node:crypto'\nimport { SecretNotFoundError, FilesystemError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\nconst STORAGE_DIR_NAME = path.join('.vaultkeeper', 'file')\nconst KEY_FILE = '.key'\nconst GCM_IV_BYTES = 12\nconst GCM_KEY_BYTES = 32\nconst GCM_TAG_LENGTH = 128 // bits\n\nfunction getStorageDir(): string {\n return path.join(os.homedir(), STORAGE_DIR_NAME)\n}\n\nfunction getEntryPath(storageDir: string, id: string): string {\n const safeId = Buffer.from(id, 'utf8').toString('hex')\n return path.join(storageDir, `${safeId}.enc`)\n}\n\nasync function ensureStorageDir(storageDir: string): Promise<void> {\n try {\n await fs.mkdir(storageDir, { recursive: true, mode: 0o700 })\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code !== 'EEXIST') {\n throw new FilesystemError(\n `Failed to create storage directory: ${storageDir}`,\n storageDir,\n 'rwx',\n )\n }\n }\n}\n\nasync function getOrCreateKey(storageDir: string): Promise<Buffer> {\n const keyPath = path.join(storageDir, KEY_FILE)\n try {\n const data = await fs.readFile(keyPath)\n return data\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n // Generate a random 32-byte key\n const key = crypto.randomBytes(GCM_KEY_BYTES)\n await fs.writeFile(keyPath, key, { mode: 0o600 })\n return key\n }\n throw err\n }\n}\n\nfunction encryptGcm(key: Buffer, plaintext: string): string {\n const iv = crypto.randomBytes(GCM_IV_BYTES)\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH / 8,\n })\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])\n const authTag = cipher.getAuthTag()\n return [iv.toString('base64'), authTag.toString('base64'), encrypted.toString('base64')].join(':')\n}\n\nfunction decryptGcm(key: Buffer, encoded: string): string {\n const parts = encoded.split(':')\n if (parts.length !== 3) {\n throw new Error('Invalid encrypted file format: expected iv:authTag:ciphertext')\n }\n const [ivB64, authTagB64, ciphertextB64] = parts\n if (ivB64 === undefined || authTagB64 === undefined || ciphertextB64 === undefined) {\n throw new Error('Invalid encrypted file format: missing part')\n }\n const iv = Buffer.from(ivB64, 'base64')\n const authTag = Buffer.from(authTagB64, 'base64')\n const ciphertext = Buffer.from(ciphertextB64, 'base64')\n\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH / 8,\n })\n decipher.setAuthTag(authTag)\n const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])\n return decrypted.toString('utf8')\n}\n\n/**\n * Encrypted file fallback backend.\n *\n * @remarks\n * Available on all platforms. Stores secrets as AES-256-GCM encrypted files\n * using Node.js native crypto — no external tools required.\n * Not as secure as OS-native keystores, but provides a portable fallback.\n *\n * @internal\n */\nexport class FileBackend implements ListableBackend {\n readonly type = 'file'\n readonly displayName = 'Encrypted File Store'\n\n async isAvailable(): Promise<boolean> {\n // Node.js crypto is always available; check we can create the storage dir.\n try {\n const storageDir = getStorageDir()\n await ensureStorageDir(storageDir)\n return true\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const storageDir = getStorageDir()\n await ensureStorageDir(storageDir)\n const key = await getOrCreateKey(storageDir)\n const entryPath = getEntryPath(storageDir, id)\n const encrypted = encryptGcm(key, secret)\n await fs.writeFile(entryPath, encrypted, { mode: 0o600 })\n }\n\n async retrieve(id: string): Promise<string> {\n const storageDir = getStorageDir()\n const entryPath = getEntryPath(storageDir, id)\n\n let encoded: string\n try {\n encoded = await fs.readFile(entryPath, 'utf8')\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n throw new SecretNotFoundError(`Secret not found in file store: ${id}`)\n }\n throw err\n }\n\n const key = await getOrCreateKey(storageDir)\n try {\n return decryptGcm(key, encoded)\n } catch (err) {\n throw new Error(\n `Failed to decrypt secret: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n }\n\n async delete(id: string): Promise<void> {\n const storageDir = getStorageDir()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.unlink(entryPath)\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n throw new SecretNotFoundError(`Secret not found in file store: ${id}`)\n }\n throw err\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const storageDir = getStorageDir()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n return true\n } catch {\n return false\n }\n }\n\n async list(): Promise<string[]> {\n const storageDir = getStorageDir()\n let entries: string[]\n try {\n entries = await fs.readdir(storageDir)\n } catch {\n return []\n }\n return entries\n .filter((f) => f.endsWith('.enc'))\n .map((f) => Buffer.from(f.slice(0, -4), 'hex').toString('utf8'))\n }\n}\n","/**\n * CLI spawn wrapper for executing external commands.\n */\n\nimport { spawn } from 'node:child_process'\nimport { PluginNotFoundError } from '../errors.js'\n\n/** Options for command execution. */\nexport interface ExecCommandOptions {\n /** Input to write to stdin */\n stdin?: string | undefined\n /** Timeout in milliseconds */\n timeoutMs?: number | undefined\n}\n\n/** Result of a command execution. */\nexport interface ExecCommandResult {\n stdout: string\n stderr: string\n exitCode: number\n}\n\n/**\n * Execute a command and return stdout.\n * @throws Error if the command exits with a non-zero code.\n */\nexport async function execCommand(\n command: string,\n args: string[],\n options?: ExecCommandOptions,\n): Promise<string> {\n const result = await execCommandFull(command, args, options)\n if (result.exitCode !== 0) {\n throw new Error(`Command failed with exit code ${String(result.exitCode)}: ${result.stderr}`)\n }\n return result.stdout.trim()\n}\n\n/**\n * Execute a command and return the full result.\n */\nexport function execCommandFull(\n command: string,\n args: string[],\n options?: ExecCommandOptions,\n): Promise<ExecCommandResult> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, {\n stdio: [options?.stdin !== undefined ? 'pipe' : 'ignore', 'pipe', 'pipe'],\n })\n let stdout = ''\n let stderr = ''\n\n proc.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString()\n })\n\n proc.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString()\n })\n\n if (options?.stdin !== undefined && proc.stdin) {\n proc.stdin.write(options.stdin)\n proc.stdin.end()\n }\n\n if (options?.timeoutMs !== undefined) {\n setTimeout(() => {\n proc.kill('SIGTERM')\n reject(new Error(`Command timed out after ${String(options.timeoutMs)}ms`))\n }, options.timeoutMs)\n }\n\n proc.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 })\n })\n\n proc.on('error', (error) => {\n if ('code' in error && error.code === 'ENOENT') {\n reject(\n new PluginNotFoundError(\n `'${command}' is not installed or not found in PATH`,\n command,\n '',\n ),\n )\n } else {\n reject(error)\n }\n })\n })\n}\n","/**\n * macOS Keychain backend implementation.\n *\n * @remarks\n * Stores secrets as base64-encoded generic passwords in the macOS Keychain\n * using the `security` CLI tool. Service name format: `vaultkeeper:<id>`.\n */\n\nimport { execCommand, execCommandFull } from '../util/exec.js'\nimport { SecretNotFoundError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\nconst ACCOUNT = 'vaultkeeper'\nconst SERVICE_PREFIX = 'vaultkeeper:'\n\n/**\n * macOS Keychain secret backend.\n *\n * @remarks\n * Only available on Darwin (macOS). Uses `security` CLI to store/retrieve\n * generic passwords. Secrets are base64-encoded before storage.\n *\n * @internal\n */\nexport class KeychainBackend implements ListableBackend {\n readonly type = 'keychain'\n readonly displayName = 'macOS Keychain'\n\n async isAvailable(): Promise<boolean> {\n if (process.platform !== 'darwin') {\n return false\n }\n try {\n const result = await execCommandFull('security', ['version'])\n return result.exitCode === 0\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const service = `${SERVICE_PREFIX}${id}`\n const encoded = Buffer.from(secret, 'utf8').toString('base64')\n // Delete existing entry first (ignore errors) then add fresh\n await execCommandFull('security', [\n 'delete-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n ])\n await execCommand('security', [\n 'add-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n '-w',\n encoded,\n ])\n }\n\n async retrieve(id: string): Promise<string> {\n const service = `${SERVICE_PREFIX}${id}`\n const result = await execCommandFull('security', [\n 'find-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n '-w',\n ])\n if (result.exitCode !== 0) {\n throw new SecretNotFoundError(`Secret not found in macOS Keychain: ${id}`)\n }\n const encoded = result.stdout.trim()\n return Buffer.from(encoded, 'base64').toString('utf8')\n }\n\n async delete(id: string): Promise<void> {\n const service = `${SERVICE_PREFIX}${id}`\n const result = await execCommandFull('security', [\n 'delete-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n ])\n if (result.exitCode !== 0) {\n throw new SecretNotFoundError(`Secret not found in macOS Keychain: ${id}`)\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const service = `${SERVICE_PREFIX}${id}`\n const result = await execCommandFull('security', [\n 'find-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n ])\n return result.exitCode === 0\n }\n\n async list(): Promise<string[]> {\n const result = await execCommandFull('security', [\n 'dump-keychain',\n ])\n if (result.exitCode !== 0) {\n return []\n }\n const ids: string[] = []\n const servicePattern = /0x00000007 <blob>=\"vaultkeeper:([^\"]+)\"/g\n let match: RegExpExecArray | null = servicePattern.exec(result.stdout)\n while (match !== null) {\n const id = match[1]\n if (id !== undefined) {\n ids.push(id)\n }\n match = servicePattern.exec(result.stdout)\n }\n return ids\n }\n}\n","/**\n * Windows DPAPI backend implementation.\n *\n * @remarks\n * Stores secrets using Windows Data Protection API (DPAPI) via PowerShell.\n * DPAPI encrypts data using the current user's credentials and machine key.\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { execCommand, execCommandFull } from '../util/exec.js'\nimport { SecretNotFoundError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\nfunction getStoragePath(): string {\n return path.join(os.homedir(), '.vaultkeeper', 'dpapi')\n}\n\nfunction getEntryPath(storageDir: string, id: string): string {\n // Use hex encoding of id for safe filenames\n const safeId = Buffer.from(id, 'utf8').toString('hex')\n return path.join(storageDir, `${safeId}.enc`)\n}\n\n/**\n * Windows DPAPI secret backend.\n *\n * @remarks\n * Only available on Windows. Uses PowerShell with\n * [System.Security.Cryptography.ProtectedData] to encrypt/decrypt secrets.\n * Encrypted blobs are stored in ~/.vaultkeeper/dpapi/.\n *\n * @internal\n */\nexport class DpapiBackend implements ListableBackend {\n readonly type = 'dpapi'\n readonly displayName = 'Windows DPAPI'\n\n async isAvailable(): Promise<boolean> {\n if (process.platform !== 'win32') {\n return false\n }\n try {\n const result = await execCommandFull('powershell', [\n '-NoProfile',\n '-Command',\n '[System.Security.Cryptography.ProtectedData] | Out-Null; exit 0',\n ])\n return result.exitCode === 0\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const storageDir = getStoragePath()\n await fs.mkdir(storageDir, { recursive: true })\n const entryPath = getEntryPath(storageDir, id)\n\n const script = [\n 'Add-Type -AssemblyName System.Security',\n `$bytes = [System.Text.Encoding]::UTF8.GetBytes(${JSON.stringify(secret)})`,\n '$entropy = $null',\n '$scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser',\n '$encrypted = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $entropy, $scope)',\n `[System.IO.File]::WriteAllBytes(${JSON.stringify(entryPath)}, $encrypted)`,\n ].join('; ')\n\n await execCommand('powershell', ['-NoProfile', '-Command', script])\n }\n\n async retrieve(id: string): Promise<string> {\n const storageDir = getStoragePath()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n } catch {\n throw new SecretNotFoundError(`Secret not found in Windows DPAPI store: ${id}`)\n }\n\n const script = [\n 'Add-Type -AssemblyName System.Security',\n `$encrypted = [System.IO.File]::ReadAllBytes(${JSON.stringify(entryPath)})`,\n '$entropy = $null',\n '$scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser',\n '$bytes = [System.Security.Cryptography.ProtectedData]::Unprotect($encrypted, $entropy, $scope)',\n 'Write-Output ([System.Text.Encoding]::UTF8.GetString($bytes))',\n ].join('; ')\n\n return execCommand('powershell', ['-NoProfile', '-Command', script])\n }\n\n async delete(id: string): Promise<void> {\n const storageDir = getStoragePath()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.unlink(entryPath)\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n throw new SecretNotFoundError(`Secret not found in Windows DPAPI store: ${id}`)\n }\n throw err\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const storageDir = getStoragePath()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n return true\n } catch {\n return false\n }\n }\n\n async list(): Promise<string[]> {\n const storageDir = getStoragePath()\n let entries: string[]\n try {\n entries = await fs.readdir(storageDir)\n } catch {\n return []\n }\n return entries\n .filter((f) => f.endsWith('.enc'))\n .map((f) => Buffer.from(f.slice(0, -4), 'hex').toString('utf8'))\n }\n}\n","/**\n * Linux secret-tool backend implementation.\n *\n * @remarks\n * Stores secrets using the `secret-tool` CLI which interfaces with the\n * GNOME Keyring or any other Secret Service API implementation via D-Bus.\n */\n\nimport { execCommand, execCommandFull } from '../util/exec.js'\nimport { SecretNotFoundError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\nconst ATTRIBUTE_KEY = 'vaultkeeper-id'\nconst LABEL_PREFIX = 'vaultkeeper: '\n\n/**\n * Linux secret-tool (Secret Service API) backend.\n *\n * @remarks\n * Only available on Linux with secret-tool installed. Requires a running\n * Secret Service (e.g., GNOME Keyring or KWallet with Secret Service plugin).\n *\n * @internal\n */\nexport class SecretToolBackend implements ListableBackend {\n readonly type = 'secret-tool'\n readonly displayName = 'Linux Secret Service (secret-tool)'\n\n async isAvailable(): Promise<boolean> {\n if (process.platform !== 'linux') {\n return false\n }\n try {\n const result = await execCommandFull('secret-tool', ['--version'])\n return result.exitCode === 0\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const label = `${LABEL_PREFIX}${id}`\n await execCommand(\n 'secret-tool',\n ['store', '--label', label, ATTRIBUTE_KEY, id],\n { stdin: secret },\n )\n }\n\n async retrieve(id: string): Promise<string> {\n const result = await execCommandFull('secret-tool', ['lookup', ATTRIBUTE_KEY, id])\n if (result.exitCode !== 0 || result.stdout.trim() === '') {\n throw new SecretNotFoundError(`Secret not found in Secret Service: ${id}`)\n }\n return result.stdout.trim()\n }\n\n async delete(id: string): Promise<void> {\n const result = await execCommandFull('secret-tool', ['clear', ATTRIBUTE_KEY, id])\n if (result.exitCode !== 0) {\n throw new SecretNotFoundError(`Secret not found in Secret Service: ${id}`)\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const result = await execCommandFull('secret-tool', ['lookup', ATTRIBUTE_KEY, id])\n return result.exitCode === 0 && result.stdout.trim() !== ''\n }\n\n async list(): Promise<string[]> {\n const result = await execCommandFull('secret-tool', [\n 'search',\n ATTRIBUTE_KEY,\n '',\n ])\n if (result.exitCode !== 0) {\n return []\n }\n const ids: string[] = []\n const attrPattern = new RegExp(`attribute\\\\.${ATTRIBUTE_KEY} = (.+)`, 'g')\n let match: RegExpExecArray | null = attrPattern.exec(result.stdout)\n while (match !== null) {\n const id = match[1]\n if (id !== undefined) {\n ids.push(id)\n }\n match = attrPattern.exec(result.stdout)\n }\n return ids\n }\n}\n","/**\n * Shared constants for 1Password SDK integration.\n *\n * @remarks\n * Centralised here so the backend, worker, and discovery modules stay in sync.\n *\n * @internal\n */\n\nimport { readFileSync, existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/** Name reported to the 1Password SDK for integration tracking. */\nexport const INTEGRATION_NAME = 'vaultkeeper'\n\nlet cachedVersion: string | undefined\n\n/**\n * Version reported to the 1Password SDK.\n *\n * @remarks\n * Lazily derived from packages/vaultkeeper/package.json on first call so that\n * consumers who never use the 1Password backend pay no I/O cost at import time.\n * The result is memoized for subsequent calls.\n *\n * @internal\n */\nexport function getIntegrationVersion(): string {\n if (cachedVersion !== undefined) return cachedVersion\n\n const dir = dirname(fileURLToPath(import.meta.url))\n // Source: src/backend/ → ../../package.json\n // Bundled: dist/ → ../package.json\n const candidates = [\n resolve(dir, '..', '..', 'package.json'),\n resolve(dir, '..', 'package.json'),\n ]\n for (const candidate of candidates) {\n if (!existsSync(candidate)) continue\n const raw: unknown = JSON.parse(readFileSync(candidate, 'utf8'))\n if (\n raw !== null &&\n typeof raw === 'object' &&\n 'version' in raw &&\n typeof raw.version === 'string'\n ) {\n cachedVersion = raw.version\n return cachedVersion\n }\n }\n throw new Error(\n `Could not read version from vaultkeeper package.json. Tried paths: ${candidates.join(', ')}`,\n )\n}\n","/**\n * 1Password SDK-based backend implementation.\n *\n * @remarks\n * Stores secrets in 1Password using the `@1password/sdk` package.\n * Each secret is stored as a \"Password\" item in the specified vault.\n *\n * Supports two access modes:\n * - `session`: A single SDK client is created on first use and cached for all operations.\n * - `per-access`: The `retrieve()` operation spawns a child process that creates a fresh\n * SDK client (triggering biometric auth) for each retrieval. Other operations still use\n * the cached session client.\n */\n\nimport { spawn } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, join } from 'node:path'\nimport {\n SecretNotFoundError,\n PluginNotFoundError,\n BackendLockedError,\n AuthorizationDeniedError,\n} from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\n// ---- SDK type imports (runtime-dynamic, not static imports) ----\n// We import the SDK dynamically so that the backend degrades gracefully\n// when the native SDK library is not available on the host system.\n\ntype SdkModule = typeof import('@1password/sdk')\ntype Client = import('@1password/sdk').Client\ntype Item = import('@1password/sdk').Item\ntype ItemOverview = import('@1password/sdk').ItemOverview\n\nconst SDK_INSTALL_URL = 'https://developer.1password.com/docs/sdks/'\nconst TAG = 'vaultkeeper'\nconst PASSWORD_FIELD_TITLE = 'password'\nconst SESSION_TIMEOUT_MS = 30_000\nimport { INTEGRATION_NAME, getIntegrationVersion } from './one-password-constants.js'\n\n/** Options accepted by `OnePasswordBackend`. */\nexport interface OnePasswordBackendOptions {\n /** Vault ID to store/retrieve secrets from. */\n vault: string\n /** Account name or UUID for desktop app authentication (mutually exclusive with serviceAccountToken). */\n account?: string\n /** Service account token for headless CI/CD use (mutually exclusive with account). */\n serviceAccountToken?: string\n /** Access mode: 'session' (default) or 'per-access'. */\n accessMode?: 'session' | 'per-access'\n /**\n * Override the session timeout in milliseconds.\n * Defaults to 30000ms. Exposed for testing only.\n * @internal\n */\n sessionTimeoutMs?: number\n}\n\n/** Worker response shape for successful retrieval. */\ninterface WorkerSuccess {\n value: string\n}\n\n/** Worker response shape for a retrieval failure. */\ninterface WorkerFailure {\n error: string\n code: string\n}\n\ntype WorkerResponse = WorkerSuccess | WorkerFailure\n\nfunction isWorkerSuccess(res: WorkerResponse): res is WorkerSuccess {\n return 'value' in res\n}\n\nfunction isWorkerResponse(value: unknown): value is WorkerResponse {\n if (value === null || typeof value !== 'object') return false\n if ('value' in value && typeof value.value === 'string') return true\n if (\n 'error' in value &&\n typeof value.error === 'string' &&\n 'code' in value &&\n typeof value.code === 'string'\n )\n return true\n return false\n}\n\n/**\n * 1Password backend via the `@1password/sdk` package.\n *\n * @remarks\n * Requires the `@1password/sdk` package to be installed and, when using desktop\n * authentication, the 1Password desktop application to be running and unlocked.\n *\n * @internal\n */\nexport class OnePasswordBackend implements ListableBackend {\n readonly type = '1password'\n readonly displayName = '1Password'\n\n private readonly vaultId: string\n private readonly account: string | undefined\n private readonly serviceAccountToken: string | undefined\n private readonly accessMode: 'session' | 'per-access'\n private readonly sessionTimeoutMs: number\n\n /** In-flight or resolved client promise — prevents duplicate createClient calls. */\n private clientPromise: Promise<Client> | undefined\n\n constructor(options: OnePasswordBackendOptions) {\n if (options.accessMode === 'per-access' && options.serviceAccountToken !== undefined) {\n throw new Error(\n 'per-access mode requires desktop biometric authentication and cannot be used with a service account token',\n )\n }\n if (options.account !== undefined && options.serviceAccountToken !== undefined) {\n throw new Error(\n 'account and serviceAccountToken are mutually exclusive — provide one or the other, not both',\n )\n }\n this.vaultId = options.vault\n this.sessionTimeoutMs = options.sessionTimeoutMs ?? SESSION_TIMEOUT_MS\n if (options.account !== undefined) {\n this.account = options.account\n }\n if (options.serviceAccountToken !== undefined) {\n this.serviceAccountToken = options.serviceAccountToken\n }\n this.accessMode = options.accessMode ?? 'session'\n }\n\n async isAvailable(): Promise<boolean> {\n const sdk = await this.tryLoadSdk()\n return sdk !== null\n }\n\n // ---- Session client management ----\n\n /**\n * Dynamically import the SDK. Returns `null` if the SDK is not installed or\n * the native library cannot be loaded.\n */\n private async tryLoadSdk(): Promise<SdkModule | null> {\n try {\n const sdk = await import('@1password/sdk')\n return sdk\n } catch {\n return null\n }\n }\n\n /**\n * Acquire (or create) a cached SDK client.\n * Wraps `createClient` with a configurable timeout (default 30 s) to handle\n * the known beta SDK hang after session expiry.\n */\n private acquireClient(): Promise<Client> {\n this.clientPromise ??= this.createClientInternal().catch((err: unknown) => {\n // Reset the promise so future calls retry\n this.clientPromise = undefined\n throw err\n })\n return this.clientPromise\n }\n\n private async createClientInternal(): Promise<Client> {\n const sdk = await this.tryLoadSdk()\n if (sdk === null) {\n throw new PluginNotFoundError(\n '1Password SDK (@1password/sdk) is not available. Install it to use this backend.',\n '@1password/sdk',\n SDK_INSTALL_URL,\n )\n }\n\n const auth = this.buildAuth(sdk)\n\n let timerId: ReturnType<typeof setTimeout> | undefined\n const timeoutPromise = new Promise<never>((_resolve, reject) => {\n timerId = setTimeout(() => {\n reject(new BackendLockedError('1Password session timed out waiting for authentication', true))\n }, this.sessionTimeoutMs)\n })\n\n try {\n const client = await Promise.race([\n sdk.createClient({\n auth,\n integrationName: INTEGRATION_NAME,\n integrationVersion: getIntegrationVersion(),\n }),\n timeoutPromise,\n ])\n return client\n } catch (err) {\n if (err instanceof BackendLockedError) {\n throw err\n }\n if (err instanceof sdk.DesktopSessionExpiredError) {\n throw new BackendLockedError(\n '1Password session has expired. Please unlock the app.',\n true,\n )\n }\n throw new AuthorizationDeniedError(\n `1Password authentication failed: ${String(err)}`,\n )\n } finally {\n if (timerId !== undefined) {\n clearTimeout(timerId)\n }\n }\n }\n\n private buildAuth(sdk: SdkModule): string | import('@1password/sdk').DesktopAuth {\n if (this.serviceAccountToken !== undefined) {\n return this.serviceAccountToken\n }\n const accountName = this.account ?? ''\n return new sdk.DesktopAuth(accountName)\n }\n\n // ---- Helpers for item lookup by title ----\n\n /**\n * List all items in the vault tagged \"vaultkeeper\" and find one with the\n * matching title (= secret ID). Returns `undefined` if not found.\n */\n private async findItemOverview(\n client: Client,\n id: string,\n ): Promise<ItemOverview | undefined> {\n const overviews = await client.items.list(this.vaultId)\n for (const overview of overviews) {\n if (overview.title === id && overview.tags.includes(TAG)) {\n return overview\n }\n }\n return undefined\n }\n\n /**\n * Fetch the full item for a given secret id. Returns `undefined` if not found.\n */\n private async findItem(client: Client, id: string): Promise<Item | undefined> {\n const overview = await this.findItemOverview(client, id)\n if (overview === undefined) return undefined\n return client.items.get(this.vaultId, overview.id)\n }\n\n /**\n * Extract the concealed password field value from an item.\n */\n private extractSecret(item: Item, id: string): string {\n for (const field of item.fields) {\n if (field.title === PASSWORD_FIELD_TITLE) {\n return field.value\n }\n }\n throw new SecretNotFoundError(\n `Secret found in 1Password but missing password field: ${id}`,\n )\n }\n\n // ---- SecretBackend / ListableBackend implementation ----\n\n async store(id: string, secret: string): Promise<void> {\n const { ItemCategory, ItemFieldType } = await this.requireSdk()\n const client = await this.acquireClient()\n\n const existing = await this.findItem(client, id)\n\n if (existing !== undefined) {\n // Update the existing item's password field, or append one if missing\n const hasPasswordField = existing.fields.some((f) => f.title === PASSWORD_FIELD_TITLE)\n const updatedFields = hasPasswordField\n ? existing.fields.map((f) => {\n if (f.title === PASSWORD_FIELD_TITLE) {\n return { ...f, value: secret }\n }\n return f\n })\n : [\n ...existing.fields,\n {\n id: 'password',\n title: PASSWORD_FIELD_TITLE,\n fieldType: ItemFieldType.Concealed,\n value: secret,\n },\n ]\n await client.items.put({ ...existing, fields: updatedFields })\n } else {\n await client.items.create({\n category: ItemCategory.Password,\n vaultId: this.vaultId,\n title: id,\n tags: [TAG],\n fields: [\n {\n id: 'password',\n title: PASSWORD_FIELD_TITLE,\n fieldType: ItemFieldType.Concealed,\n value: secret,\n },\n ],\n })\n }\n }\n\n async retrieve(id: string): Promise<string> {\n if (this.accessMode === 'per-access') {\n return this.retrieveViaWorker(id)\n }\n return this.retrieveViaSession(id)\n }\n\n private async retrieveViaSession(id: string): Promise<string> {\n const client = await this.acquireClient()\n const item = await this.findItem(client, id)\n if (item === undefined) {\n throw new SecretNotFoundError(`Secret not found in 1Password: ${id}`)\n }\n return this.extractSecret(item, id)\n }\n\n /**\n * Spawn the per-access worker script that triggers a fresh biometric prompt\n * for each retrieval, then returns the secret from its stdout.\n */\n private retrieveViaWorker(id: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const workerPath = join(\n dirname(fileURLToPath(import.meta.url)),\n 'one-password-worker.js',\n )\n\n const accountArg = this.account ?? ''\n const child = spawn(\n process.execPath,\n [workerPath, accountArg, this.vaultId, id],\n { stdio: ['ignore', 'pipe', 'pipe'] },\n )\n\n const stdoutChunks: Buffer[] = []\n const stderrChunks: Buffer[] = []\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk)\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk)\n })\n\n child.on('close', (code) => {\n const raw = Buffer.concat(stdoutChunks).toString('utf8').trim()\n\n // If worker produced no stdout, use exit code + stderr for diagnostics\n if (raw === '') {\n const stderr = Buffer.concat(stderrChunks).toString('utf8').trim()\n const detail = stderr !== '' ? stderr : `exit code ${String(code)}`\n reject(new Error(`1Password per-access worker crashed for secret ${id}: ${detail}`))\n return\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n reject(new SecretNotFoundError(`Worker returned unparseable output for secret: ${id}`))\n return\n }\n if (!isWorkerResponse(parsed)) {\n reject(new SecretNotFoundError(`Worker returned unexpected response shape for secret: ${id}`))\n return\n }\n if (isWorkerSuccess(parsed)) {\n resolve(parsed.value)\n } else {\n switch (parsed.code) {\n case 'NOT_FOUND':\n reject(new SecretNotFoundError(`Secret not found in 1Password: ${id}`))\n break\n case 'AUTH_DENIED':\n reject(new AuthorizationDeniedError('1Password authentication was denied'))\n break\n case 'LOCKED':\n reject(new BackendLockedError('1Password is locked. Please unlock and retry.', true))\n break\n default:\n reject(new SecretNotFoundError(`Worker failed for secret ${id}: ${parsed.error}`))\n }\n }\n })\n\n child.on('error', (err) => {\n reject(new Error(\n `Failed to spawn 1Password per-access worker at ${workerPath}: ${String(err)}`,\n ))\n })\n })\n }\n\n async delete(id: string): Promise<void> {\n const client = await this.acquireClient()\n const overview = await this.findItemOverview(client, id)\n if (overview === undefined) {\n throw new SecretNotFoundError(`Secret not found in 1Password: ${id}`)\n }\n await client.items.delete(this.vaultId, overview.id)\n }\n\n async exists(id: string): Promise<boolean> {\n const client = await this.acquireClient()\n const overview = await this.findItemOverview(client, id)\n return overview !== undefined\n }\n\n async list(): Promise<string[]> {\n const client = await this.acquireClient()\n const overviews = await client.items.list(this.vaultId)\n const ids: string[] = []\n for (const overview of overviews) {\n if (overview.tags.includes(TAG)) {\n ids.push(overview.title)\n }\n }\n return ids\n }\n\n // ---- Private helpers ----\n\n /** Load SDK and throw PluginNotFoundError if unavailable. */\n private async requireSdk(): Promise<SdkModule> {\n const sdk = await this.tryLoadSdk()\n if (sdk === null) {\n throw new PluginNotFoundError(\n '1Password SDK (@1password/sdk) is not available.',\n '@1password/sdk',\n SDK_INSTALL_URL,\n )\n }\n return sdk\n }\n}\n","/**\n * YubiKey backend implementation.\n *\n * @remarks\n * Stores secrets protected by a YubiKey using the `ykman` CLI tool.\n * Secrets are encrypted using AES-256-GCM with a key derived from the\n * YubiKey's HMAC-SHA1 challenge-response (slot 2) via HKDF-SHA-256.\n *\n * Encrypted file format (version 1, all parts base64-encoded, colon-separated):\n * 1:<iv>:<authTag>:<ciphertext>\n *\n * The leading \"1:\" version prefix allows future format migrations and enables\n * detection of legacy CBC files (which lack this prefix).\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport * as crypto from 'node:crypto'\nimport { execCommandFull } from '../util/exec.js'\nimport { SecretNotFoundError, PluginNotFoundError, DeviceNotPresentError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\nconst YKMAN_INSTALL_URL = 'https://developers.yubico.com/yubikey-manager/'\nconst STORAGE_DIR_NAME = path.join('.vaultkeeper', 'yubikey')\nconst METADATA_FILE = 'metadata.json'\nconst DEVICE_TIMEOUT_MS = 5000\n\n/** AES-256-GCM constants */\nconst GCM_IV_BYTES = 12\nconst GCM_KEY_BYTES = 32\nconst GCM_TAG_LENGTH_BITS = 128\n\n/** Version prefix written at the start of every encrypted file. */\nconst FORMAT_VERSION = '1'\n\ninterface YubikeyMetadata {\n entries: Record<string, string>\n}\n\nfunction getStorageDir(): string {\n return path.join(os.homedir(), STORAGE_DIR_NAME)\n}\n\nfunction getEntryPath(storageDir: string, id: string): string {\n const safeId = Buffer.from(id, 'utf8').toString('hex')\n return path.join(storageDir, `${safeId}.enc`)\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (value === null || typeof value !== 'object') {\n return false\n }\n return Object.values(value).every((v) => typeof v === 'string')\n}\n\nasync function loadMetadata(storageDir: string): Promise<YubikeyMetadata> {\n const metaPath = path.join(storageDir, METADATA_FILE)\n try {\n const raw = await fs.readFile(metaPath, 'utf8')\n const parsed: unknown = JSON.parse(raw)\n if (\n parsed !== null &&\n typeof parsed === 'object' &&\n 'entries' in parsed &&\n isStringRecord(parsed.entries)\n ) {\n return { entries: parsed.entries }\n }\n return { entries: {} }\n } catch {\n return { entries: {} }\n }\n}\n\nasync function saveMetadata(storageDir: string, metadata: YubikeyMetadata): Promise<void> {\n const metaPath = path.join(storageDir, METADATA_FILE)\n await fs.writeFile(metaPath, JSON.stringify(metadata, null, 2), { mode: 0o600 })\n}\n\n/** Expected byte length of a YubiKey HMAC-SHA1 response (20 bytes = 40 hex chars). */\nconst HMAC_RESPONSE_HEX_LENGTH = 40\n\n/** Regex for a valid HMAC-SHA1 hex response: exactly 40 lowercase or uppercase hex digits. */\nconst HMAC_RESPONSE_RE = /^[0-9a-fA-F]{40}$/\n\n/**\n * Derive a 256-bit AES key from the YubiKey HMAC-SHA1 response using HKDF-SHA-256.\n *\n * The HMAC-SHA1 response is 20 bytes — too short and too biased to use\n * directly as an AES-256 key. HKDF expands it to exactly 32 bytes while\n * binding the key to the secret `id` via the `info` field.\n *\n * Throws if `hmacResponse` is not exactly 40 hex characters (20 bytes), which\n * would indicate a malformed or truncated ykman response.\n */\nfunction deriveKey(hmacResponse: string, id: string): Buffer {\n const trimmed = hmacResponse.trim()\n if (!HMAC_RESPONSE_RE.test(trimmed)) {\n throw new Error(\n `Invalid YubiKey HMAC response: expected exactly ${String(HMAC_RESPONSE_HEX_LENGTH)} hex characters (20 bytes), got ${String(trimmed.length)} characters`,\n )\n }\n // The ykman response is a hex string; convert to raw bytes as the IKM.\n const ikm = Buffer.from(trimmed, 'hex')\n const info = Buffer.from(`vaultkeeper-yubikey:${id}`, 'utf8')\n // Node's hkdfSync returns an ArrayBuffer; wrap without copying.\n const keyMaterial = crypto.hkdfSync('sha256', ikm, Buffer.alloc(0), info, GCM_KEY_BYTES)\n return Buffer.from(keyMaterial)\n}\n\n/**\n * Encrypt `plaintext` with AES-256-GCM using `key`.\n * Returns a versioned, colon-separated string: `1:<iv>:<authTag>:<ciphertext>`\n * (all binary fields base64-encoded).\n *\n * The key and all intermediate buffers are zeroed in the finally block,\n * guaranteeing cleanup even if `createCipheriv` or `cipher.final()` throws.\n */\nfunction encryptGcm(key: Buffer, plaintext: string): string {\n const iv = crypto.randomBytes(GCM_IV_BYTES)\n let encrypted: Buffer | undefined\n let authTag: Buffer | undefined\n try {\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH_BITS / 8,\n })\n encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])\n authTag = cipher.getAuthTag()\n\n return [\n FORMAT_VERSION,\n iv.toString('base64'),\n authTag.toString('base64'),\n encrypted.toString('base64'),\n ].join(':')\n } finally {\n // Zero all secret material regardless of success or failure.\n key.fill(0)\n iv.fill(0)\n encrypted?.fill(0)\n authTag?.fill(0)\n }\n}\n\n/**\n * Decrypt a versioned GCM blob produced by `encryptGcm`.\n *\n * Version detection distinguishes three cases:\n * - First segment is a number matching `FORMAT_VERSION` → current format, proceed.\n * - First segment is a different number → unsupported future version, throw a\n * clear \"unsupported version N\" error.\n * - First segment is not a number at all → legacy/corrupt format (e.g. an\n * AES-256-CBC file written before this implementation), throw a migration error.\n *\n * The key buffer is always zeroed in a finally block, guaranteeing cleanup even\n * if `createDecipheriv` or `setAuthTag` throws before the decrypt attempt.\n */\nfunction decryptGcm(key: Buffer, encoded: string): string {\n const parts = encoded.split(':')\n const versionSegment = parts[0] ?? ''\n\n // Determine whether the first segment is a numeric version prefix at all.\n const parsedVersion = parseInt(versionSegment, 10)\n const isNumericVersion =\n String(parsedVersion) === versionSegment && !Number.isNaN(parsedVersion)\n\n if (!isNumericVersion) {\n // No recognisable version prefix — treat as legacy CBC or corrupt file.\n key.fill(0)\n throw new Error(\n 'Encrypted file uses a legacy format (AES-256-CBC). ' +\n 'Delete the secret and re-store it to migrate to AES-256-GCM.',\n )\n }\n\n if (versionSegment !== FORMAT_VERSION) {\n // A future format version this binary does not know how to decode.\n key.fill(0)\n throw new Error(\n `Unsupported encrypted file version: ${versionSegment}. ` +\n `This vaultkeeper build only supports version ${FORMAT_VERSION}. ` +\n 'Upgrade vaultkeeper to read this secret.',\n )\n }\n\n if (parts.length !== 4) {\n key.fill(0)\n throw new Error(\n `Invalid encrypted file format: expected ${FORMAT_VERSION}:iv:authTag:ciphertext`,\n )\n }\n\n const [_version, ivB64, authTagB64, ciphertextB64] = parts\n if (ivB64 === undefined || authTagB64 === undefined || ciphertextB64 === undefined) {\n key.fill(0)\n throw new Error('Invalid encrypted file format: missing part')\n }\n\n let decrypted: Buffer | undefined\n try {\n const iv = Buffer.from(ivB64, 'base64')\n const authTag = Buffer.from(authTagB64, 'base64')\n const ciphertext = Buffer.from(ciphertextB64, 'base64')\n\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH_BITS / 8,\n })\n decipher.setAuthTag(authTag)\n\n try {\n decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])\n } catch (err) {\n throw new Error(\n `GCM authentication failed — ciphertext may be tampered: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n\n const plaintext = decrypted.toString('utf8')\n return plaintext\n } finally {\n // Zero all secret material regardless of success or failure.\n key.fill(0)\n decrypted?.fill(0)\n }\n}\n\n/**\n * YubiKey backend via `ykman` CLI.\n *\n * @remarks\n * Requires ykman to be installed and a YubiKey to be connected.\n * Secrets are stored in files encrypted using AES-256-GCM. The encryption\n * key is derived from the YubiKey's HMAC-SHA1 challenge-response (slot 2)\n * via HKDF-SHA-256, binding each secret to its `id`.\n *\n * @internal\n */\nexport class YubikeyBackend implements ListableBackend {\n readonly type = 'yubikey'\n readonly displayName = 'YubiKey'\n\n async isAvailable(): Promise<boolean> {\n try {\n const result = await execCommandFull('ykman', ['--version'])\n if (result.exitCode !== 0) {\n return false\n }\n // Also verify a YubiKey is connected\n const listResult = await execCommandFull('ykman', ['list'])\n return listResult.exitCode === 0 && listResult.stdout.trim() !== ''\n } catch {\n return false\n }\n }\n\n private async requireDevice(): Promise<void> {\n const available = await this.isAvailable()\n if (!available) {\n const hasYkman = await execCommandFull('ykman', ['--version']).then(\n (r) => r.exitCode === 0,\n () => false,\n )\n if (!hasYkman) {\n throw new PluginNotFoundError('ykman is not installed', 'ykman', YKMAN_INSTALL_URL)\n }\n throw new DeviceNotPresentError('No YubiKey device detected', DEVICE_TIMEOUT_MS)\n }\n }\n\n /**\n * Perform the YubiKey HMAC-SHA1 challenge-response for `id` and return the\n * raw hex response string. Throws on device failure.\n */\n private async challengeResponse(id: string): Promise<string> {\n const challenge = Buffer.from(`vaultkeeper:${id}`, 'utf8').toString('hex')\n const responseResult = await execCommandFull('ykman', ['otp', 'calculate', '2', challenge])\n if (responseResult.exitCode !== 0) {\n throw new Error(`YubiKey challenge-response failed: ${responseResult.stderr}`)\n }\n return responseResult.stdout.trim()\n }\n\n async store(id: string, secret: string): Promise<void> {\n await this.requireDevice()\n\n const storageDir = getStorageDir()\n await fs.mkdir(storageDir, { recursive: true, mode: 0o700 })\n\n const hmacResponse = await this.challengeResponse(id)\n const key = deriveKey(hmacResponse, id)\n const encrypted = encryptGcm(key, secret)\n\n const entryPath = getEntryPath(storageDir, id)\n await fs.writeFile(entryPath, encrypted, { mode: 0o600 })\n\n const metadata = await loadMetadata(storageDir)\n metadata.entries[id] = entryPath\n await saveMetadata(storageDir, metadata)\n }\n\n async retrieve(id: string): Promise<string> {\n await this.requireDevice()\n\n const storageDir = getStorageDir()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n } catch {\n throw new SecretNotFoundError(`Secret not found in YubiKey store: ${id}`)\n }\n\n const encoded = await fs.readFile(entryPath, 'utf8')\n const hmacResponse = await this.challengeResponse(id)\n const key = deriveKey(hmacResponse, id)\n\n return decryptGcm(key, encoded)\n }\n\n async delete(id: string): Promise<void> {\n await this.requireDevice()\n\n const storageDir = getStorageDir()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.unlink(entryPath)\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n throw new SecretNotFoundError(`Secret not found in YubiKey store: ${id}`)\n }\n throw err\n }\n\n const metadata = await loadMetadata(storageDir)\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete metadata.entries[id]\n await saveMetadata(storageDir, metadata)\n }\n\n async exists(id: string): Promise<boolean> {\n const storageDir = getStorageDir()\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n return true\n } catch {\n return false\n }\n }\n\n async list(): Promise<string[]> {\n const storageDir = getStorageDir()\n const metadata = await loadMetadata(storageDir)\n return Object.keys(metadata.entries)\n }\n}\n","/**\n * Side-effect module that registers all built-in backends with the {@link BackendRegistry}.\n *\n * @remarks\n * Imported from the package entry point (`index.ts`) so that built-in backends\n * are available immediately after `import 'vaultkeeper'`.\n *\n * @see https://github.com/mike-north/vaultkeeper/issues/21\n */\n\nimport type { BackendConfig } from '../types.js'\nimport { BackendRegistry } from './registry.js'\nimport { FileBackend } from './file-backend.js'\nimport { KeychainBackend } from './keychain-backend.js'\nimport { DpapiBackend } from './dpapi-backend.js'\nimport { SecretToolBackend } from './secret-tool-backend.js'\nimport { OnePasswordBackend } from './one-password-backend.js'\nimport type { OnePasswordBackendOptions } from './one-password-backend.js'\nimport { YubikeyBackend } from './yubikey-backend.js'\n\n/**\n * Register all built-in backends with the {@link BackendRegistry}.\n *\n * @remarks\n * Called automatically as a module side-effect. Also exported so that tests\n * can re-register builtins after calling `BackendRegistry.clearBackends()`.\n *\n * @internal\n */\nexport function registerBuiltinBackends(): void {\n BackendRegistry.register('file', () => new FileBackend())\n BackendRegistry.register('keychain', () => new KeychainBackend())\n BackendRegistry.register('dpapi', () => new DpapiBackend())\n BackendRegistry.register('secret-tool', () => new SecretToolBackend())\n BackendRegistry.register('1password', (config?: BackendConfig) => {\n const opts = config?.options\n const vaultId = opts?.vault ?? ''\n const opOptions: OnePasswordBackendOptions = {\n vault: vaultId,\n // 'session' is the safer default — 'per-access' re-prompts on every read.\n accessMode: opts?.accessMode === 'per-access' ? 'per-access' : 'session',\n }\n const account = opts?.account\n if (account !== undefined) {\n opOptions.account = account\n }\n const serviceAccountToken = opts?.serviceAccountToken\n if (serviceAccountToken !== undefined) {\n opOptions.serviceAccountToken = serviceAccountToken\n }\n return new OnePasswordBackend(opOptions)\n })\n BackendRegistry.register('yubikey', () => new YubikeyBackend())\n}\n\nregisterBuiltinBackends()\n","/**\n * Backend abstraction layer types for vaultkeeper.\n */\n\n/**\n * Factory function for creating a SecretBackend instance.\n *\n * @remarks\n * Factories may optionally accept a {@link BackendConfig} to configure the\n * backend from the user's vaultkeeper config file. Factories that do not need\n * configuration can ignore the parameter.\n *\n * @public\n */\n// Inline import() avoids a circular dependency: ../types.js imports from this barrel.\nexport type BackendFactory = (config?: import('../types.js').BackendConfig) => SecretBackend\n\n/**\n * Abstraction interface for all secret storage backends.\n *\n * @remarks\n * Each backend implementation must handle its own availability check and\n * secret lifecycle (store, retrieve, delete, exists).\n *\n * @public\n */\nexport interface SecretBackend {\n /** Unique type identifier for this backend. */\n readonly type: string\n\n /** Human-readable display name for this backend. */\n readonly displayName: string\n\n /**\n * Check whether this backend is available on the current system.\n * @returns true if the backend can be used, false otherwise\n */\n isAvailable(): Promise<boolean>\n\n /**\n * Store a secret under the given id.\n * @param id - Unique identifier for the secret\n * @param secret - The secret value to store\n */\n store(id: string, secret: string): Promise<void>\n\n /**\n * Retrieve a secret by id.\n * @param id - Unique identifier for the secret\n * @returns The stored secret value\n * @throws SecretNotFoundError if the secret does not exist\n */\n retrieve(id: string): Promise<string>\n\n /**\n * Delete a secret by id.\n * @param id - Unique identifier for the secret\n * @throws SecretNotFoundError if the secret does not exist\n */\n delete(id: string): Promise<void>\n\n /**\n * Check whether a secret exists for the given id.\n * @param id - Unique identifier for the secret\n * @returns true if the secret exists, false otherwise\n */\n exists(id: string): Promise<boolean>\n}\n\n/**\n * Backend that can enumerate stored secret IDs.\n * @public\n */\nexport interface ListableBackend extends SecretBackend {\n /**\n * List IDs of all secrets managed by this backend.\n * @returns Array of secret identifiers\n */\n list(): Promise<string[]>\n}\n\n/**\n * Type guard for backends that support listing.\n * @public\n */\nexport function isListableBackend(backend: SecretBackend): backend is ListableBackend {\n return 'list' in backend && typeof backend.list === 'function'\n}\n","/**\n * Executable hashing utilities.\n */\n\nimport * as crypto from 'node:crypto'\nimport * as fs from 'node:fs'\n\n/**\n * Compute the SHA-256 digest of the file at `filePath`.\n *\n * @param filePath - Absolute or relative path to the binary to hash.\n * @returns Hex-encoded SHA-256 digest string.\n * @internal\n */\nexport function hashExecutable(filePath: string): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const hash = crypto.createHash('sha256')\n const stream = fs.createReadStream(filePath)\n\n stream.on('data', (chunk: Buffer | string) => {\n hash.update(chunk)\n })\n\n stream.on('end', () => {\n resolve(hash.digest('hex'))\n })\n\n stream.on('error', (err: Error) => {\n reject(err)\n })\n })\n}\n","/**\n * Trust manifest management — load, save, and query approved executable hashes.\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport type { TrustManifest, TrustManifestEntry } from './types.js'\n\nconst MANIFEST_FILENAME = 'trust-manifest.json'\n\n/** Raw shape persisted to disk (plain object, not a Map). */\ninterface RawManifest {\n version: number\n entries: Record<string, TrustManifestEntry>\n}\n\n/**\n * Type guard that checks `value` is an object with a `version: number` and\n * `entries` object property, matching {@link RawManifest}.\n *\n * We avoid type assertions by narrowing through the `in` operator and\n * `typeof` checks. The discriminated union `unknown → object` chain lets\n * TypeScript track narrowness without any `as` casts.\n */\nfunction isRawManifest(value: unknown): value is RawManifest {\n if (typeof value !== 'object' || value === null) return false\n if (!('version' in value) || typeof value.version !== 'number') return false\n if (!('entries' in value) || typeof value.entries !== 'object' || value.entries === null) return false\n return true\n}\n\n/**\n * Type guard for a single {@link TrustManifestEntry}.\n */\nfunction isTrustManifestEntry(value: unknown): value is TrustManifestEntry {\n if (typeof value !== 'object' || value === null) return false\n if (!('hashes' in value) || !Array.isArray(value.hashes)) return false\n if (!('trustTier' in value)) return false\n const { trustTier } = value\n if (trustTier !== 1 && trustTier !== 2 && trustTier !== 3) return false\n return true\n}\n\n/**\n * Load the trust manifest from `configDir`.\n * Returns an empty `Map` if the manifest file does not yet exist.\n * @internal\n */\nexport async function loadManifest(configDir: string): Promise<TrustManifest> {\n const manifestPath = path.join(configDir, MANIFEST_FILENAME)\n let rawText: string\n try {\n rawText = await fs.readFile(manifestPath, 'utf8')\n } catch (err) {\n if (\n typeof err === 'object' &&\n err !== null &&\n 'code' in err &&\n err.code === 'ENOENT'\n ) {\n return new Map()\n }\n throw err\n }\n\n const parsed: unknown = JSON.parse(rawText)\n\n if (!isRawManifest(parsed)) {\n return new Map()\n }\n\n const manifest: TrustManifest = new Map()\n for (const [namespace, entry] of Object.entries(parsed.entries)) {\n if (isTrustManifestEntry(entry)) {\n manifest.set(namespace, { hashes: [...entry.hashes], trustTier: entry.trustTier })\n }\n }\n return manifest\n}\n\n/**\n * Persist `manifest` to `configDir`, creating the directory if necessary.\n * @internal\n */\nexport async function saveManifest(configDir: string, manifest: TrustManifest): Promise<void> {\n await fs.mkdir(configDir, { recursive: true })\n const entries: Record<string, TrustManifestEntry> = {}\n for (const [namespace, entry] of manifest) {\n entries[namespace] = entry\n }\n const raw: RawManifest = { version: 1, entries }\n const manifestPath = path.join(configDir, MANIFEST_FILENAME)\n await fs.writeFile(manifestPath, JSON.stringify(raw, null, 2), 'utf8')\n}\n\n/**\n * Return a new manifest that includes `hash` under `namespace`.\n * If the namespace does not yet exist it is created with tier 3 (Unverified).\n * The trust tier of an existing entry is not changed.\n * @internal\n */\nexport function addTrustedHash(manifest: TrustManifest, namespace: string, hash: string): TrustManifest {\n const next = new Map(manifest)\n const existing = next.get(namespace)\n if (existing === undefined) {\n next.set(namespace, { hashes: [hash], trustTier: 3 })\n } else if (!existing.hashes.includes(hash)) {\n next.set(namespace, { hashes: [...existing.hashes, hash], trustTier: existing.trustTier })\n }\n return next\n}\n\n/**\n * Return `true` if `hash` is in the approved list for `namespace`.\n * @internal\n */\nexport function isTrusted(manifest: TrustManifest, namespace: string, hash: string): boolean {\n const entry = manifest.get(namespace)\n if (entry === undefined) return false\n return entry.hashes.includes(hash)\n}\n","/**\n * Trust classification for executables.\n *\n * Tier 1 — Sigstore: cryptographic provenance verified via Sigstore (lazy import).\n * Tier 2 — Registry: hash found in the approved trust manifest.\n * Tier 3 — Unverified: default fallback when no stronger evidence is available.\n *\n * TOFU (Trust On First Use): on the first encounter with an executable the hash\n * is recorded. If the hash changes on a subsequent call a `tofuConflict` is\n * signalled so the caller can prompt for re-approval.\n *\n * Dev-mode bypass: when the executable path is the literal string `\"dev\"` all\n * hash verification is skipped and Tier 3 unverified is returned immediately.\n */\n\nimport { hashExecutable } from './hash.js'\nimport { loadManifest, saveManifest, addTrustedHash, isTrusted } from './manifest.js'\nimport type { TrustVerificationResult, TrustOptions } from './types.js'\n\n/** Attempt Sigstore bundle verification (Tier 1). Returns `true` on success. */\nasync function trySigstore(execPath: string): Promise<boolean> {\n try {\n // Dynamic import so the library works without sigstore installed.\n // @ts-expect-error — sigstore is an optional peer dependency not listed in\n // package.json; the import will fail at runtime if not installed, which is\n // the intended behaviour. We catch that case below.\n const sigstore: unknown = await import('sigstore')\n // sigstore.verify expects a bundle; for executable verification we check\n // whether the library is present and functional. If the import succeeds but\n // the verify function is not available we fall through gracefully.\n if (typeof sigstore !== 'object' || sigstore === null) {\n return false\n }\n if (!('verify' in sigstore) || typeof sigstore.verify !== 'function') {\n return false\n }\n // Executable bundles are not universally available; treat any error as a\n // Tier-1 failure rather than a hard error.\n void execPath // execPath would be used in a full Sigstore bundle lookup\n return false // Full Sigstore bundle verification not yet available for arbitrary binaries\n } catch {\n return false\n }\n}\n\n/**\n * Verify the trust tier of the executable at `execPath`.\n *\n * @param execPath - Path to the executable, or `\"dev\"` to enable dev-mode bypass.\n * @param options - Optional trust configuration.\n * @internal\n */\nexport async function verifyTrust(\n execPath: string,\n options?: TrustOptions,\n): Promise<TrustVerificationResult> {\n // Dev-mode bypass: skip all verification for the sentinel value \"dev\".\n if (execPath === 'dev') {\n return {\n identity: { hash: 'dev', trustTier: 3, verified: false },\n tofuConflict: false,\n reason: 'Dev mode — hash verification skipped',\n }\n }\n\n const configDir = options?.configDir ?? '.vaultkeeper'\n const namespace = options?.namespace ?? execPath\n\n // Compute the current hash of the executable.\n const currentHash = await hashExecutable(execPath)\n\n // Load the manifest for TOFU and registry checks.\n const manifest = await loadManifest(configDir)\n\n // --- Tier 1: Sigstore ---\n if (options?.skipSigstore !== true) {\n const sigstoreVerified = await trySigstore(execPath)\n if (sigstoreVerified) {\n const updated = addTrustedHash(manifest, namespace, currentHash)\n await saveManifest(configDir, updated)\n return {\n identity: { hash: currentHash, trustTier: 1, verified: true },\n tofuConflict: false,\n reason: 'Sigstore bundle verified',\n }\n }\n }\n\n // --- Tier 2: Registry (manifest) ---\n if (isTrusted(manifest, namespace, currentHash)) {\n return {\n identity: { hash: currentHash, trustTier: 2, verified: true },\n tofuConflict: false,\n reason: 'Hash found in trust manifest',\n }\n }\n\n // --- TOFU check ---\n const existing = manifest.get(namespace)\n if (existing !== undefined && existing.hashes.length > 0) {\n // The namespace is known but the current hash is not approved — TOFU conflict.\n return {\n identity: { hash: currentHash, trustTier: 3, verified: false },\n tofuConflict: true,\n reason: `Hash changed from a previously approved value — re-approval required`,\n }\n }\n\n // --- Tier 3: First encounter — record via TOFU ---\n const updated = addTrustedHash(manifest, namespace, currentHash)\n await saveManifest(configDir, updated)\n return {\n identity: { hash: currentHash, trustTier: 3, verified: false },\n tofuConflict: false,\n reason: 'First encounter — hash recorded via TOFU',\n }\n}\n","/**\n * Capability token management.\n *\n * Tokens are backed by a `WeakMap` whose keys are `CapabilityToken` instances,\n * so the actual claims are never reachable from outside this module. Private\n * class fields enforce that no property on the token object leaks data.\n */\n\nimport type { VaultClaims } from './types.js'\nimport { AuthorizationDeniedError } from '../errors.js'\n\n/** Opaque capability token. Claims are inaccessible without `validateCapabilityToken`. */\nexport class CapabilityToken {\n // Private field ensures no public surface leaks claims.\n readonly #brand: symbol\n\n constructor() {\n this.#brand = Symbol('CapabilityToken')\n }\n\n /**\n * Return a non-enumerable identifier for debugging purposes only.\n * Does NOT expose claims.\n */\n toString(): string {\n return `[CapabilityToken ${this.#brand.toString()}]`\n }\n}\n\n/** Internal storage for claims — inaccessible outside the module closure. */\nconst claimsStore = new WeakMap<CapabilityToken, VaultClaims>()\n\n/**\n * Create a capability token that wraps `claims`.\n * The claims are stored in a module-private `WeakMap` and cannot be reached\n * without calling `validateCapabilityToken`.\n * @internal\n */\nexport function createCapabilityToken(claims: VaultClaims): CapabilityToken {\n const token = new CapabilityToken()\n claimsStore.set(token, claims)\n return token\n}\n\n/**\n * Retrieve the `VaultClaims` associated with `token`.\n *\n * @throws {AuthorizationDeniedError} if the token was not created by\n * `createCapabilityToken` in this module (i.e. it has no claims entry\n * in the store).\n * @internal\n */\nexport function validateCapabilityToken(token: CapabilityToken): VaultClaims {\n const claims = claimsStore.get(token)\n if (claims === undefined) {\n throw new AuthorizationDeniedError('Invalid or unrecognized capability token')\n }\n return claims\n}\n","/**\n * Configuration loading, validation, and defaults for vaultkeeper.\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport type { VaultConfig, BackendConfig, TrustTier } from './types.js'\n\n/**\n * Return the platform-appropriate default config directory.\n * @internal\n */\nexport function getDefaultConfigDir(): string {\n const envOverride = process.env.VAULTKEEPER_CONFIG_DIR\n if (envOverride !== undefined && envOverride !== '') {\n return envOverride\n }\n if (process.platform === 'win32') {\n const appData = process.env.APPDATA\n if (appData !== undefined) {\n return path.join(appData, 'vaultkeeper')\n }\n return path.join(os.homedir(), 'AppData', 'Roaming', 'vaultkeeper')\n }\n return path.join(os.homedir(), '.config', 'vaultkeeper')\n}\n\n/** Default configuration when no config file exists. */\nfunction defaultConfig(): VaultConfig {\n return {\n version: 1,\n backends: [{ type: 'file', enabled: true }],\n keyRotation: { gracePeriodDays: 7 },\n defaults: { ttlMinutes: 60, trustTier: 3 },\n }\n}\n\n/**\n * Type guard for plain objects.\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Validates a backend config entry.\n */\nfunction validateBackendEntry(entry: unknown, index: number): BackendConfig {\n if (!isObject(entry)) {\n throw new Error(`backends[${String(index)}] must be an object`)\n }\n if (typeof entry.type !== 'string' || entry.type.trim() === '') {\n throw new Error(`backends[${String(index)}].type must be a non-empty string`)\n }\n if (typeof entry.enabled !== 'boolean') {\n throw new Error(`backends[${String(index)}].enabled must be a boolean`)\n }\n\n const result: BackendConfig = {\n type: entry.type,\n enabled: entry.enabled,\n }\n\n if (entry.plugin !== undefined) {\n if (typeof entry.plugin !== 'boolean') {\n throw new Error(`backends[${String(index)}].plugin must be a boolean`)\n }\n result.plugin = entry.plugin\n }\n\n if (entry.path !== undefined) {\n if (typeof entry.path !== 'string') {\n throw new Error(`backends[${String(index)}].path must be a string`)\n }\n result.path = entry.path\n }\n\n if (entry.options !== undefined) {\n if (!isObject(entry.options)) {\n throw new Error(`backends[${String(index)}].options must be an object`)\n }\n const opts: Record<string, string> = {}\n for (const [k, v] of Object.entries(entry.options)) {\n if (typeof v !== 'string') {\n throw new Error(\n `backends[${String(index)}].options[\"${k}\"] must be a string`,\n )\n }\n opts[k] = v\n }\n result.options = opts\n }\n\n return result\n}\n\n/**\n * Validate an unknown value as a VaultConfig, throwing on invalid structure.\n * @internal\n */\nexport function validateConfig(config: unknown): VaultConfig {\n if (!isObject(config)) {\n throw new Error('Config must be an object')\n }\n\n if (typeof config.version !== 'number' || config.version !== 1) {\n throw new Error('Config version must be 1')\n }\n\n if (!Array.isArray(config.backends) || config.backends.length === 0) {\n throw new Error('Config must have at least one backend')\n }\n\n const backends: BackendConfig[] = config.backends.map((entry: unknown, i: number) =>\n validateBackendEntry(entry, i),\n )\n\n if (!isObject(config.keyRotation)) {\n throw new Error('Config keyRotation must be an object')\n }\n if (\n typeof config.keyRotation.gracePeriodDays !== 'number' ||\n config.keyRotation.gracePeriodDays <= 0\n ) {\n throw new Error('Config keyRotation.gracePeriodDays must be a positive number')\n }\n\n if (!isObject(config.defaults)) {\n throw new Error('Config defaults must be an object')\n }\n if (typeof config.defaults.ttlMinutes !== 'number' || config.defaults.ttlMinutes <= 0) {\n throw new Error('Config defaults.ttlMinutes must be a positive number')\n }\n // Coerce string trust tier values from Rust CLI config (which serializes as \"1\"/\"2\"/\"3\")\n let tier: unknown = config.defaults.trustTier\n if (typeof tier === 'string') {\n const parsed = Number(tier)\n if (!Number.isNaN(parsed)) {\n tier = parsed\n }\n }\n if (tier !== 1 && tier !== 2 && tier !== 3) {\n throw new Error('Config defaults.trustTier must be 1, 2, or 3')\n }\n\n const result: VaultConfig = {\n version: 1,\n backends,\n keyRotation: {\n gracePeriodDays: config.keyRotation.gracePeriodDays,\n },\n defaults: {\n ttlMinutes: config.defaults.ttlMinutes,\n trustTier: tier satisfies TrustTier,\n },\n }\n\n if (config.developmentMode !== undefined) {\n if (!isObject(config.developmentMode)) {\n throw new Error('Config developmentMode must be an object')\n }\n if (!Array.isArray(config.developmentMode.executables)) {\n throw new Error('Config developmentMode.executables must be an array')\n }\n const executables: string[] = []\n for (const [i, exe] of Array.from(config.developmentMode.executables).entries()) {\n if (typeof exe !== 'string') {\n throw new Error(`Config developmentMode.executables[${String(i)}] must be a string`)\n }\n executables.push(exe)\n }\n result.developmentMode = { executables }\n }\n\n return result\n}\n\n/**\n * Load the vaultkeeper config from disk, falling back to defaults if the file\n * does not exist.\n *\n * @param configDir - Directory containing config.json. Defaults to platform-appropriate path.\n * @internal\n */\nexport async function loadConfig(configDir?: string): Promise<VaultConfig> {\n const dir = configDir ?? getDefaultConfigDir()\n const configPath = path.join(dir, 'config.json')\n\n let raw: string\n try {\n raw = await fs.readFile(configPath, 'utf-8')\n } catch {\n return defaultConfig()\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n throw new Error(`Failed to parse config file at ${configPath}`)\n }\n\n return validateConfig(parsed)\n}\n","/**\n * Key management for vaultkeeper, including generation, rotation, revocation,\n * and grace-period tracking.\n */\n\nimport * as crypto from 'node:crypto'\nimport { RotationInProgressError, SetupError } from '../errors.js'\nimport type { KeyMaterial, KeyState } from './types.js'\n\n/**\n * Manage cryptographic keys with rotation and grace-period semantics.\n * @internal\n */\nexport class KeyManager {\n #state: KeyState | undefined = undefined\n #gracePeriodTimer: ReturnType<typeof setTimeout> | undefined = undefined\n #gracePeriodExpiresAt: number | undefined = undefined\n #rotating = false\n\n /** Generate a new 32-byte key with a timestamp-based id. */\n generateKey(): KeyMaterial {\n const randomSuffix = crypto.randomBytes(4).toString('hex')\n return {\n id: `k-${String(Date.now())}-${randomSuffix}`,\n key: new Uint8Array(crypto.randomBytes(32)),\n createdAt: new Date(),\n }\n }\n\n /**\n * Initialize the manager with a freshly generated key.\n * Safe to call multiple times; subsequent calls are no-ops.\n */\n init(): Promise<void> {\n if (this.#state === undefined) {\n this.#state = { current: this.generateKey() }\n }\n return Promise.resolve()\n }\n\n /** Return the current (encryption) key. Throws if not initialized. */\n getCurrentKey(): KeyMaterial {\n const state = this.#requireState()\n return state.current\n }\n\n /**\n * Return the previous key if we are still inside a grace period,\n * otherwise `undefined`.\n */\n getPreviousKey(): KeyMaterial | undefined {\n const state = this.#requireState()\n return state.previous\n }\n\n /**\n * Find a key by its id, searching current then previous.\n * Returns `undefined` if the key is not found (or the previous key's\n * grace period has expired).\n */\n findKeyById(kid: string): KeyMaterial | undefined {\n const state = this.#requireState()\n if (state.current.id === kid) {\n return state.current\n }\n const { previous } = state\n if (previous?.id === kid) {\n // previous?.id === kid is only true when previous is defined and its id\n // matches, so we can safely return it here. TypeScript does not narrow\n // the optional-chain result back to KeyMaterial, so we guard explicitly.\n return previous\n }\n return undefined\n }\n\n /**\n * Rotate the current key: the current key becomes previous, a new key\n * becomes current. A grace-period timer is started; when it fires the\n * previous key is cleared automatically.\n *\n * @throws {RotationInProgressError} if a rotation is already underway.\n */\n rotateKey(gracePeriodMs: number): void {\n if (this.#rotating) {\n throw new RotationInProgressError('A key rotation is already in progress')\n }\n\n const state = this.#requireState()\n this.#rotating = true\n\n // Cancel any existing grace-period timer before starting a new rotation.\n this.#clearGracePeriodTimer()\n\n const newKey = this.generateKey()\n this.#state = { current: newKey, previous: state.current }\n this.#gracePeriodExpiresAt = Date.now() + gracePeriodMs\n\n this.#gracePeriodTimer = setTimeout(() => {\n if (this.#state !== undefined) {\n // Remove the previous key once the grace period elapses.\n this.#state = { current: this.#state.current }\n }\n this.#gracePeriodExpiresAt = undefined\n this.#gracePeriodTimer = undefined\n this.#rotating = false\n }, gracePeriodMs)\n\n // Allow the timer to be GC'd without keeping the process alive.\n if (typeof this.#gracePeriodTimer.unref === 'function') {\n this.#gracePeriodTimer.unref()\n }\n }\n\n /**\n * Emergency revocation: immediately clear the previous key and generate\n * a brand-new current key. Any in-flight grace period is cancelled.\n */\n revokeKey(): void {\n this.#clearGracePeriodTimer()\n this.#rotating = false\n this.#gracePeriodExpiresAt = undefined\n\n const newKey = this.generateKey()\n this.#state = { current: newKey }\n }\n\n /**\n * Return `true` while a rotation grace period is active (i.e. the previous\n * key is still accessible).\n */\n isInGracePeriod(): boolean {\n if (this.#gracePeriodExpiresAt === undefined) {\n return false\n }\n return Date.now() < this.#gracePeriodExpiresAt\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n #requireState(): KeyState {\n if (this.#state === undefined) {\n throw new SetupError(\n 'KeyManager has not been initialized — call init() first',\n 'KeyManager',\n )\n }\n return this.#state\n }\n\n #clearGracePeriodTimer(): void {\n if (this.#gracePeriodTimer !== undefined) {\n clearTimeout(this.#gracePeriodTimer)\n this.#gracePeriodTimer = undefined\n }\n }\n}\n","/**\n * JWE token creation and decryption using `jose` with `dir` + `A256GCM`.\n */\n\nimport { CompactEncrypt, compactDecrypt } from 'jose'\nimport type { VaultClaims } from '../types.js'\nimport { InvalidTokenError } from '../errors.js'\n\nconst ALGORITHM = 'dir'\nconst ENCRYPTION = 'A256GCM'\n\n/**\n * Options for token creation.\n * @internal\n */\nexport interface CreateTokenOptions {\n /** Optional key ID to embed in the JWE header for rotation tracking. */\n kid?: string | undefined\n}\n\n/**\n * Creates a compact JWE string from the given claims.\n *\n * Uses `dir` (direct key agreement) with `A256GCM` content encryption.\n * The 256-bit key must be exactly 32 bytes.\n *\n * @param key - 32-byte symmetric key (AES-256)\n * @param claims - VaultClaims payload to encrypt\n * @param options - Optional token creation options\n * @returns Compact JWE string\n * @internal\n */\nexport async function createToken(\n key: Uint8Array,\n claims: VaultClaims,\n options?: CreateTokenOptions,\n): Promise<string> {\n const plaintext = new TextEncoder().encode(JSON.stringify(claims))\n\n const header: { alg: typeof ALGORITHM; enc: typeof ENCRYPTION; kid?: string } = {\n alg: ALGORITHM,\n enc: ENCRYPTION,\n }\n\n if (options?.kid !== undefined) {\n header.kid = options.kid\n }\n\n return new CompactEncrypt(plaintext).setProtectedHeader(header).encrypt(key)\n}\n\n/**\n * Type guard that checks whether an unknown value is a non-null object.\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Parses a raw JSON payload object into VaultClaims, validating that all required fields\n * are present and of the correct types. Returns `undefined` if validation fails.\n */\nfunction parseVaultClaims(raw: unknown): VaultClaims | undefined {\n if (!isObject(raw)) {\n return undefined\n }\n\n const { jti, exp, iat, sub, exe, use, tid, bkd, val, ref } = raw\n\n if (typeof jti !== 'string') return undefined\n if (typeof exp !== 'number') return undefined\n if (typeof iat !== 'number') return undefined\n if (typeof sub !== 'string') return undefined\n if (typeof exe !== 'string') return undefined\n if (use !== null && typeof use !== 'number') return undefined\n if (tid !== 1 && tid !== 2 && tid !== 3) return undefined\n if (typeof bkd !== 'string') return undefined\n if (typeof val !== 'string') return undefined\n if (typeof ref !== 'string') return undefined\n\n return { jti, exp, iat, sub, exe, use: use ?? null, tid, bkd, val, ref }\n}\n\n/**\n * Decrypts a compact JWE string and returns the VaultClaims payload.\n *\n * @param key - 32-byte symmetric key (AES-256)\n * @param jwe - Compact JWE string to decrypt\n * @returns Decrypted VaultClaims\n * @throws VaultError if decryption fails or the payload is malformed\n * @internal\n */\nexport async function decryptToken(key: Uint8Array, jwe: string): Promise<VaultClaims> {\n let plaintext: Uint8Array\n try {\n const result = await compactDecrypt(jwe, key)\n plaintext = result.plaintext\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new InvalidTokenError(`JWE decryption failed: ${message}`)\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(new TextDecoder().decode(plaintext))\n } catch {\n throw new InvalidTokenError('JWE payload is not valid JSON')\n }\n\n const claims = parseVaultClaims(parsed)\n if (claims === undefined) {\n throw new InvalidTokenError('JWE payload does not match VaultClaims schema')\n }\n\n return claims\n}\n\n/**\n * Extracts the `kid` header from a compact JWE without decrypting it.\n *\n * The protected header in compact JWE is the first Base64URL-encoded segment.\n *\n * @param jwe - Compact JWE string\n * @returns The kid value, or undefined if not present\n * @throws VaultError if the JWE structure is invalid\n * @internal\n */\nexport function extractKid(jwe: string): string | undefined {\n const parts = jwe.split('.')\n if (parts.length !== 5) {\n throw new InvalidTokenError('Invalid JWE compact serialization: expected 5 parts')\n }\n const headerSegment = parts[0]\n if (headerSegment === undefined || headerSegment === '') {\n throw new InvalidTokenError('Invalid JWE compact serialization: missing header segment')\n }\n let headerJson: string\n try {\n headerJson = Buffer.from(headerSegment, 'base64url').toString('utf-8')\n } catch {\n throw new InvalidTokenError('Invalid JWE compact serialization: header is not valid Base64URL')\n }\n\n let header: unknown\n try {\n header = JSON.parse(headerJson)\n } catch {\n throw new InvalidTokenError('Invalid JWE compact serialization: header is not valid JSON')\n }\n\n if (!isObject(header)) {\n return undefined\n }\n\n const kid = header.kid\n if (typeof kid !== 'string') {\n return undefined\n }\n return kid\n}\n","/**\n * VaultClaims validation and in-memory token blocklist.\n */\n\nimport type { VaultClaims } from '../types.js'\nimport {\n TokenExpiredError,\n TokenRevokedError,\n UsageLimitExceededError,\n VaultError,\n} from '../errors.js'\n\n/**\n * Maximum number of JTIs the in-memory blocklist will retain.\n * When the cap is reached, the oldest inserted entry is evicted (FIFO/LRU).\n * This prevents unbounded growth for long-running processes.\n */\nconst BLOCKLIST_MAX_SIZE = 10_000\n\n/**\n * In-memory blocklist for revoked token JTIs. This is process-local and non-persistent.\n * For production use, a distributed blocklist (e.g., Redis) should be layered on top.\n *\n * A Map is used instead of a Set because Map preserves insertion order, which\n * allows O(1) eviction of the oldest entry (first key in iteration order).\n * The map values are always `true` — only the keys matter for lookup.\n */\nconst blocklist = new Map<string, true>()\n\n/**\n * Adds a JTI to the in-memory blocklist, preventing further use of that token.\n * If the blocklist has reached its maximum size, the oldest entry is evicted first.\n *\n * @param jti - The unique token ID to block\n * @internal\n */\nexport function blockToken(jti: string): void {\n if (blocklist.has(jti)) {\n // Already blocked — re-inserting would not change insertion order in Map,\n // so we delete and re-add to refresh the recency position.\n blocklist.delete(jti)\n } else if (blocklist.size >= BLOCKLIST_MAX_SIZE) {\n // Evict the oldest entry (first key in insertion-order iteration).\n const oldestKey = blocklist.keys().next().value\n if (oldestKey !== undefined) {\n blocklist.delete(oldestKey)\n }\n }\n blocklist.set(jti, true)\n}\n\n/**\n * Returns true if the given JTI has been blocked.\n *\n * @param jti - The unique token ID to check\n * @internal\n */\nexport function isBlocked(jti: string): boolean {\n return blocklist.has(jti)\n}\n\n/**\n * Clears all blocked JTIs from the in-memory blocklist.\n * Primarily intended for use in tests.\n * @internal\n */\nexport function clearBlocklist(): void {\n blocklist.clear()\n}\n\n/**\n * Validates all claims in a VaultClaims payload.\n * @internal\n *\n * Checks performed:\n * - Required fields present (jti, exp, iat, sub, exe, tid, bkd, val, ref)\n * - Token is not expired (exp vs. current time)\n * - Token is not on the blocklist\n * - Usage limit (use) is not exceeded if a positive limit is set\n * - Trust tier (tid) is valid (1, 2, or 3)\n *\n * @param claims - VaultClaims payload to validate\n * @param usedCount - How many times the token has been used already (for `use` limit checking)\n * @throws TokenExpiredError if the token is expired\n * @throws TokenRevokedError if the token has been blocked\n * @throws UsageLimitExceededError if the usage count has been exhausted\n * @throws VaultError for missing or malformed required fields\n */\nexport function validateClaims(claims: VaultClaims, usedCount = 0): void {\n // Validate required string fields are non-empty\n if (claims.jti.trim() === '') {\n throw new VaultError('Invalid token: jti must not be empty')\n }\n if (claims.sub.trim() === '') {\n throw new VaultError('Invalid token: sub must not be empty')\n }\n if (claims.exe.trim() === '') {\n throw new VaultError('Invalid token: exe must not be empty')\n }\n if (claims.bkd.trim() === '') {\n throw new VaultError('Invalid token: bkd must not be empty')\n }\n if (claims.val.trim() === '') {\n throw new VaultError('Invalid token: val must not be empty')\n }\n if (claims.ref.trim() === '') {\n throw new VaultError('Invalid token: ref must not be empty')\n }\n\n // Validate timestamp ordering\n if (claims.iat > claims.exp) {\n throw new VaultError('Invalid token: iat must not be after exp')\n }\n\n // Check expiration\n const nowSec = Math.floor(Date.now() / 1000)\n if (nowSec >= claims.exp) {\n throw new TokenExpiredError(\n `Token expired at ${String(claims.exp)} (now: ${String(nowSec)})`,\n false,\n )\n }\n\n // Check blocklist\n if (isBlocked(claims.jti)) {\n throw new TokenRevokedError(`Token ${claims.jti} has been revoked`)\n }\n\n // Check usage limit\n if (claims.use !== null) {\n if (claims.use <= 0) {\n throw new UsageLimitExceededError(\n `Token ${claims.jti} has a non-positive usage limit: ${String(claims.use)}`,\n )\n }\n if (usedCount >= claims.use) {\n throw new UsageLimitExceededError(\n `Token ${claims.jti} usage limit of ${String(claims.use)} exceeded (used: ${String(usedCount)})`,\n )\n }\n }\n}\n","/**\n * Delegated HTTP fetch access pattern.\n *\n * Replaces `{{secret}}` placeholders in the request URL, headers, and body\n * with the actual secret value, then executes the fetch.\n */\n\nimport type { FetchRequest } from '../types.js'\n\nconst PLACEHOLDER = '{{secret}}'\n\nfunction replacePlaceholder(value: string, secret: string): string {\n return value.replaceAll(PLACEHOLDER, secret)\n}\n\nfunction replaceInRecord(\n record: Record<string, string>,\n secret: string,\n): Record<string, string> {\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n result[key] = replacePlaceholder(value, secret)\n }\n return result\n}\n\n/**\n * Execute a delegated HTTP fetch with the secret injected into the request.\n *\n * @param secret - The secret value to inject\n * @param request - The fetch request template with `{{secret}}` placeholders\n * @returns The fetch Response\n * @internal\n */\nexport async function delegatedFetch(\n secret: string,\n request: FetchRequest,\n): Promise<Response> {\n const url = replacePlaceholder(request.url, secret)\n const headers =\n request.headers !== undefined\n ? replaceInRecord(request.headers, secret)\n : undefined\n const body =\n request.body !== undefined\n ? replacePlaceholder(request.body, secret)\n : undefined\n\n const init: RequestInit = {}\n if (request.method !== undefined) {\n init.method = request.method\n }\n if (headers !== undefined) {\n init.headers = headers\n }\n if (body !== undefined) {\n init.body = body\n }\n\n return fetch(url, init)\n}\n","/**\n * Delegated command execution access pattern.\n *\n * Replaces `{{secret}}` placeholders in command args and environment values,\n * then executes the command.\n */\n\nimport { spawn } from 'node:child_process'\nimport type { ExecRequest, ExecResult } from '../types.js'\nimport { ExecError } from '../errors.js'\n\nconst PLACEHOLDER = '{{secret}}'\n\nfunction replacePlaceholder(value: string, secret: string): string {\n return value.replaceAll(PLACEHOLDER, secret)\n}\n\nfunction replaceInRecord(\n record: Record<string, string>,\n secret: string,\n): Record<string, string> {\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n result[key] = replacePlaceholder(value, secret)\n }\n return result\n}\n\n/**\n * Execute a delegated command with the secret injected into args and env.\n *\n * @param secret - The secret value to inject\n * @param request - The exec request template with `{{secret}}` placeholders\n * @returns The command result (stdout, stderr, exitCode)\n * @internal\n */\nexport function delegatedExec(\n secret: string,\n request: ExecRequest,\n): Promise<ExecResult> {\n if (request.command.includes(PLACEHOLDER)) {\n throw new ExecError(\n `The {{secret}} placeholder is not supported in the command field. Use args or env instead.`,\n request.command,\n )\n }\n\n const args = (request.args ?? []).map((arg) => replacePlaceholder(arg, secret))\n const env =\n request.env !== undefined ? replaceInRecord(request.env, secret) : undefined\n\n return new Promise((resolve, reject) => {\n const spawnOptions: Parameters<typeof spawn>[2] = {\n stdio: ['ignore', 'pipe', 'pipe'],\n }\n if (env !== undefined) {\n spawnOptions.env = { ...process.env, ...env }\n }\n if (request.cwd !== undefined) {\n spawnOptions.cwd = request.cwd\n }\n\n const proc = spawn(request.command, args, spawnOptions)\n let stdout = ''\n let stderr = ''\n\n proc.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString()\n })\n\n proc.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString()\n })\n\n proc.on('close', (code) => {\n resolve({ stdout, stderr, exitCode: code ?? 1 })\n })\n\n proc.on('error', (error) => {\n const isEnoent = error instanceof Error && 'code' in error && error.code === 'ENOENT'\n if (isEnoent) {\n reject(\n new ExecError(\n `Command not found: ${request.command}. Verify the command exists and is in PATH.`,\n request.command,\n ),\n )\n } else {\n reject(\n new ExecError(\n `Failed to execute command: ${request.command}. ${error instanceof Error ? error.message : String(error)}`,\n request.command,\n ),\n )\n }\n })\n })\n}\n","/**\n * Controlled direct access pattern.\n *\n * Provides a `SecretAccessor` backed by a Proxy that:\n * - Exposes a single `.read()` method\n * - Passes a Buffer containing the secret to the callback\n * - Zeros the buffer after the callback returns\n * - Prevents double-read (throws a descriptive Error on second call)\n * - Redacts itself from Node.js inspect output\n */\n\nimport type { SecretAccessor } from '../types.js'\nimport { AccessorConsumedError } from '../errors.js'\n\nconst INSPECT_CUSTOM = Symbol.for('nodejs.util.inspect.custom')\n\n/** Extended accessor that also supports custom inspect. */\ninterface SecretAccessorInternal extends SecretAccessor {\n [INSPECT_CUSTOM](): string\n}\n\n/**\n * Proxy target class that satisfies SecretAccessorInternal.\n *\n * Instances have their prototype set to null and are made non-extensible\n * after construction, so all proxy invariants can be met consistently:\n * - getPrototypeOf trap returns null (matches actual prototype)\n * - isExtensible trap returns false (matches actual extensibility)\n * - ownKeys trap includes all own keys (matches non-extensible contract)\n */\nclass SecretAccessorTarget implements SecretAccessorInternal {\n readonly read: (callback: (buf: Buffer) => void) => void\n readonly [INSPECT_CUSTOM]: () => string\n\n constructor(\n readImpl: (callback: (buf: Buffer) => void) => void,\n inspectImpl: () => string,\n ) {\n this.read = readImpl\n this[INSPECT_CUSTOM] = inspectImpl\n }\n}\n\n/**\n * Create a `SecretAccessor` for the given secret value.\n * @internal\n *\n * The accessor is backed by a Proxy with all 13 traps implemented. The\n * `consumed` flag blocks re-execution after the first `read()` call, and the\n * buffer containing the secret is zeroed in the `finally` block regardless of\n * whether the callback throws. No proxy revocation is used: the `consumed`\n * flag already prevents double-reads, and revocation would surface a raw V8\n * `TypeError: Cannot perform 'get' on a proxy that has been revoked` before\n * the descriptive error message can be thrown.\n */\nexport function createSecretAccessor(secretValue: string): SecretAccessor {\n let consumed = false\n\n // Close over the actual read logic.\n function readImpl(callback: (buf: Buffer) => void): void {\n if (consumed) {\n throw new AccessorConsumedError('SecretAccessor has already been consumed — call getSecret() again to obtain a new accessor')\n }\n consumed = true\n\n const buf = Buffer.from(secretValue, 'utf8')\n try {\n callback(buf)\n } finally {\n buf.fill(0)\n }\n }\n\n function inspectImpl(): string {\n return '[SecretAccessor]'\n }\n\n // Build the proxy target: a class instance with null prototype and\n // non-extensible to satisfy V8's proxy invariants for those traps.\n const target = new SecretAccessorTarget(readImpl, inspectImpl)\n Object.setPrototypeOf(target, null)\n Object.preventExtensions(target)\n\n // All 13 proxy handler traps.\n const handler: Required<ProxyHandler<SecretAccessorInternal>> = {\n get(_t, prop, _receiver) {\n if (prop === 'read') return readImpl\n if (prop === INSPECT_CUSTOM) return inspectImpl\n return undefined\n },\n set(_t, _prop, _value, _receiver) {\n return false\n },\n has(_t, prop) {\n return prop === 'read' || prop === INSPECT_CUSTOM\n },\n deleteProperty(_t, _prop) {\n return false\n },\n apply(_t, _thisArg, _args) {\n throw new TypeError('SecretAccessor is not a function')\n },\n construct(_t, _args, _newTarget) {\n throw new TypeError('SecretAccessor is not a constructor')\n },\n defineProperty(_t, _prop, _descriptor) {\n return false\n },\n getOwnPropertyDescriptor(_t, prop) {\n if (prop === 'read') {\n return { configurable: true, enumerable: true, writable: false, value: readImpl }\n }\n if (prop === INSPECT_CUSTOM) {\n return { configurable: true, enumerable: false, writable: false, value: inspectImpl }\n }\n return undefined\n },\n getPrototypeOf(_t) {\n // Null prototype — matches the actual target prototype after setPrototypeOf(target, null).\n return null\n },\n setPrototypeOf(_t, _proto) {\n return false\n },\n isExtensible(_t) {\n // Non-extensible — matches the actual target extensibility.\n return false\n },\n preventExtensions(_t) {\n // Already non-extensible — trap returns true (success) matching target state.\n return true\n },\n ownKeys(_t) {\n // Must include all own keys of the non-extensible target.\n // The target has 'read' and INSPECT_CUSTOM as own properties.\n return ['read', INSPECT_CUSTOM]\n },\n }\n\n return new Proxy(target, handler)\n}\n","/**\n * Shared algorithm resolution for signing and verification.\n * @internal\n */\n\nimport type { KeyObject } from 'node:crypto'\nimport { InvalidAlgorithmError } from '../errors.js'\n\n/**\n * Allowlist of hash algorithms accepted for non-Edwards keys.\n * Prevents algorithm downgrade attacks (e.g. callers requesting `'md5'`).\n * @internal\n */\nconst ALLOWED_ALGORITHMS = new Set(['sha256', 'sha384', 'sha512'])\n\n/**\n * Resolve the algorithm parameter for `crypto.sign()` / `crypto.verify()`\n * based on the key type.\n *\n * Ed25519 / Ed448 keys use `null` (the algorithm is implicit in the key).\n * RSA and EC keys default to `'sha256'` unless overridden.\n *\n * @param key - The key object to inspect\n * @param override - Caller-provided algorithm override (ignored for Edwards curves)\n * @returns `signAlg` is passed to the Node.js crypto API; `label` is the\n * human-readable algorithm name returned to the caller.\n * @throws {InvalidAlgorithmError} If `override` is not in the allowed algorithm set.\n * @internal\n */\nexport function resolveAlgorithmForKey(\n key: KeyObject,\n override: string | undefined,\n): { signAlg: string | null; label: string } {\n const keyType = key.asymmetricKeyType\n if (keyType === 'ed25519' || keyType === 'ed448') {\n return { signAlg: null, label: keyType }\n }\n const alg = (override ?? 'sha256').toLowerCase()\n if (!ALLOWED_ALGORITHMS.has(alg)) {\n throw new InvalidAlgorithmError(\n `Unsupported algorithm '${alg}'. Allowed: ${[...ALLOWED_ALGORITHMS].join(', ')}`,\n alg,\n [...ALLOWED_ALGORITHMS],\n )\n }\n return { signAlg: alg, label: alg }\n}\n","/**\n * Delegated signing access pattern.\n *\n * Receives a PEM-encoded private key from VaultKeeper internals,\n * creates a signature over the provided data, and returns the\n * base64-encoded signature. The key is not exposed to the caller —\n * it flows in but does not flow out.\n */\n\nimport * as crypto from 'node:crypto'\nimport type { SignRequest, SignResult } from '../types.js'\nimport { resolveAlgorithmForKey } from './sign-util.js'\n\n/**\n * Sign data using a PEM-encoded private key.\n *\n * @param secretPem - PEM-encoded private key (from `claims.val`)\n * @param request - The sign request (data + optional algorithm override)\n * @returns Base64-encoded signature and the algorithm used\n * @internal\n */\nexport function delegatedSign(\n secretPem: string,\n request: SignRequest,\n): SignResult {\n // Note: `secretPem` is a JS string and cannot be zeroed. This is consistent\n // with how `delegatedFetch` and `delegatedExec` handle `claims.val`. Node.js\n // `KeyObject` also does not expose a zeroing API.\n const key = crypto.createPrivateKey(secretPem)\n const { signAlg, label } = resolveAlgorithmForKey(key, request.algorithm)\n\n const data = Buffer.isBuffer(request.data)\n ? request.data\n : Buffer.from(request.data)\n const signature = crypto.sign(signAlg, data, key)\n\n return {\n signature: signature.toString('base64'),\n algorithm: label,\n }\n}\n","/**\n * Delegated verification utility.\n *\n * Verifies a signature against public key material. This is a static\n * utility — no secrets are involved, so it does not require a VaultKeeper\n * instance or capability token.\n */\n\nimport * as crypto from 'node:crypto'\nimport type { VerifyRequest } from '../types.js'\nimport { resolveAlgorithmForKey } from './sign-util.js'\n\n/**\n * Verify a signature using a public key.\n *\n * Returns `false` for invalid key material, malformed signatures, or any\n * verification failure. The one exception is disallowed algorithms (e.g.\n * `'md5'`, `'sha1'`), which throw {@link InvalidAlgorithmError} so that\n * callers cannot silently downgrade to a weak hash.\n *\n * @param request - The verify request (data, signature, publicKey, optional algorithm)\n * @returns `true` if the signature is valid, `false` otherwise\n * @throws {InvalidAlgorithmError} If `request.algorithm` is not in the allowed set.\n * @internal\n */\nexport function delegatedVerify(request: VerifyRequest): boolean {\n // Invalid key material or malformed signatures are treated as verification\n // failures (return false) rather than thrown errors. Disallowed algorithms\n // are the deliberate exception — see resolveAlgorithmForKey below.\n let key: crypto.KeyObject\n try {\n key = crypto.createPublicKey(request.publicKey)\n } catch {\n return false\n }\n\n // Reject private key material passed as publicKey — crypto.createPublicKey()\n // silently derives the public component from a private key PEM, which could\n // mask a consumer misconfiguration. We check the raw PEM text because\n // createPublicKey() converts private keys to public KeyObjects transparently.\n if (typeof request.publicKey === 'string' && request.publicKey.includes('PRIVATE KEY')) {\n return false\n }\n\n // NOTE: resolveAlgorithmForKey throws for disallowed algorithms (e.g. 'md5').\n // That error must propagate — do NOT wrap this call in a try/catch.\n const { signAlg } = resolveAlgorithmForKey(key, request.algorithm)\n const sig = Buffer.from(request.signature, 'base64')\n\n try {\n const data = Buffer.isBuffer(request.data)\n ? request.data\n : Buffer.from(request.data)\n return crypto.verify(signAlg, data, key, sig)\n } catch {\n return false\n }\n}\n","/**\n * Individual preflight check functions for each system dependency.\n */\n\nimport { execCommand } from '../util/exec.js'\nimport type { PreflightCheck } from '../types.js'\n\n/**\n * Parse a semver-like version string and return [major, minor, patch].\n * Returns null if unparseable.\n */\nfunction parseVersion(raw: string): [number, number, number] | null {\n const match = /(\\d+)\\.(\\d+)\\.(\\d+)/.exec(raw)\n if (!match) return null\n const major = parseInt(match[1] ?? '0', 10)\n const minor = parseInt(match[2] ?? '0', 10)\n const patch = parseInt(match[3] ?? '0', 10)\n return [major, minor, patch]\n}\n\n/**\n * Returns true if [aMajor, aMinor, aPatch] >= [bMajor, bMinor, bPatch].\n */\nfunction versionGte(\n a: [number, number, number],\n b: [number, number, number],\n): boolean {\n if (a[0] !== b[0]) return a[0] > b[0]\n if (a[1] !== b[1]) return a[1] > b[1]\n return a[2] >= b[2]\n}\n\n/**\n * Check that openssl is present and >= 1.1.1.\n * @internal\n */\nexport async function checkOpenssl(): Promise<PreflightCheck> {\n const name = 'openssl'\n try {\n const output = await execCommand('openssl', ['version'])\n const parsed = parseVersion(output)\n if (!parsed) {\n return {\n name,\n status: 'version-unsupported',\n version: output,\n reason: 'Could not parse openssl version',\n }\n }\n if (!versionGte(parsed, [1, 1, 1])) {\n return {\n name,\n status: 'version-unsupported',\n version: output,\n reason: 'openssl >= 1.1.1 is required',\n }\n }\n return { name, status: 'ok', version: output }\n } catch {\n return { name, status: 'missing', reason: 'openssl not found in PATH' }\n }\n}\n\n/**\n * Check that bash is present.\n * @internal\n */\nexport async function checkBash(): Promise<PreflightCheck> {\n const name = 'bash'\n try {\n const output = await execCommand('bash', ['--version'])\n const firstLine = output.split('\\n')[0] ?? output\n return { name, status: 'ok', version: firstLine }\n } catch {\n return { name, status: 'missing', reason: 'bash not found in PATH' }\n }\n}\n\n/**\n * Check that PowerShell is present (Windows only).\n * @internal\n */\nexport async function checkPowershell(): Promise<PreflightCheck> {\n const name = 'powershell'\n try {\n const output = await execCommand('powershell', [\n '-Command',\n '$PSVersionTable.PSVersion',\n ])\n const version = output.trim()\n return { name, status: 'ok', version }\n } catch {\n return { name, status: 'missing', reason: 'powershell not found in PATH' }\n }\n}\n\n/**\n * Check that macOS security CLI is present (macOS only, for Keychain access).\n * @internal\n */\nexport async function checkSecurity(): Promise<PreflightCheck> {\n const name = 'security'\n try {\n // `security help` exits with non-zero but writes to stderr; we only need it to exist\n await execCommand('security', ['help'])\n return { name, status: 'ok' }\n } catch (err) {\n // security help exits non-zero intentionally — if we got stderr output, it's present\n const message = err instanceof Error ? err.message : String(err)\n if (message.includes('security')) {\n // The command exists but help exits with a non-zero code\n return { name, status: 'ok' }\n }\n return {\n name,\n status: 'missing',\n reason: 'security command not found in PATH',\n }\n }\n}\n\n/**\n * Check that secret-tool is present (Linux only).\n * @internal\n */\nexport async function checkSecretTool(): Promise<PreflightCheck> {\n const name = 'secret-tool'\n try {\n const output = await execCommand('secret-tool', ['--version'])\n return { name, status: 'ok', version: output.trim() }\n } catch {\n return {\n name,\n status: 'missing',\n reason: 'secret-tool not found in PATH (install libsecret-tools)',\n }\n }\n}\n\n/**\n * Check that 1Password CLI (op) is present (optional).\n * @internal\n */\nexport async function checkOp(): Promise<PreflightCheck> {\n const name = 'op'\n try {\n const output = await execCommand('op', ['--version'])\n return { name, status: 'ok', version: output.trim() }\n } catch {\n return {\n name,\n status: 'missing',\n reason: 'op (1Password CLI) not found in PATH',\n }\n }\n}\n\n/**\n * Check that ykman (YubiKey Manager CLI) is present (optional).\n * @internal\n */\nexport async function checkYkman(): Promise<PreflightCheck> {\n const name = 'ykman'\n try {\n const output = await execCommand('ykman', ['--version'])\n return { name, status: 'ok', version: output.trim() }\n } catch {\n return {\n name,\n status: 'missing',\n reason: 'ykman (YubiKey Manager) not found in PATH',\n }\n }\n}\n","/**\n * Platform detection utilities.\n */\n\n/**\n * The OS platform identifier used for platform-specific behavior.\n * @public\n */\nexport type Platform = 'darwin' | 'win32' | 'linux'\n\n/** Get the current platform. */\nexport function currentPlatform(): Platform {\n const p = process.platform\n if (p === 'darwin' || p === 'win32' || p === 'linux') {\n return p\n }\n throw new Error(`Unsupported platform: ${p}`)\n}\n\n/** Check if running on macOS. */\nexport function isDarwin(): boolean {\n return process.platform === 'darwin'\n}\n\n/** Check if running on Windows. */\nexport function isWindows(): boolean {\n return process.platform === 'win32'\n}\n\n/** Check if running on Linux. */\nexport function isLinux(): boolean {\n return process.platform === 'linux'\n}\n","/**\n * Doctor runner: orchestrates platform-appropriate checks and aggregates results.\n */\n\nimport {\n checkOpenssl,\n checkBash,\n checkPowershell,\n checkSecurity,\n checkSecretTool,\n checkOp,\n checkYkman,\n} from './checks.js'\nimport { currentPlatform } from '../util/platform.js'\nimport type { BackendConfig, PreflightCheck, PreflightResult } from '../types.js'\nimport type { Platform } from '../util/platform.js'\n\n/**\n * Options for running the doctor.\n * @public\n */\nexport interface RunDoctorOptions {\n /** Override the platform detection (useful for testing). */\n platform?: Platform\n /**\n * When provided, doctor checks are scoped to the given backends.\n * Platform-native dependency checks (e.g. `secret-tool`, `security`,\n * `powershell`) are demoted from required to optional when the\n * corresponding backend is not enabled. Plugin tool checks (`op`,\n * `ykman`) are promoted from optional to required when their backend\n * (`1password`, `yubikey`) is explicitly enabled.\n *\n * When omitted, all platform-default checks are treated as required\n * (backward-compatible behavior).\n */\n backends?: BackendConfig[]\n}\n\n/** A doctor check entry pairing the check function with whether it is required. */\ninterface CheckEntry {\n check: () => Promise<PreflightCheck>\n required: boolean\n}\n\n/** Aggregated check entry with its result. */\ninterface ResolvedEntry {\n required: boolean\n result: PreflightCheck\n}\n\n/**\n * Run all platform-appropriate preflight checks and aggregate the results.\n * @public\n */\nexport async function runDoctor(options?: RunDoctorOptions): Promise<PreflightResult> {\n let platform: Platform\n try {\n platform = options?.platform ?? currentPlatform()\n } catch {\n return {\n checks: [],\n ready: false,\n warnings: [],\n nextSteps: ['Unsupported platform. vaultkeeper supports macOS, Linux, and Windows.'],\n }\n }\n\n const enabledTypes = enabledBackendTypes(options?.backends)\n const entries: CheckEntry[] = buildCheckList(platform, enabledTypes)\n\n const resolved: ResolvedEntry[] = await Promise.all(\n entries.map(async ({ check, required }) => {\n const result = await check()\n return { required, result }\n }),\n )\n\n const ready = resolved.every(({ required, result }) => {\n if (!required) return true\n return result.status === 'ok'\n })\n\n const warnings: string[] = []\n const nextSteps: string[] = []\n\n for (const { required, result } of resolved) {\n const reasonSuffix = result.reason !== undefined ? ` — ${result.reason}` : ''\n\n if (result.status === 'missing') {\n if (required) {\n nextSteps.push(`Install missing required dependency: ${result.name}${reasonSuffix}`)\n } else {\n warnings.push(`Optional dependency not found: ${result.name}${reasonSuffix}`)\n }\n } else if (result.status === 'version-unsupported') {\n const msg = `${result.name} version is unsupported${reasonSuffix}`\n if (required) {\n nextSteps.push(`Upgrade required dependency: ${msg}`)\n } else {\n warnings.push(`Optional dependency version unsupported: ${msg}`)\n }\n }\n }\n\n const checks = resolved.map(({ result }) => result)\n\n return { checks, ready, warnings, nextSteps }\n}\n\n/**\n * Extract the set of enabled backend type strings from the config.\n * Returns `null` when no backend list was provided, signalling that the\n * caller should fall back to platform defaults (backward-compatible).\n */\nfunction enabledBackendTypes(\n backends: BackendConfig[] | undefined,\n): Set<string> | null {\n if (backends === undefined) return null\n const types = new Set<string>()\n for (const b of backends) {\n if (b.enabled) types.add(b.type)\n }\n return types\n}\n\nfunction buildCheckList(\n platform: Platform,\n enabledTypes: Set<string> | null,\n): CheckEntry[] {\n // Core checks are always required regardless of backends.\n const entries: CheckEntry[] = [{ check: checkOpenssl, required: true }]\n\n if (platform === 'darwin') {\n // `security` is required only if keychain backend is configured (or no\n // backend list was provided, preserving backward-compatible defaults).\n entries.push({\n check: checkSecurity,\n required: enabledTypes === null || enabledTypes.has('keychain'),\n })\n entries.push({ check: checkBash, required: false })\n } else if (platform === 'win32') {\n entries.push({\n check: checkPowershell,\n required: enabledTypes === null || enabledTypes.has('dpapi'),\n })\n } else {\n // linux\n entries.push({ check: checkBash, required: true })\n entries.push({\n check: checkSecretTool,\n required: enabledTypes === null || enabledTypes.has('secret-tool'),\n })\n }\n\n // Plugin backend tools — required only if the corresponding backend is\n // explicitly enabled; otherwise optional (informational).\n entries.push({\n check: checkOp,\n required: enabledTypes?.has('1password') ?? false,\n })\n entries.push({\n check: checkYkman,\n required: enabledTypes?.has('yubikey') ?? false,\n })\n\n return entries\n}\n","/**\n * VaultKeeper main class — wires together all vaultkeeper subsystems.\n */\n\nimport * as crypto from 'node:crypto'\nimport type {\n VaultConfig,\n VaultClaims,\n VaultResponse,\n FetchRequest,\n ExecRequest,\n ExecResult,\n SecretAccessor,\n PreflightResult,\n TrustTier,\n SignRequest,\n SignResult,\n VerifyRequest,\n} from './types.js'\nimport { loadConfig, getDefaultConfigDir } from './config.js'\nimport { KeyManager } from './keys/manager.js'\nimport { BackendRegistry } from './backend/registry.js'\nimport type { SecretBackend } from './backend/types.js'\nimport { createToken, decryptToken, extractKid, validateClaims, blockToken } from './jwe/index.js'\nimport { verifyTrust } from './identity/trust.js'\nimport {\n CapabilityToken,\n createCapabilityToken,\n validateCapabilityToken,\n} from './identity/session.js'\nimport { delegatedFetch } from './access/delegated-fetch.js'\nimport { delegatedExec } from './access/delegated-exec.js'\nimport { createSecretAccessor } from './access/controlled-direct.js'\nimport { delegatedSign } from './access/delegated-sign.js'\nimport { delegatedVerify } from './access/delegated-verify.js'\nimport { runDoctor } from './doctor/runner.js'\nimport type { RunDoctorOptions } from './doctor/runner.js'\nimport {\n IdentityMismatchError,\n BackendUnavailableError,\n VaultError,\n KeyRevokedError,\n} from './errors.js'\n\n/** Options for initializing VaultKeeper. */\nexport interface VaultKeeperOptions {\n /** Override the config directory. */\n configDir?: string | undefined\n /** Supply config directly, skipping file load. */\n config?: VaultConfig | undefined\n /** Skip the doctor preflight check. */\n skipDoctor?: boolean | undefined\n}\n\n/** Options for the setup operation. */\nexport interface SetupOptions {\n /** TTL in minutes for the JWE. */\n ttlMinutes?: number | undefined\n /** Usage limit (null for unlimited). */\n useLimit?: number | null | undefined\n /** Executable path for identity binding. Use \"dev\" for dev mode. */\n executablePath?: string | undefined\n /** Trust tier override. */\n trustTier?: TrustTier | undefined\n /** Backend type to use. */\n backendType?: string | undefined\n}\n\n/** Usage tracking for tokens with use limits. */\nconst usageCounts = new Map<string, number>()\n\n/**\n * Maximum number of JTIs the in-memory usage-count map will retain.\n * When the cap is reached, the oldest inserted entry is evicted (FIFO).\n * This prevents unbounded growth for long-running processes.\n */\nconst USAGE_MAP_MAX_SIZE = 10_000\n\n/**\n * Main entry point for vaultkeeper. Orchestrates backends, keys, JWE tokens,\n * identity verification, and access patterns.\n */\nexport class VaultKeeper {\n readonly #config: VaultConfig\n readonly #keyManager: KeyManager\n readonly #configDir: string\n #backend: SecretBackend | undefined\n\n private constructor(config: VaultConfig, keyManager: KeyManager, configDir: string) {\n this.#config = config\n this.#keyManager = keyManager\n this.#configDir = configDir\n }\n\n /**\n * Initialize a new VaultKeeper instance.\n * Runs doctor checks (unless skipped), loads config, and sets up the key manager.\n */\n static async init(options?: VaultKeeperOptions): Promise<VaultKeeper> {\n const configDir = options?.configDir ?? getDefaultConfigDir()\n const config = options?.config ?? (await loadConfig(configDir))\n\n if (options?.skipDoctor !== true) {\n const doctorResult = await runDoctor({ backends: config.backends })\n if (!doctorResult.ready) {\n throw new VaultError(\n `System not ready: ${doctorResult.nextSteps.join('; ')}`,\n )\n }\n }\n\n const keyManager = new KeyManager()\n await keyManager.init()\n\n const vault = new VaultKeeper(config, keyManager, configDir)\n vault.#backend = vault.#resolveBackend()\n\n return vault\n }\n\n /**\n * Run doctor checks without full initialization.\n *\n * When called without arguments, uses conservative platform defaults —\n * all platform-native dependency checks are treated as required. Pass\n * `{ backends }` to scope checks to only the backends you plan to use.\n *\n * @param options - Optional doctor options (e.g. `{ backends }` to scope checks).\n */\n static async doctor(options?: RunDoctorOptions): Promise<PreflightResult> {\n return runDoctor(options)\n }\n\n /**\n * Store a secret in the configured backend.\n *\n * This is a convenience method that delegates to the active backend's\n * `store()` method. If a secret with the same name already exists, it is\n * overwritten.\n *\n * @param name - Identifier for the secret.\n * @param value - The secret value to store.\n * @public\n */\n async store(name: string, value: string): Promise<void> {\n VaultKeeper.#validateSecretName(name)\n const backend = this.#requireBackend()\n await backend.store(name, value)\n }\n\n /**\n * Delete a secret from the configured backend.\n *\n * This is a convenience method that delegates to the active backend's\n * `delete()` method.\n *\n * @param name - Identifier for the secret to delete.\n * @public\n */\n async delete(name: string): Promise<void> {\n VaultKeeper.#validateSecretName(name)\n const backend = this.#requireBackend()\n await backend.delete(name)\n }\n\n /**\n * Read a stored secret from the backend and mint a JWE token that encapsulates it.\n *\n * @param secretName - Identifier for the secret\n * @param options - Setup options\n * @returns Compact JWE string\n */\n async setup(secretName: string, options?: SetupOptions): Promise<string> {\n VaultKeeper.#validateSecretName(secretName)\n const backend = this.#requireBackend()\n const backendType = options?.backendType ?? backend.type\n const ttlMinutes = options?.ttlMinutes ?? this.#config.defaults.ttlMinutes\n const trustTier = options?.trustTier ?? this.#config.defaults.trustTier\n const useLimit = options?.useLimit ?? null\n const executablePath = options?.executablePath ?? 'dev'\n\n const secretValue = await backend.retrieve(secretName)\n\n let exeIdentity: string\n if (executablePath === 'dev' || this.#isDevModeExecutable(executablePath)) {\n exeIdentity = 'dev'\n } else {\n const trustResult = await verifyTrust(executablePath, {\n configDir: this.#configDir,\n })\n if (trustResult.tofuConflict) {\n throw new IdentityMismatchError(\n 'Executable hash changed — re-approval required',\n 'previously-approved',\n trustResult.identity.hash,\n )\n }\n exeIdentity = trustResult.identity.hash\n }\n\n const now = Math.floor(Date.now() / 1000)\n const claims: VaultClaims = {\n jti: crypto.randomUUID(),\n exp: now + ttlMinutes * 60,\n iat: now,\n sub: secretName,\n exe: exeIdentity,\n use: useLimit,\n tid: trustTier,\n bkd: backendType,\n val: secretValue,\n ref: secretName,\n }\n\n const currentKey = this.#keyManager.getCurrentKey()\n return createToken(currentKey.key, claims, { kid: currentKey.id })\n }\n\n /**\n * Decrypt a JWE, validate claims, verify executable identity, and return\n * an opaque CapabilityToken.\n *\n * @param jwe - Compact JWE string from setup()\n * @returns Object containing an opaque {@link CapabilityToken} for use with\n * fetch/exec/getSecret, and a {@link VaultResponse} describing key status.\n * When the JWE was decrypted with a non-current key,\n * `vaultResponse.rotatedJwt` contains a re-encrypted JWE for the current key.\n */\n async authorize(jwe: string): Promise<{ token: CapabilityToken; vaultResponse: VaultResponse }> {\n const kid = extractKid(jwe)\n const { claims, keyStatus } = await this.#decryptWithKeyResolution(jwe, kid)\n\n // Validate claims (expiry, blocklist, usage)\n const jti = claims.jti\n const currentCount = usageCounts.get(jti) ?? 0\n validateClaims(claims, currentCount)\n\n // Only track usage for tokens with a finite use limit. Unlimited tokens\n // (claims.use === null) never need count checks, so tracking them would\n // waste memory and cause unnecessary evictions of limited-token entries.\n if (claims.use !== null) {\n const newCount = currentCount + 1\n usageCounts.set(jti, newCount)\n\n // Evict the oldest entry when the map exceeds its size cap to prevent\n // unbounded memory growth in long-running processes. Block the evicted\n // JTI so that it cannot be silently re-authorized with a reset count.\n if (usageCounts.size > USAGE_MAP_MAX_SIZE) {\n const oldest = usageCounts.keys().next().value\n if (oldest !== undefined) {\n usageCounts.delete(oldest)\n blockToken(oldest)\n }\n }\n }\n\n const token = createCapabilityToken(claims)\n\n const vaultResponse: VaultResponse = { keyStatus }\n if (keyStatus === 'previous') {\n // Re-encrypt with current key\n const currentKey = this.#keyManager.getCurrentKey()\n const rotatedJwt = await createToken(currentKey.key, claims, { kid: currentKey.id })\n vaultResponse.rotatedJwt = rotatedJwt\n }\n\n return { token, vaultResponse }\n }\n\n /**\n * Execute a delegated HTTP fetch, injecting the secret from the token.\n *\n * The secret value is substituted for every `{{secret}}` placeholder found\n * in `request.url`, `request.headers`, and `request.body` before the fetch\n * is executed. The raw secret is never exposed in the return value.\n *\n * @param token - A `CapabilityToken` obtained from `authorize()`.\n * @param request - The fetch request template. Use `{{secret}}` as a\n * placeholder wherever the secret value should be injected.\n * @returns The `Response` from the underlying `fetch()` call, together with\n * the vault metadata (`vaultResponse`).\n * @throws {Error} If `token` is invalid or was not created by this vault\n * instance.\n */\n async fetch(\n token: CapabilityToken,\n request: FetchRequest,\n ): Promise<{ response: Response; vaultResponse: VaultResponse }> {\n const claims = validateCapabilityToken(token)\n const response = await delegatedFetch(claims.val, request)\n return {\n response,\n vaultResponse: { keyStatus: 'current' },\n }\n }\n\n /**\n * Execute a delegated command, injecting the secret from the token.\n *\n * The secret value is substituted for every `{{secret}}` placeholder found\n * in `request.args` and `request.env` values before the process is spawned.\n * The raw secret is never exposed in the return value.\n *\n * @param token - A `CapabilityToken` obtained from `authorize()`.\n * @param request - The exec request template. Use `{{secret}}` as a\n * placeholder wherever the secret value should be injected.\n * @returns The command result (`stdout`, `stderr`, `exitCode`) together with\n * the vault metadata (`vaultResponse`).\n * @throws {Error} If `token` is invalid or was not created by this vault\n * instance.\n */\n async exec(\n token: CapabilityToken,\n request: ExecRequest,\n ): Promise<{ result: ExecResult; vaultResponse: VaultResponse }> {\n const claims = validateCapabilityToken(token)\n const result = await delegatedExec(claims.val, request)\n return {\n result,\n vaultResponse: { keyStatus: 'current' },\n }\n }\n\n /**\n * Create a controlled-direct `SecretAccessor` from a capability token.\n *\n * The accessor wraps the secret in a single-use, auto-zeroing `Buffer`. The\n * secret is accessible only through the `read()` callback and is zeroed\n * immediately after the callback returns.\n *\n * @param token - A `CapabilityToken` obtained from `authorize()`.\n * @returns A `SecretAccessor` that can be read exactly once.\n * @throws {Error} If `token` is invalid or was not created by this vault\n * instance.\n */\n getSecret(token: CapabilityToken): SecretAccessor {\n const claims = validateCapabilityToken(token)\n return createSecretAccessor(claims.val)\n }\n\n /**\n * Sign data using the private key embedded in a capability token.\n *\n * The signing key is extracted from the token's encrypted claims, used\n * for a single `crypto.sign()` call, and never exposed to the caller.\n * The algorithm is auto-detected from the key type unless overridden\n * in the request.\n *\n * @param token - A `CapabilityToken` obtained from `authorize()`.\n * @param request - The data to sign and optional algorithm override.\n * @returns The base64-encoded signature and algorithm label, together\n * with the vault metadata (`vaultResponse`).\n * @throws {VaultError} If `token` is invalid or was not created by this\n * vault instance.\n * @throws {InvalidAlgorithmError} If `request.algorithm` is not in the\n * allowed set (e.g. `'md5'`).\n */\n async sign(\n token: CapabilityToken,\n request: SignRequest,\n ): Promise<{ result: SignResult; vaultResponse: VaultResponse }> {\n const claims = validateCapabilityToken(token)\n const result = delegatedSign(claims.val, request)\n // Await to satisfy require-await; sign() is async for API consistency\n // with fetch()/exec() and to reserve the right to check vaultResponse.rotatedJwt.\n await Promise.resolve()\n return {\n result,\n vaultResponse: { keyStatus: 'current' },\n }\n }\n\n /**\n * Verify a signature using a public key.\n *\n * This is a static method — no VaultKeeper instance, secrets, or\n * capability tokens are required. It is safe to call from CI or any\n * context that has access to public key material.\n *\n * Returns `false` for invalid key material, malformed signatures, or\n * any verification failure (except disallowed algorithms, which throw).\n *\n * @throws {InvalidAlgorithmError} If `request.algorithm` is not in the\n * allowed set (e.g. `'md5'`).\n *\n * @param request - The data, signature, public key, and optional\n * algorithm override.\n * @returns `true` if the signature is valid, `false` otherwise.\n */\n static verify(request: VerifyRequest): boolean {\n return delegatedVerify(request)\n }\n\n /**\n * Rotate the current encryption key.\n *\n * The previous key remains valid for decryption during the grace period\n * configured in `keyRotation.gracePeriodDays`. JWEs presented during the\n * grace period return a `rotatedJwt` in the `VaultResponse` so callers can\n * persist the updated token.\n *\n * @throws {RotationInProgressError} If a rotation is already in progress\n * (i.e. a previous key is still within its grace period).\n */\n async rotateKey(): Promise<void> {\n const gracePeriodMs = this.#config.keyRotation.gracePeriodDays * 24 * 60 * 60 * 1000\n this.#keyManager.rotateKey(gracePeriodMs)\n await Promise.resolve()\n }\n\n /**\n * Emergency key revocation — invalidates the previous key immediately.\n *\n * After revocation, any JWE that was encrypted with the revoked key will\n * be permanently unreadable. A new encryption key is generated automatically\n * so that `setup()` can be called immediately after revocation.\n */\n async revokeKey(): Promise<void> {\n this.#keyManager.revokeKey()\n await Promise.resolve()\n }\n\n /**\n * Add or remove an executable from the development-mode whitelist.\n *\n * When an executable is in the development-mode list, identity verification\n * (TOFU hash checking) is skipped for that executable during `setup()`. This\n * is intended for local development workflows where the binary changes\n * frequently.\n *\n * @param executablePath - Absolute path to the executable to add or remove.\n * @param enabled - Pass `true` to add the executable to the list, `false`\n * to remove it.\n */\n async setDevelopmentMode(executablePath: string, enabled: boolean): Promise<void> {\n if (this.#config.developmentMode === undefined) {\n if (enabled) {\n this.#config.developmentMode = { executables: [executablePath] }\n }\n return\n }\n\n const exes = this.#config.developmentMode.executables\n const idx = exes.indexOf(executablePath)\n\n if (enabled && idx === -1) {\n exes.push(executablePath)\n } else if (!enabled && idx !== -1) {\n exes.splice(idx, 1)\n }\n\n await Promise.resolve()\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n static #validateSecretName(name: string): void {\n if (name.trim() === '') {\n throw new VaultError('Secret name must not be empty')\n }\n }\n\n #resolveBackend(): SecretBackend {\n const enabledBackends = this.#config.backends.filter((b) => b.enabled)\n if (enabledBackends.length === 0) {\n throw new BackendUnavailableError(\n 'No enabled backends configured',\n 'none-enabled',\n this.#config.backends.map((b) => b.type),\n )\n }\n\n const firstEnabled = enabledBackends[0]\n if (firstEnabled === undefined) {\n throw new BackendUnavailableError(\n 'No enabled backends configured',\n 'none-enabled',\n [],\n )\n }\n\n return BackendRegistry.create(firstEnabled.type, firstEnabled)\n }\n\n #requireBackend(): SecretBackend {\n if (this.#backend === undefined) {\n throw new VaultError('VaultKeeper backend not initialized')\n }\n return this.#backend\n }\n\n #isDevModeExecutable(executablePath: string): boolean {\n if (this.#config.developmentMode === undefined) {\n return false\n }\n return this.#config.developmentMode.executables.includes(executablePath)\n }\n\n async #decryptWithKeyResolution(\n jwe: string,\n kid: string | undefined,\n ): Promise<{ claims: VaultClaims; keyStatus: 'current' | 'previous' }> {\n // Try to find key by kid\n if (kid !== undefined) {\n const key = this.#keyManager.findKeyById(kid)\n if (key !== undefined) {\n const claims = await decryptToken(key.key, jwe)\n const isCurrent = key.id === this.#keyManager.getCurrentKey().id\n return {\n claims,\n keyStatus: isCurrent ? 'current' : 'previous',\n }\n }\n // kid not found — key may have been revoked\n throw new KeyRevokedError(`Key ${kid} not found — may have been revoked`)\n }\n\n // No kid — try current key first, then previous\n try {\n const claims = await decryptToken(this.#keyManager.getCurrentKey().key, jwe)\n return { claims, keyStatus: 'current' }\n } catch {\n const previousKey = this.#keyManager.getPreviousKey()\n if (previousKey !== undefined) {\n const claims = await decryptToken(previousKey.key, jwe)\n return { claims, keyStatus: 'previous' }\n }\n throw new VaultError('Failed to decrypt JWE with any available key')\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/backend/registry.ts","../src/util/at-rest.ts","../src/config.ts","../src/backend/file-backend.ts","../src/util/exec.ts","../src/backend/keychain-backend.ts","../src/backend/dpapi-backend.ts","../src/backend/secret-tool-backend.ts","../src/backend/one-password-item-ops.ts","../src/backend/one-password-constants.ts","../src/backend/one-password-backend.ts","../src/backend/yubikey-backend.ts","../src/backend/register-builtins.ts","../src/backend/types.ts","../src/identity/hash.ts","../src/identity/manifest.ts","../src/identity/trust.ts","../src/identity/session.ts","../src/keys/manager.ts","../src/keys/storage.ts","../src/jwe/token.ts","../src/jwe/claims.ts","../src/access/placeholder.ts","../src/access/delegated-fetch.ts","../src/access/redact.ts","../src/access/delegated-exec.ts","../src/access/controlled-direct.ts","../src/access/jws.ts","../src/doctor/checks.ts","../src/util/platform.ts","../src/doctor/runner.ts","../src/vault.ts"],"names":["path","crypto","fs","fs2","os2","resolve","resolveStorageDir","path3","os3","getEntryPath","fs4","join","dirname","fileURLToPath","spawn","STORAGE_DIR_NAME","path4","GCM_IV_BYTES","GCM_KEY_BYTES","GCM_TAG_LENGTH_BITS","os4","fs5","crypto3","encryptGcm","decryptGcm","crypto4","path5","fs7","crypto5","path6","fs8","isObject","Buffer","sign","path7","crypto6","require","path8"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Error hierarchy for vaultkeeper.\n */\n\n/** Base error for all vaultkeeper errors. */\nexport class VaultError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'VaultError'\n }\n}\n\n// --- Backend Access Failures ---\n\n/**\n * Thrown when the backend keychain or credential store is locked and requires\n * user interaction (e.g. biometric prompt or password entry) before access can\n * be granted.\n */\nexport class BackendLockedError extends VaultError {\n /**\n * Whether the lock can be resolved through an interactive user prompt.\n * When `true`, callers may retry after prompting the user.\n */\n readonly interactive: boolean\n\n constructor(message: string, interactive: boolean) {\n super(message)\n this.name = 'BackendLockedError'\n this.interactive = interactive\n }\n}\n\n/**\n * Thrown when a hardware device (e.g. YubiKey or smart card) required for\n * authentication is not currently connected.\n */\nexport class DeviceNotPresentError extends VaultError {\n /**\n * How long (in milliseconds) the operation waited for the device before\n * giving up.\n */\n readonly timeoutMs: number\n\n constructor(message: string, timeoutMs: number) {\n super(message)\n this.name = 'DeviceNotPresentError'\n this.timeoutMs = timeoutMs\n }\n}\n\n/**\n * Thrown when the user explicitly denies an authorization request for a\n * secret access operation (e.g. cancels an OS permission dialog).\n */\nexport class AuthorizationDeniedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'AuthorizationDeniedError'\n }\n}\n\n/**\n * Thrown when an operation requires a backend capability (e.g.\n * presence-per-use) that the active backend cannot provide.\n *\n * @remarks\n * This is a configuration/backend mismatch, not a runtime authorization\n * failure: the requirement was asserted against a backend whose configured\n * instance does not advertise the capability, so no credential, session, or\n * device is ever touched before this is thrown. It is fixable by switching to\n * (or reconfiguring) a backend that provides the capability — inspect\n * {@link NotCapableError.capability} for which one was required and\n * {@link NotCapableError.backendType} for the backend that lacked it. Distinct\n * from {@link AuthorizationDeniedError} (a human/token rejection) and\n * {@link PresenceDeclinedError} (a human declined a fresh action).\n *\n * @public\n */\nexport class NotCapableError extends VaultError {\n /** The `type` identifier of the active backend that lacked the capability. */\n readonly backendType: string\n\n /**\n * The machine-readable capability key that was required but not advertised\n * (e.g. `'presencePerUse'`).\n */\n readonly capability: string\n\n constructor(message: string, backendType: string, capability: string) {\n super(message)\n this.name = 'NotCapableError'\n this.backendType = backendType\n this.capability = capability\n }\n}\n\n/**\n * Thrown when a required fresh, per-use human presence action was explicitly\n * declined by the human (e.g. a biometric or touch prompt was cancelled).\n *\n * @remarks\n * Distinct from {@link AuthorizationDeniedError}, which signals a token or\n * capability rejection, and from {@link PresenceTimeoutError}, which signals the\n * device was present but no action happened in time. A declined presence action\n * means the human was asked and said no.\n *\n * @public\n */\nexport class PresenceDeclinedError extends VaultError {\n /** The `type` identifier of the backend that requested the presence action. */\n readonly backendType: string\n\n constructor(message: string, backendType: string) {\n super(message)\n this.name = 'PresenceDeclinedError'\n this.backendType = backendType\n }\n}\n\n/**\n * Thrown when a required fresh, per-use human presence action did not happen\n * within the allotted time — the device was present and ready, but no touch,\n * tap, or biometric approval was performed before the timeout elapsed.\n *\n * @remarks\n * Distinct from {@link DeviceNotPresentError} (the device itself was absent) and\n * from {@link PresenceDeclinedError} (the human actively declined). Inspect\n * {@link PresenceTimeoutError.timeoutMs} for how long the operation waited.\n *\n * @public\n */\nexport class PresenceTimeoutError extends VaultError {\n /** The `type` identifier of the backend that requested the presence action. */\n readonly backendType: string\n\n /** How long (in milliseconds) the operation waited for the presence action. */\n readonly timeoutMs: number\n\n constructor(message: string, backendType: string, timeoutMs: number) {\n super(message)\n this.name = 'PresenceTimeoutError'\n this.backendType = backendType\n this.timeoutMs = timeoutMs\n }\n}\n\n/**\n * Thrown when no configured backend is available or reachable.\n * Inspect `reason` for a machine-readable cause and `attempted` for the list\n * of backend types that were tried.\n */\nexport class BackendUnavailableError extends VaultError {\n /**\n * Machine-readable reason code describing why the backend is unavailable\n * (e.g. `'none-enabled'`, `'all-failed'`).\n */\n readonly reason: string\n\n /**\n * The backend type identifiers that were attempted before this error was\n * thrown.\n */\n readonly attempted: string[]\n\n constructor(message: string, reason: string, attempted: string[]) {\n super(message)\n this.name = 'BackendUnavailableError'\n this.reason = reason\n this.attempted = attempted\n }\n}\n\n/**\n * Thrown when a required backend plugin (e.g. a third-party credential\n * manager) is not installed on the current system.\n */\nexport class PluginNotFoundError extends VaultError {\n /**\n * The plugin package or binary name that was not found.\n */\n readonly plugin: string\n\n /**\n * A URL pointing to installation instructions for the missing plugin.\n */\n readonly installUrl: string\n\n constructor(message: string, plugin: string, installUrl: string) {\n super(message)\n this.name = 'PluginNotFoundError'\n this.plugin = plugin\n this.installUrl = installUrl\n }\n}\n\n/**\n * Thrown when a requested secret does not exist in the backend store.\n */\nexport class SecretNotFoundError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'SecretNotFoundError'\n }\n}\n\n// --- JWE Lifecycle Failures ---\n\n/**\n * Thrown when a JWE token has passed its expiration time (`exp` claim).\n */\nexport class TokenExpiredError extends VaultError {\n /**\n * Whether the token can be refreshed by calling `setup()` again.\n * When `true`, the secret still exists in the backend and a new token can be\n * issued.\n */\n readonly canRefresh: boolean\n\n constructor(message: string, canRefresh: boolean) {\n super(message)\n this.name = 'TokenExpiredError'\n this.canRefresh = canRefresh\n }\n}\n\n/**\n * Thrown when the encryption key that was used to create a JWE has since been\n * rotated out of the grace period and can no longer be used for decryption.\n */\nexport class KeyRotatedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'KeyRotatedError'\n }\n}\n\n/**\n * Thrown when the encryption key referenced by a JWE's `kid` header has been\n * explicitly revoked and is no longer available for decryption.\n */\nexport class KeyRevokedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'KeyRevokedError'\n }\n}\n\n/**\n * Thrown when a JWE token has been explicitly blocked (e.g. after a single-use\n * token has already been consumed).\n */\nexport class TokenRevokedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'TokenRevokedError'\n }\n}\n\n/**\n * Thrown when a token with a finite `use` limit has been presented more times\n * than the limit allows.\n */\nexport class UsageLimitExceededError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'UsageLimitExceededError'\n }\n}\n\n// --- Identity and Trust Failures ---\n\n/**\n * Thrown when the hash of an executable no longer matches the previously\n * approved hash stored in the trust manifest (TOFU conflict).\n *\n * Callers must re-approve the executable before a new token can be issued for\n * it.\n */\nexport class IdentityMismatchError extends VaultError {\n /**\n * The hash that was recorded in the trust manifest at approval time.\n */\n readonly previousHash: string\n\n /**\n * The hash computed from the executable at the current moment.\n */\n readonly currentHash: string\n\n constructor(message: string, previousHash: string, currentHash: string) {\n super(message)\n this.name = 'IdentityMismatchError'\n this.previousHash = previousHash\n this.currentHash = currentHash\n }\n}\n\n/**\n * Thrown by {@link VaultKeeper.setup} when the caller does not make an\n * unambiguous executable-trust decision.\n *\n * `setup()` deliberately has no default trust behaviour: the caller must either\n * pass a real `executablePath` (which runs trust-on-first-use verification) or\n * explicitly opt out with `skipTrust: true` (a development-only escape hatch).\n * Supplying neither — or both at once — throws this error rather than silently\n * skipping verification. Passing the retired `'dev'` sentinel as `executablePath`\n * also throws this error. Inspect {@link ExecutableTrustRequiredError.reason} to\n * distinguish the cases.\n *\n * @public\n */\nexport class ExecutableTrustRequiredError extends VaultError {\n /**\n * Machine-readable discriminator for why the trust choice was rejected.\n * `'missing-choice'` means neither `executablePath` nor `skipTrust: true`\n * was provided, so no trust decision was expressed. `'conflicting-choice'`\n * means both `executablePath` and `skipTrust: true` were provided, which\n * are mutually exclusive intents. `'legacy-dev-sentinel'` means\n * `executablePath` was the retired literal `'dev'` opt-out sentinel, which is\n * no longer supported and must be replaced with `skipTrust: true`.\n */\n readonly reason: 'missing-choice' | 'conflicting-choice' | 'legacy-dev-sentinel'\n\n constructor(\n message: string,\n reason: 'missing-choice' | 'conflicting-choice' | 'legacy-dev-sentinel',\n ) {\n super(message)\n this.name = 'ExecutableTrustRequiredError'\n this.reason = reason\n }\n}\n\n// --- Access Pattern Failures ---\n\n/**\n * Thrown when spawning or running a subprocess fails.\n *\n * This covers a delegated `exec()` call failing due to an invalid request\n * (e.g. a `{{secret}}` placeholder in the `command` field) or a\n * process-level error (e.g. the command binary is not found or cannot be\n * spawned) — and also vaultkeeper's own internal tool invocations (doctor\n * version probes, the keychain/secret-tool/dpapi/yubikey credential helpers),\n * which run through the same subprocess utility. Callers that need to handle\n * only delegated-exec failures should scope their `catch` to the code paths\n * that call `exec()`, not discriminate on this type alone.\n *\n * @public\n */\nexport class ExecError extends VaultError {\n /**\n * The command that failed to execute.\n */\n readonly command: string\n\n constructor(message: string, command: string) {\n super(message)\n this.name = 'ExecError'\n this.command = command\n }\n}\n\n/**\n * Thrown when a JWE string is invalid or cannot be processed — for example,\n * it is structurally malformed (wrong number of segments, invalid\n * Base64URL), decryption fails (wrong key, tampered ciphertext), or the\n * decrypted payload does not match the expected claims schema.\n *\n * @public\n */\nexport class InvalidTokenError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidTokenError'\n }\n}\n\n/**\n * Thrown when `SecretAccessor.read()` is called after the accessor has\n * already been consumed.\n *\n * @public\n */\nexport class AccessorConsumedError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'AccessorConsumedError'\n }\n}\n\n// --- Infrastructure Failures ---\n\n/**\n * Thrown when a caller requests a signing key algorithm that is not a\n * supported JOSE algorithm identifier. The signing algorithm registry uses\n * strict JOSE identifiers (currently `'EdDSA'`); an unrecognized value is\n * rejected rather than defaulted.\n *\n * @public\n */\nexport class InvalidAlgorithmError extends VaultError {\n /**\n * The algorithm that was requested.\n */\n readonly algorithm: string\n\n /**\n * The set of algorithms that are allowed.\n */\n readonly allowed: string[]\n\n constructor(message: string, algorithm: string, allowed: string[]) {\n super(message)\n this.name = 'InvalidAlgorithmError'\n this.algorithm = algorithm\n this.allowed = allowed\n }\n}\n\n/**\n * Thrown when signing-key material cannot be parsed. Two paths raise it. During\n * verification, the supplied public key is not a structurally parseable SPKI PEM\n * public key (or a private key was passed where a public key is required); this\n * is an operational fault distinct from a signature that simply does not verify,\n * which returns `false`. During key use, a stored signing key decrypts cleanly\n * but is not valid private key material — corrupt or tampered on disk — when\n * exporting its public half or signing with it (`getPublicKey`/`signWithKey`).\n * The message never echoes any part of the key material.\n *\n * @public\n */\nexport class InvalidKeyMaterialError extends VaultError {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidKeyMaterialError'\n }\n}\n\n/**\n * Thrown when a named signing key does not exist in the active backend — for\n * example `key export` or `sign` is asked for a name that was never enrolled\n * with `key create`. This is distinct from {@link SecretNotFoundError}: signing\n * keys occupy their own namespace and are never returned as ordinary secrets.\n *\n * @public\n */\nexport class SigningKeyNotFoundError extends VaultError {\n /**\n * The signing-key name that was requested (the caller-facing `--name`, not\n * the internal namespaced identifier).\n */\n readonly keyName: string\n\n constructor(message: string, keyName: string) {\n super(message)\n this.name = 'SigningKeyNotFoundError'\n this.keyName = keyName\n }\n}\n\n/**\n * Thrown when `key create` (or `createSigningKey`) is asked to enroll a signing\n * key under a name that already exists. Enrollment never silently overwrites an\n * existing key, because a regenerated keypair would invalidate every public key\n * that was previously exported and pinned by a verifier.\n *\n * @public\n */\nexport class SigningKeyAlreadyExistsError extends VaultError {\n /**\n * The signing-key name that already exists (the caller-facing `--name`, not\n * the internal namespaced identifier).\n */\n readonly keyName: string\n\n constructor(message: string, keyName: string) {\n super(message)\n this.name = 'SigningKeyAlreadyExistsError'\n this.keyName = keyName\n }\n}\n\n/**\n * Thrown when a signing operation (`key create`, `key export`, `sign`) is\n * requested against a backend that does not implement the signing contract.\n * Signing is never silently emulated on a backend that cannot perform it in a\n * key-stays-backend-side manner; inspect {@link SigningNotSupportedError.builtInSigningBackends}\n * for the built-in backend types that do.\n *\n * @public\n */\nexport class SigningNotSupportedError extends VaultError {\n /** The type identifier of the active backend that cannot sign. */\n readonly backendType: string\n\n /**\n * The **built-in** backend type identifiers known to implement the signing\n * contract (currently just the `file` backend). This is deliberately a\n * static list of built-ins, not a live capability survey: a consumer that\n * registers its own {@link SigningBackend} is not enumerated here, because\n * discovering that would require instantiating every registered backend —\n * a side effect that must not happen on an error path. A caller can still\n * point a user at a working built-in, and custom backends may implement the\n * contract independently.\n */\n readonly builtInSigningBackends: string[]\n\n constructor(message: string, backendType: string, builtInSigningBackends: string[]) {\n super(message)\n this.name = 'SigningNotSupportedError'\n this.backendType = backendType\n this.builtInSigningBackends = builtInSigningBackends\n }\n}\n\n/**\n * Thrown when an encrypted-at-rest secret entry cannot be decrypted — e.g.\n * the stored ciphertext is truncated/corrupted or the AES-GCM auth tag fails\n * to verify. The message never echoes any part of the secret or key\n * material.\n *\n * @public\n */\nexport class DecryptionError extends VaultError {\n /**\n * The path of the encrypted entry that failed to decrypt.\n */\n readonly path: string\n\n constructor(message: string, path: string) {\n super(message)\n this.name = 'DecryptionError'\n this.path = path\n }\n}\n\n/**\n * Thrown when a delegated `fetch()` call fails before a `Response` can be\n * produced — for example the URL is malformed or the underlying network\n * request fails (DNS failure, connection refused, TLS error).\n *\n * @public\n */\nexport class FetchError extends VaultError {\n /**\n * The unresolved URL template that fetch failed to request, with\n * `{{secret}}`/`{{secret:name}}` placeholders left intact. The\n * placeholder-resolved URL is deliberately never stored here, so an\n * injected secret is never exposed.\n */\n readonly url: string\n\n constructor(message: string, url: string) {\n super(message)\n this.name = 'FetchError'\n this.url = url\n }\n}\n\n/**\n * Thrown when a config value fails structural or semantic validation (e.g. a\n * whitespace-only `BackendConfig.path`).\n */\nexport class ConfigValidationError extends VaultError {\n /**\n * The dotted/bracketed path to the offending config field (e.g.\n * `'backends[0].path'`).\n */\n readonly field: string\n\n /**\n * The path of the config file that failed validation, when the error\n * originated from loading a file on disk (via `loadConfig`) rather than\n * from validating an in-memory value directly. This is `configDir` joined\n * with `config.json` exactly as provided to `loadConfig` — it is not\n * guaranteed to be absolute (`loadConfig` does not resolve a relative\n * `configDir`).\n */\n readonly configFilePath: string | undefined\n\n constructor(message: string, field: string, configFilePath?: string) {\n super(message)\n this.name = 'ConfigValidationError'\n this.field = field\n this.configFilePath = configFilePath\n }\n}\n\n/**\n * Thrown when a config's `backends[].type` names a backend that is not\n * registered with the {@link BackendRegistry}.\n *\n * A specialization of {@link ConfigValidationError}: an unknown backend type is\n * a semantic schema failure (the config parses and is structurally valid, but\n * names a backend that cannot be created), so it fails config validation the\n * same way `version !== 1` does. It carries the offending `backendType` and the\n * set of `knownTypes` so a consumer — notably `doctor` — can give the same\n * \"Available types: …\" guidance the runtime {@link BackendUnavailableError}\n * gives, without parsing the human-readable message. This closes the gap where\n * a config with an unknown backend type parsed as valid JSON and passed\n * `doctor` with a false \"System ready.\", only for the next real command to\n * throw {@link BackendUnavailableError} (issue #215).\n */\nexport class UnknownBackendTypeError extends ConfigValidationError {\n /** The unregistered backend type named in the config. */\n readonly backendType: string\n\n /**\n * The backend type identifiers that were registered when validation ran —\n * the valid options to offer in remediation.\n */\n readonly knownTypes: string[]\n\n constructor(\n message: string,\n field: string,\n backendType: string,\n knownTypes: string[],\n configFilePath?: string,\n ) {\n super(message, field, configFilePath)\n this.name = 'UnknownBackendTypeError'\n this.backendType = backendType\n this.knownTypes = knownTypes\n }\n}\n\n/**\n * Thrown when a config file's contents cannot be parsed as JSON.\n *\n * The `message` already embeds the file path, the parse location (when the\n * underlying `SyntaxError` exposes one), and a remediation hint that either\n * points at `vaultkeeper config init` (via the separate `@vaultkeeper/cli`\n * package — this library ships no CLI of its own) or at repairing/replacing\n * the config directly through this library's JS API — see issues #68, #100.\n * `path` and `location` are also exposed individually for callers (e.g.\n * `doctor`) that want to report them as structured fields rather than\n * re-parsing the message.\n */\nexport class ConfigParseError extends VaultError {\n /**\n * The path of the config file that failed to parse. This is `configDir`\n * joined with `config.json` exactly as provided to `loadConfig` — it is\n * not guaranteed to be absolute (`loadConfig` does not resolve a relative\n * `configDir`).\n */\n readonly path: string\n\n /**\n * A human-readable parse location (e.g. `'line 3, column 12'`), when one\n * could be derived from the underlying `SyntaxError`.\n */\n readonly location: string | undefined\n\n constructor(message: string, path: string, location: string | undefined) {\n super(message)\n this.name = 'ConfigParseError'\n this.path = path\n this.location = location\n }\n}\n\n/**\n * Thrown during initialization when a required system dependency (e.g. OpenSSL\n * or a native credential helper) is missing or incompatible.\n */\nexport class SetupError extends VaultError {\n /**\n * The name of the dependency that caused the setup failure.\n */\n readonly dependency: string\n\n constructor(message: string, dependency: string) {\n super(message)\n this.name = 'SetupError'\n this.dependency = dependency\n }\n}\n\n/**\n * Thrown when a filesystem operation fails. Common causes include a\n * permission or access problem, for example the config directory is not\n * writable, but the underlying failure may be any Node.js errno condition,\n * for example the disk is full or a file was expected but a directory was\n * found. Inspect the code property for the specific errno code when one is\n * available.\n */\nexport class FilesystemError extends VaultError {\n /**\n * The path of the file or directory that caused the error, as provided by\n * the caller. Not guaranteed to be absolute — e.g. `loadConfig` throws this\n * with `configDir` joined with `config.json` exactly as given, without\n * resolving a relative `configDir`.\n */\n readonly path: string\n\n /**\n * The file operation or access mode that was being attempted when the\n * failure occurred, for example 'read', 'write', 'delete', or 'rwx' for a\n * directory create/access check. Despite the field name, this does not\n * imply the failure was itself a permission problem — it names the\n * attempted operation regardless of the underlying errno, which may be a\n * non-permission code such as ENOSPC or EISDIR.\n */\n readonly permission: string\n\n /**\n * The Node.js errno code from the underlying filesystem failure, for\n * example EACCES, EPERM, ENOSPC, or EISDIR. Undefined when the error was\n * constructed without an underlying cause, or when that cause did not\n * expose a string errno code. Prefer this over parsing the message text,\n * which is not a contractual format.\n */\n readonly code: string | undefined\n\n /**\n * @param message - Human-readable description of the failure.\n * @param filePath - The path of the file or directory that caused the error.\n * @param permission - The file operation or access mode being attempted,\n * for example 'read', 'write', 'delete', or 'rwx'. See the `permission`\n * property for why this need not indicate an actual permission problem.\n * @param cause - The underlying error that was caught, if any. Recorded as\n * the standard `Error.cause` and used to populate `code` when it exposes a\n * string errno code.\n */\n constructor(message: string, filePath: string, permission: string, cause?: unknown) {\n super(message)\n this.name = 'FilesystemError'\n this.path = filePath\n this.permission = permission\n this.code = hasErrnoCode(cause) ? cause.code : undefined\n if (cause !== undefined) {\n // Matches the property descriptor the native `new Error(message, {\n // cause })` form installs (non-enumerable), rather than a plain\n // assignment, which would make `cause` enumerable and thus show up in\n // `Object.keys()`/`JSON.stringify()` output unlike a standard cause.\n Object.defineProperty(this, 'cause', {\n value: cause,\n writable: true,\n enumerable: false,\n configurable: true,\n })\n }\n }\n}\n\n/**\n * True when `err` is an `Error` carrying a Node.js-style string `code`\n * property — the `NodeJS.ErrnoException` convention used by filesystem and\n * other system-call failures.\n */\nfunction hasErrnoCode(err: unknown): err is Error & { code: string } {\n return err instanceof Error && 'code' in err && typeof err.code === 'string'\n}\n\n/**\n * Build a typed FilesystemError from a caught Node.js filesystem failure,\n * describing which resource and operation were involved. The original error\n * is preserved as `cause`, and its errno code, when present, is copied onto\n * the returned error for machine-readable discrimination.\n *\n * @param err - The value caught from the failed filesystem call.\n * @param resourceLabel - A short noun phrase describing what was being\n * accessed, for example 'secret file' or 'wrapping key file'.\n * @param filePath - The path that was being accessed.\n * @param permission - The operation being attempted, for example 'read',\n * 'write', or 'delete'.\n * @internal\n */\nexport function toFilesystemError(\n err: unknown,\n resourceLabel: string,\n filePath: string,\n permission: string,\n): FilesystemError {\n const detail = err instanceof Error ? err.message : String(err)\n return new FilesystemError(\n `Failed to ${permission} ${resourceLabel} at ${filePath}: ${detail}`,\n filePath,\n permission,\n err,\n )\n}\n\n/**\n * Thrown when a key rotation is requested while a previous rotation is still\n * within its grace period (i.e. the previous key has not yet been retired).\n */\nexport class RotationInProgressError extends VaultError {\n constructor(message: string) {\n const trimmed = message.trim()\n const nextSteps =\n 'Either wait for the current grace period to elapse before rotating again, ' +\n \"or run 'vaultkeeper revoke-key' (or call revokeKey()) to invalidate the previous key \" +\n 'immediately and clear the grace period.'\n const prefix = trimmed.length === 0 ? '' : `${trimmed}${/[.!?]$/.test(trimmed) ? '' : '.'} `\n super(`${prefix}${nextSteps}`)\n this.name = 'RotationInProgressError'\n }\n}\n","/**\n * Registry for secret backend implementations.\n *\n * @remarks\n * The registry maintains a mapping of backend types to factory functions,\n * allowing dynamic creation of backends based on configuration.\n */\n\nimport type { SecretBackend, BackendFactory } from './types.js'\nimport type { BackendSetupFactory } from './setup-types.js'\nimport { BackendUnavailableError } from '../errors.js'\n\n/**\n * Registry for secret backend implementations.\n *\n * @remarks\n * The registry allows registration of custom backends and provides\n * a factory method to create backend instances from a type string.\n *\n * Note: This class is used as a namespace for static methods.\n * @public\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class BackendRegistry {\n private static backends = new Map<string, BackendFactory>()\n private static setups = new Map<string, BackendSetupFactory>()\n\n /**\n * Register a backend factory.\n * @param type - Backend type identifier\n * @param factory - Factory function to create backend instances\n */\n static register(type: string, factory: BackendFactory): void {\n this.backends.set(type, factory)\n }\n\n /**\n * Create a backend instance by type.\n * @param type - Backend type identifier\n * @param config - Optional backend configuration forwarded to the factory\n * @param configDir - Optional resolved config directory forwarded to the\n * factory, so file-based backends can default their storage under it\n * @returns A SecretBackend instance\n * @throws {@link BackendUnavailableError} if the backend type is not registered\n */\n static create(\n type: string,\n config?: import('../types.js').BackendConfig,\n configDir?: string,\n ): SecretBackend {\n const factory = this.backends.get(type)\n if (factory === undefined) {\n throw new BackendUnavailableError(\n `Unknown backend type: ${type}. ` +\n `Available types: ${Array.from(this.backends.keys()).join(', ')}`,\n 'unknown-type',\n Array.from(this.backends.keys()),\n )\n }\n return factory(config, configDir)\n }\n\n /**\n * Get all registered backend type identifiers.\n * @returns Array of backend type identifiers\n */\n static getTypes(): string[] {\n return Array.from(this.backends.keys())\n }\n\n /**\n * Returns backend types that are available on the current system.\n *\n * @remarks\n * Creates each registered backend via its factory, calls `isAvailable()`,\n * and returns only the type identifiers whose backend reports availability.\n * If a backend's `isAvailable()` call throws, that backend is excluded from\n * the result rather than propagating the error.\n *\n * @returns Promise resolving to an array of available backend type identifiers\n * @public\n */\n static async getAvailableTypes(): Promise<string[]> {\n const entries = Array.from(this.backends.entries())\n const results = await Promise.all(\n entries.map(async ([type, factory]) => {\n try {\n const backend = factory()\n const available = await backend.isAvailable()\n return available ? type : null\n } catch {\n return null\n }\n }),\n )\n return results.filter((type): type is string => type !== null)\n }\n\n /**\n * Register a setup factory for a backend type.\n * @param type - Backend type identifier\n * @param factory - Factory function that creates a setup generator\n */\n static registerSetup(type: string, factory: BackendSetupFactory): void {\n this.setups.set(type, factory)\n }\n\n /**\n * Get the setup factory for a backend type, if one is registered.\n * @param type - Backend type identifier\n * @returns The setup factory, or `undefined` if none is registered\n */\n static getSetup(type: string): BackendSetupFactory | undefined {\n return this.setups.get(type)\n }\n\n /**\n * Check whether a setup factory is registered for the given backend type.\n * @param type - Backend type identifier\n * @returns `true` if a setup factory is registered\n */\n static hasSetup(type: string): boolean {\n return this.setups.has(type)\n }\n\n /**\n * Clear all registered backend factories.\n * Intended for use in tests only.\n * @internal\n */\n static clearBackends(): void {\n this.backends.clear()\n }\n\n /**\n * Clear all registered setup factories.\n * Intended for use in tests only.\n * @internal\n */\n static clearSetups(): void {\n this.setups.clear()\n }\n}\n","/**\n * Shared AES-256-GCM helpers for encrypting data at rest under a locally\n * stored wrapping key.\n *\n * @remarks\n * These primitives back both the encrypted {@link FileBackend} secret store and\n * the persisted {@link KeyManager} key material. Keeping a single implementation\n * ensures every at-rest write in the codebase uses the same authenticated\n * cipher (AES-256-GCM, never AES-CBC) and the same on-disk envelope, rather than\n * re-deriving crypto per consumer.\n *\n * Envelope format (all parts base64, colon-separated):\n * `<iv>:<authTag>:<ciphertext>`\n *\n * @internal\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as crypto from 'node:crypto'\nimport { toFilesystemError, DecryptionError } from '../errors.js'\n\nconst GCM_IV_BYTES = 12\nconst GCM_KEY_BYTES = 32\nconst GCM_TAG_LENGTH_BITS = 128\n\n/**\n * Encrypt `plaintext` with AES-256-GCM under `key`, returning the\n * `iv:authTag:ciphertext` envelope described in the module docs.\n *\n * @param key - 32-byte AES-256 wrapping key.\n * @param plaintext - UTF-8 string to encrypt.\n * @internal\n */\nexport function encryptGcm(key: Buffer, plaintext: string): string {\n const iv = crypto.randomBytes(GCM_IV_BYTES)\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH_BITS / 8,\n })\n const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])\n const authTag = cipher.getAuthTag()\n return [iv.toString('base64'), authTag.toString('base64'), encrypted.toString('base64')].join(':')\n}\n\n/**\n * Decrypt an `iv:authTag:ciphertext` envelope produced by {@link encryptGcm}.\n *\n * @param key - The same 32-byte AES-256 wrapping key used to encrypt.\n * @param encoded - The colon-separated envelope.\n * @param path - The path of the encrypted entry being decrypted, for\n * attribution on a thrown {@link DecryptionError}. Callers that don't yet\n * have a path (e.g. an in-memory envelope) may omit it.\n * @returns The decrypted UTF-8 plaintext.\n * @throws {DecryptionError} If the envelope is malformed or authentication fails.\n * @internal\n */\nexport function decryptGcm(key: Buffer, encoded: string, path = ''): string {\n const parts = encoded.split(':')\n if (parts.length !== 3) {\n throw new DecryptionError('Invalid encrypted envelope: expected iv:authTag:ciphertext', path)\n }\n const [ivB64, authTagB64, ciphertextB64] = parts\n if (ivB64 === undefined || authTagB64 === undefined || ciphertextB64 === undefined) {\n throw new DecryptionError('Invalid encrypted envelope: missing part', path)\n }\n const iv = Buffer.from(ivB64, 'base64')\n const authTag = Buffer.from(authTagB64, 'base64')\n const ciphertext = Buffer.from(ciphertextB64, 'base64')\n\n try {\n // Inside the try from createDecipheriv onward: the iv and authTag lengths\n // come from the on-disk envelope, so a truncated/corrupt entry can make\n // createDecipheriv or setAuthTag throw a native RangeError/TypeError —\n // not just decipher.final()'s auth-tag failure.\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH_BITS / 8,\n })\n decipher.setAuthTag(authTag)\n const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])\n return decrypted.toString('utf8')\n } catch (err) {\n // Wrap every native crypto failure so the documented\n // @throws {DecryptionError} contract holds on every path.\n throw new DecryptionError(\n `Failed to decrypt envelope: ${err instanceof Error ? err.message : String(err)}`,\n path,\n )\n }\n}\n\n/**\n * Read the 32-byte wrapping key at `keyPath`, generating and persisting a fresh\n * random one (mode `0o600`) when the file does not yet exist **or** holds a\n * value that is not exactly 32 bytes.\n *\n * @remarks\n * Regenerating on a wrong-length key is safe, not data loss: a wrapping key of\n * the wrong length cannot decrypt anything it previously encrypted (the AES-256\n * cipher requires a 32-byte key), so any ciphertext under a corrupt key is\n * already unrecoverable. Without this guard, a truncated/corrupt key file would\n * make {@link encryptGcm} throw \"Invalid key length\" on every write, wedging the\n * consumer instead of degrading to a fresh key.\n *\n * The caller is responsible for ensuring the parent directory exists. The\n * returned {@link Buffer} holds key material; zero it after use where practical.\n *\n * @param keyPath - Absolute path to the wrapping-key file.\n * @internal\n */\nexport async function getOrCreateWrapKey(keyPath: string): Promise<Buffer> {\n let existing: Buffer | undefined\n try {\n existing = await fs.readFile(keyPath)\n } catch (err) {\n if (!(err instanceof Error && 'code' in err && err.code === 'ENOENT')) {\n throw toFilesystemError(err, 'wrapping key file', keyPath, 'read')\n }\n }\n\n if (existing?.byteLength === GCM_KEY_BYTES) {\n return existing\n }\n\n // Missing or corrupt (wrong length): (re)generate a fresh key in place.\n const key = crypto.randomBytes(GCM_KEY_BYTES)\n try {\n await fs.writeFile(keyPath, key, { mode: 0o600 })\n } catch (err) {\n throw toFilesystemError(err, 'wrapping key file', keyPath, 'write')\n }\n return key\n}\n","/**\n * Configuration loading, validation, and defaults for vaultkeeper.\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport type { VaultConfig, BackendConfig, TrustTier } from './types.js'\nimport {\n ConfigValidationError,\n ConfigParseError,\n FilesystemError,\n UnknownBackendTypeError,\n} from './errors.js'\nimport { BackendRegistry } from './backend/registry.js'\n\n/**\n * Remediation hint appended to every config-loading error message so a user\n * always has a concrete next step, regardless of whether the failure was a\n * read error, a JSON syntax error, or a schema validation error (issue #68).\n *\n * This library has no CLI of its own (`vaultkeeper` ships no `bin`), so the\n * hint is qualified rather than naming a bare command: install the separate\n * `@vaultkeeper/cli` package to run `vaultkeeper config init --force`, or fix\n * the config through the JS API directly (issue #100).\n */\nconst CONFIG_REMEDIATION_HINT = `Fix the file — either install @vaultkeeper/cli and run 'vaultkeeper config init --force' to overwrite it with a valid config, or repair/replace it programmatically via this library (pass an explicit \\`config\\` or \\`configDir\\`, or write a valid config.json yourself).`\n\n/** `true` if `err` is a Node.js filesystem error with the given `code`. */\nfunction hasErrorCode(err: unknown, code: string): boolean {\n return err instanceof Error && 'code' in err && err.code === code\n}\n\n/** Extract a readable message from an unknown thrown value. */\nfunction describeError(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\n/**\n * Best-effort human-readable location (`'line X, column Y'`) derived from a\n * JSON `SyntaxError`. Modern V8 (Node 20+) already includes `line N column N`\n * in the message; older engines only report a character offset (`position\n * N`), which this falls back to converting by counting newlines in `raw`.\n * Returns `undefined` when no location can be determined.\n */\nfunction describeJsonSyntaxLocation(err: unknown, raw: string): string | undefined {\n const message = describeError(err)\n\n const lineColMatch = /line (\\d+) column (\\d+)/.exec(message)\n if (lineColMatch) {\n return `line ${lineColMatch[1] ?? ''}, column ${lineColMatch[2] ?? ''}`\n }\n\n const positionMatch = /position (\\d+)/.exec(message)\n if (positionMatch) {\n const posStr = positionMatch[1]\n const pos = posStr !== undefined ? Number(posStr) : NaN\n if (!Number.isNaN(pos) && pos >= 0 && pos <= raw.length) {\n const upToPos = raw.slice(0, pos)\n const line = upToPos.split('\\n').length\n const column = pos - upToPos.lastIndexOf('\\n')\n return `line ${String(line)}, column ${String(column)}`\n }\n }\n\n return undefined\n}\n\n/**\n * Return the platform-appropriate default config directory, ignoring the\n * `VAULTKEEPER_CONFIG_DIR` environment variable.\n *\n * This is the location vaultkeeper falls back to when neither a CLI\n * `--config-dir` flag nor the `VAULTKEEPER_CONFIG_DIR` environment variable\n * is set: `%APPDATA%/vaultkeeper` on Windows, `~/.config/vaultkeeper`\n * elsewhere.\n *\n * Unlike `getDefaultConfigDir`, this deliberately does not consult\n * `VAULTKEEPER_CONFIG_DIR`, so a caller can tell whether an active config\n * directory differs from the machine default even when that difference came\n * from the environment variable — for example, to decide whether a printed\n * remediation command must carry an explicit `--config-dir` so it still\n * targets the right file in a fresh shell that does not have the environment\n * variable set.\n *\n * @public\n */\nexport function getPlatformDefaultConfigDir(): string {\n if (process.platform === 'win32') {\n const appData = process.env.APPDATA\n if (appData !== undefined) {\n return path.join(appData, 'vaultkeeper')\n }\n return path.join(os.homedir(), 'AppData', 'Roaming', 'vaultkeeper')\n }\n return path.join(os.homedir(), '.config', 'vaultkeeper')\n}\n\n/**\n * Return the platform-appropriate default config directory.\n *\n * Resolution order: the `VAULTKEEPER_CONFIG_DIR` environment variable, then\n * the platform default (see `getPlatformDefaultConfigDir`). Consumers that\n * also support a higher-precedence override (e.g. a CLI flag) should check\n * that first and only fall back to this function when no override was\n * supplied.\n *\n * @public\n */\nexport function getDefaultConfigDir(): string {\n const envOverride = process.env.VAULTKEEPER_CONFIG_DIR\n if (envOverride !== undefined && envOverride !== '') {\n return envOverride\n }\n return getPlatformDefaultConfigDir()\n}\n\n/**\n * The backend type vaultkeeper uses by default when no backend is explicitly\n * configured — the **`file`** backend, on every platform.\n *\n * @remarks\n * The zero-config default is deliberately the portable, self-contained\n * AES-256-GCM encrypted file backend rather than the platform-native OS\n * credential store. This guarantees that a bare {@link VaultKeeper.init} — or a\n * `vaultkeeper config init` (run via the separate `@vaultkeeper/cli` package)\n * with no `--backend` flag — can never silently write a secret into the\n * user's real login keychain (or Windows DPAPI store) before they have\n * chosen to. It also matches the WASM SDK, which always uses the file\n * backend.\n *\n * The OS-native store is still available as an explicit opt-in: pass\n * `--backend keychain` (macOS) / `--backend dpapi` (Windows) to\n * `vaultkeeper config init` (via `@vaultkeeper/cli`), or set\n * `{ type: 'keychain' | 'dpapi' }` directly in a config object/file. Use\n * {@link platformNativeBackendType} to discover which native store the current\n * platform offers.\n *\n * @returns The zero-config default backend type identifier (`'file'`).\n * @public\n */\nexport function defaultBackendType(): string {\n return 'file'\n}\n\n/**\n * Resolve the OS-native credential store type for the current platform.\n *\n * @remarks\n * This is **not** the zero-config default — {@link defaultBackendType} (always\n * `'file'`) is. This function reports which platform-native store a user can\n * explicitly opt into (e.g. via `vaultkeeper config init --backend keychain`\n * from the separate `@vaultkeeper/cli` package, or `{ type: 'keychain' }` in\n * a config object/file passed directly to this library):\n *\n * - **macOS** → `keychain` (macOS Keychain)\n * - **Windows** → `dpapi` (Windows DPAPI)\n * - **Linux** → `secret-tool` (Secret Service via `libsecret`; opting in\n * requires the `libsecret-tools` package)\n * - **any other platform** → `file` (no built-in native store integration, so\n * the portable AES-256-GCM encrypted file backend is the only option)\n *\n * Use it to tell the user which native store is available on their platform, or\n * to label the opt-in. It never affects what an unconfigured vault resolves to\n * — that is always {@link defaultBackendType} (`file`).\n *\n * @returns The OS-native backend type identifier for the current platform.\n * @public\n */\nexport function platformNativeBackendType(): string {\n if (process.platform === 'darwin') {\n return 'keychain'\n }\n if (process.platform === 'win32') {\n return 'dpapi'\n }\n if (process.platform === 'linux') {\n // The `secret-tool` backend is a real shipped built-in (Secret Service via\n // libsecret) — the Linux OS-native store a user can opt into. It is not the\n // zero-config default (that is `file`), so naming it here never risks a\n // silent write: the caller must explicitly choose `--backend secret-tool`.\n return 'secret-tool'\n }\n // Other platforms (e.g. the BSDs) have no built-in native-store integration.\n return 'file'\n}\n\n/**\n * Default configuration when no config file exists.\n *\n * The active backend is the safe zero-config default resolved by\n * {@link defaultBackendType} (the `file` backend on every platform), never the\n * OS-native credential store — a missing config must never silently target the\n * real keychain (issue #98).\n */\nfunction defaultConfig(): VaultConfig {\n return {\n version: 1,\n backends: [{ type: defaultBackendType(), enabled: true }],\n keyRotation: { gracePeriodDays: 7 },\n defaults: { ttlMinutes: 60, trustTier: 3 },\n }\n}\n\n/**\n * Type guard for plain objects.\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Validates a backend config entry.\n */\nfunction validateBackendEntry(entry: unknown, index: number): BackendConfig {\n const base = `backends[${String(index)}]`\n\n if (!isObject(entry)) {\n throw new ConfigValidationError(`${base} must be an object`, base)\n }\n if (typeof entry.type !== 'string' || entry.type.trim() === '') {\n throw new ConfigValidationError(`${base}.type must be a non-empty string`, `${base}.type`)\n }\n // A structurally-valid type string that names a backend nobody registered is\n // still an unusable config: the next real command would throw\n // BackendUnavailableError at backend-creation time. Reject it here, in the\n // shared validation path, so `loadConfig` and `doctor` agree instead of\n // doctor reporting \"System ready.\" for a config the first store/fetch will\n // reject (issue #215). The valid set is the live registry — which includes\n // any custom backends a consumer registered — not a hardcoded list. Guard on\n // a populated registry so isolated callers that validate a config before the\n // built-in backends have been registered are not told every type is invalid.\n const knownTypes = BackendRegistry.getTypes()\n if (knownTypes.length > 0 && !knownTypes.includes(entry.type)) {\n throw new UnknownBackendTypeError(\n `${base}.type is an unknown backend type: \"${entry.type}\". ` +\n `Available types: ${knownTypes.join(', ')}`,\n `${base}.type`,\n entry.type,\n knownTypes,\n )\n }\n if (typeof entry.enabled !== 'boolean') {\n throw new ConfigValidationError(`${base}.enabled must be a boolean`, `${base}.enabled`)\n }\n\n const result: BackendConfig = {\n type: entry.type,\n enabled: entry.enabled,\n }\n\n if (entry.plugin !== undefined) {\n if (typeof entry.plugin !== 'boolean') {\n throw new ConfigValidationError(`${base}.plugin must be a boolean`, `${base}.plugin`)\n }\n result.plugin = entry.plugin\n }\n\n if (entry.path !== undefined) {\n if (typeof entry.path !== 'string') {\n throw new ConfigValidationError(`${base}.path must be a string`, `${base}.path`)\n }\n if (entry.path.trim() === '') {\n throw new ConfigValidationError(\n `${base}.path must not be empty or whitespace-only`,\n `${base}.path`,\n )\n }\n result.path = entry.path\n }\n\n if (entry.options !== undefined) {\n if (!isObject(entry.options)) {\n throw new ConfigValidationError(`${base}.options must be an object`, `${base}.options`)\n }\n const opts: Record<string, string> = {}\n for (const [k, v] of Object.entries(entry.options)) {\n if (typeof v !== 'string') {\n const quotedKey = JSON.stringify(k)\n throw new ConfigValidationError(\n `${base}.options[${quotedKey}] must be a string`,\n `${base}.options[${quotedKey}]`,\n )\n }\n opts[k] = v\n }\n result.options = opts\n }\n\n return result\n}\n\n/**\n * Validate an unknown value as a VaultConfig, throwing on invalid structure.\n * @internal\n */\nexport function validateConfig(config: unknown): VaultConfig {\n if (!isObject(config)) {\n throw new ConfigValidationError('Config must be an object', 'config')\n }\n\n if (typeof config.version !== 'number' || config.version !== 1) {\n throw new ConfigValidationError('Config version must be 1', 'version')\n }\n\n if (!Array.isArray(config.backends) || config.backends.length === 0) {\n throw new ConfigValidationError('Config must have at least one backend', 'backends')\n }\n\n const backends: BackendConfig[] = config.backends.map((entry: unknown, i: number) =>\n validateBackendEntry(entry, i),\n )\n\n if (!isObject(config.keyRotation)) {\n throw new ConfigValidationError('Config keyRotation must be an object', 'keyRotation')\n }\n if (\n typeof config.keyRotation.gracePeriodDays !== 'number' ||\n config.keyRotation.gracePeriodDays <= 0\n ) {\n throw new ConfigValidationError(\n 'Config keyRotation.gracePeriodDays must be a positive number',\n 'keyRotation.gracePeriodDays',\n )\n }\n\n if (!isObject(config.defaults)) {\n throw new ConfigValidationError('Config defaults must be an object', 'defaults')\n }\n if (typeof config.defaults.ttlMinutes !== 'number' || config.defaults.ttlMinutes <= 0) {\n throw new ConfigValidationError(\n 'Config defaults.ttlMinutes must be a positive number',\n 'defaults.ttlMinutes',\n )\n }\n // Coerce string trust tier values from Rust CLI config (which serializes as \"1\"/\"2\"/\"3\")\n let tier: unknown = config.defaults.trustTier\n if (typeof tier === 'string') {\n const parsed = Number(tier)\n if (!Number.isNaN(parsed)) {\n tier = parsed\n }\n }\n if (tier !== 1 && tier !== 2 && tier !== 3) {\n throw new ConfigValidationError(\n 'Config defaults.trustTier must be 1, 2, or 3',\n 'defaults.trustTier',\n )\n }\n\n const result: VaultConfig = {\n version: 1,\n backends,\n keyRotation: {\n gracePeriodDays: config.keyRotation.gracePeriodDays,\n },\n defaults: {\n ttlMinutes: config.defaults.ttlMinutes,\n trustTier: tier satisfies TrustTier,\n },\n }\n\n if (config.developmentMode !== undefined) {\n if (!isObject(config.developmentMode)) {\n throw new ConfigValidationError('Config developmentMode must be an object', 'developmentMode')\n }\n if (!Array.isArray(config.developmentMode.executables)) {\n throw new ConfigValidationError(\n 'Config developmentMode.executables must be an array',\n 'developmentMode.executables',\n )\n }\n const executables: string[] = []\n for (const [i, exe] of Array.from(config.developmentMode.executables).entries()) {\n if (typeof exe !== 'string') {\n throw new ConfigValidationError(\n `Config developmentMode.executables[${String(i)}] must be a string`,\n `developmentMode.executables[${String(i)}]`,\n )\n }\n executables.push(exe)\n }\n result.developmentMode = { executables }\n }\n\n return result\n}\n\n/**\n * Load the vaultkeeper config from disk, falling back to platform defaults\n * only when the config file is missing (`ENOENT`).\n *\n * Any other read failure (e.g. `EACCES`, `EISDIR`) is a genuinely broken or\n * unreadable config and is rethrown as a {@link FilesystemError} rather than\n * silently defaulted — silently defaulting on a permissions error would hide\n * the problem from `doctor` and `config show` (issue #68). A present file\n * that fails to parse as JSON throws {@link ConfigParseError}; a present file\n * that parses but fails schema validation throws {@link ConfigValidationError}.\n * All three error messages include the config file path and a remediation\n * hint naming `vaultkeeper config init --force` (via the separate\n * `@vaultkeeper/cli` package) as well as the JS-API alternative of repairing\n * or replacing the config directly — the supported recovery paths for an\n * existing-but-broken config (issues #97, #100).\n *\n * @param configDir - Directory containing config.json. Defaults to\n * `getDefaultConfigDir()`, which itself honors `VAULTKEEPER_CONFIG_DIR`\n * before falling back to the platform-appropriate path.\n * @public\n */\nexport async function loadConfig(configDir?: string): Promise<VaultConfig> {\n const dir = configDir ?? getDefaultConfigDir()\n const configPath = path.join(dir, 'config.json')\n\n let raw: string\n try {\n raw = await fs.readFile(configPath, 'utf-8')\n } catch (err) {\n if (hasErrorCode(err, 'ENOENT')) {\n return defaultConfig()\n }\n throw new FilesystemError(\n `Cannot read config file at ${configPath}: ${describeError(err)}. ${CONFIG_REMEDIATION_HINT}`,\n configPath,\n 'read',\n err,\n )\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (err) {\n const location = describeJsonSyntaxLocation(err, raw)\n const locationSuffix = location !== undefined ? ` at ${location}` : ''\n throw new ConfigParseError(\n `Failed to parse config file at ${configPath}${locationSuffix}: ${describeError(err)}. ` +\n CONFIG_REMEDIATION_HINT,\n configPath,\n location,\n )\n }\n\n try {\n return validateConfig(parsed)\n } catch (err) {\n // Preserve the concrete subclass so its machine-readable context survives\n // the file-path re-wrap: doctor maps an UnknownBackendTypeError to a\n // richer preflight error (invalid type + valid options) than a plain\n // schema failure (issue #215).\n if (err instanceof UnknownBackendTypeError) {\n throw new UnknownBackendTypeError(\n `Invalid config at ${configPath}: ${err.message}. ${CONFIG_REMEDIATION_HINT}`,\n err.field,\n err.backendType,\n err.knownTypes,\n configPath,\n )\n }\n if (err instanceof ConfigValidationError) {\n // Regression: issue #118 — this previously joined the diagnosis and the\n // remediation hint with only a space (`...non-empty string\n // Fix the file...`), reading as a run-on with no sentence break. A\n // period now separates them, matching the punctuation already used for\n // the read-error and parse-error variants of this same hint above.\n throw new ConfigValidationError(\n `Invalid config at ${configPath}: ${err.message}. ${CONFIG_REMEDIATION_HINT}`,\n err.field,\n configPath,\n )\n }\n throw err\n }\n}\n","/**\n * Encrypted file fallback backend implementation.\n *\n * @remarks\n * Stores secrets encrypted with AES-256-GCM using Node.js native crypto.\n * Each secret is stored as an individual encrypted file under\n * `<configDir>/file/`, where `configDir` is the same resolved config\n * directory used for the config file and key material (see\n * {@link getDefaultConfigDir}). A randomly generated key stored in a\n * protected file is used for encryption.\n *\n * Encrypted file format (all parts base64-encoded, colon-separated):\n * <iv>:<authTag>:<ciphertext>\n *\n * @remarks Back-compat (issue #99)\n * Prior to this fix, the default storage directory was\n * `$HOME/.vaultkeeper/file`, independent of the resolved config directory.\n * When no explicit `path` is configured, reads (`retrieve`/`exists`/`delete`/\n * `list`) transparently fall back to that legacy location if an entry is not\n * found under the new default, so secrets stored there before this change\n * remain reachable. Writes (`store`) always target the new location — the\n * legacy directory is never written to going forward.\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport * as crypto from 'node:crypto'\nimport {\n SecretNotFoundError,\n FilesystemError,\n DecryptionError,\n toFilesystemError,\n SigningKeyNotFoundError,\n SigningKeyAlreadyExistsError,\n InvalidAlgorithmError,\n InvalidKeyMaterialError,\n} from '../errors.js'\nimport { encryptGcm, decryptGcm, getOrCreateWrapKey } from '../util/at-rest.js'\nimport { getDefaultConfigDir } from '../config.js'\nimport type { ListableBackend, SigningBackend } from './types.js'\nimport type { SigningAlgorithm, SigningPublicKey } from '../types.js'\n\nconst STORAGE_DIR_NAME = 'file'\nconst KEY_FILE = '.key'\n/**\n * Subdirectory (under the secret storage dir) holding encrypted signing-key\n * private material. Kept separate from the `.enc` secret files so a signing key\n * can never be read through {@link FileBackend.retrieve} or surface in\n * {@link FileBackend.list}.\n */\nconst SIGNING_DIR_NAME = 'signing-keys'\n/** Namespace prefix for signing-key identifiers (see {@link SigningBackend}). */\nconst SIGNING_KEY_PREFIX = 'signing-key:'\n/** Signing algorithms this backend can generate keys for. */\nconst SUPPORTED_SIGNING_ALGORITHMS: readonly SigningAlgorithm[] = ['EdDSA']\n\n/** Compute the stable kid for an SPKI-DER public key: base64url(sha256(der)). */\nfunction computeKid(spkiDer: Buffer): string {\n return crypto.createHash('sha256').update(spkiDer).digest('base64url')\n}\n\n/** Strip the namespace prefix to recover the caller-facing signing-key name. */\nfunction displayKeyName(id: string): string {\n return id.startsWith(SIGNING_KEY_PREFIX) ? id.slice(SIGNING_KEY_PREFIX.length) : id\n}\n\n/**\n * Pre-#99 default storage directory, kept as a read-only fallback.\n *\n * @remarks\n * Computed lazily (not as a module-level constant) so it reflects\n * `os.homedir()` at construction time rather than at module load time —\n * matching the existing lazy-resolution pattern the rest of this module\n * relies on for testability.\n */\nfunction legacyStorageDir(): string {\n return path.join(os.homedir(), '.vaultkeeper', 'file')\n}\n\n/**\n * Resolve the storage directory for a FileBackend instance.\n *\n * When `configuredPath` is provided (from `BackendConfig.path`), secrets are\n * stored directly under that directory. Otherwise the default is\n * `<configDir>/file`, where `configDir` is the resolved config directory\n * (the value passed to the backend factory, or `getDefaultConfigDir()` when\n * constructing a `FileBackend` directly without one).\n */\nfunction resolveStorageDir(configuredPath?: string, configDir?: string): string {\n // Config validation (see validateConfig) rejects empty/whitespace-only\n // paths, so any defined value here is guaranteed non-blank.\n if (configuredPath !== undefined) {\n return configuredPath\n }\n return path.join(configDir ?? getDefaultConfigDir(), STORAGE_DIR_NAME)\n}\n\nfunction getEntryPath(storageDir: string, id: string): string {\n const safeId = Buffer.from(id, 'utf8').toString('hex')\n return path.join(storageDir, `${safeId}.enc`)\n}\n\nasync function ensureStorageDir(storageDir: string): Promise<void> {\n try {\n await fs.mkdir(storageDir, { recursive: true, mode: 0o700 })\n } catch (err) {\n // With `recursive: true`, mkdir never throws EEXIST for a directory that\n // already exists — that case resolves silently. An EEXIST here means\n // `storageDir` itself already exists as something other than a\n // directory (e.g. a regular file), a genuine collision that must\n // surface rather than be swallowed as if the directory were ready.\n throw new FilesystemError(\n `Failed to create storage directory: ${storageDir}`,\n storageDir,\n 'rwx',\n err,\n )\n }\n}\n\nasync function getOrCreateKey(storageDir: string): Promise<Buffer> {\n return getOrCreateWrapKey(path.join(storageDir, KEY_FILE))\n}\n\n/**\n * Encrypted file fallback backend.\n *\n * @remarks\n * Available on all platforms. Stores secrets as AES-256-GCM encrypted files\n * using Node.js native crypto — no external tools required.\n * Not as secure as OS-native keystores, but provides a portable fallback.\n *\n * @internal\n */\nexport class FileBackend implements ListableBackend, SigningBackend {\n readonly type = 'file'\n readonly displayName = 'Encrypted File Store'\n\n readonly #storageDir: string\n /** Directory holding encrypted signing-key private material. */\n readonly #signingDir: string\n /**\n * Pre-#99 default storage directory, consulted as a read-only fallback\n * when `storageDir` was not explicitly configured. `undefined` when an\n * explicit `storageDir` was given — an explicit path never falls back.\n */\n readonly #legacyStorageDir: string | undefined\n\n /**\n * @param storageDir - Directory in which encrypted secrets are stored.\n * Sourced from `BackendConfig.path`. Defaults to `<configDir>/file`.\n * @param configDir - Resolved config directory, used to compute the\n * default `storageDir` when one is not explicitly provided. Ignored when\n * `storageDir` is given. Defaults to `getDefaultConfigDir()`.\n */\n constructor(storageDir?: string, configDir?: string) {\n this.#storageDir = resolveStorageDir(storageDir, configDir)\n this.#legacyStorageDir = storageDir === undefined ? legacyStorageDir() : undefined\n this.#signingDir = path.join(this.#storageDir, SIGNING_DIR_NAME)\n }\n\n async isAvailable(): Promise<boolean> {\n // Node.js crypto is always available; check we can create the storage dir.\n try {\n await ensureStorageDir(this.#storageDir)\n return true\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const storageDir = this.#storageDir\n await ensureStorageDir(storageDir)\n const key = await getOrCreateKey(storageDir)\n const entryPath = getEntryPath(storageDir, id)\n const encrypted = encryptGcm(key, secret)\n try {\n await fs.writeFile(entryPath, encrypted, { mode: 0o600 })\n } catch (err) {\n throw toFilesystemError(err, 'secret file', entryPath, 'write')\n }\n }\n\n /**\n * Attempt to read and decrypt the entry for `id` from `storageDir`.\n * Returns `undefined` (rather than throwing) when the entry does not\n * exist in `storageDir`, so callers can probe a fallback location.\n */\n async #tryRetrieveFrom(storageDir: string, id: string): Promise<string | undefined> {\n const entryPath = getEntryPath(storageDir, id)\n\n let encoded: string\n try {\n encoded = await fs.readFile(entryPath, 'utf8')\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n return undefined\n }\n throw toFilesystemError(err, 'secret file', entryPath, 'read')\n }\n\n const key = await getOrCreateKey(storageDir)\n try {\n return decryptGcm(key, encoded, entryPath)\n } catch (err) {\n throw new DecryptionError(\n `Failed to decrypt secret: ${err instanceof Error ? err.message : String(err)}`,\n entryPath,\n )\n }\n }\n\n async retrieve(id: string): Promise<string> {\n const fromPrimary = await this.#tryRetrieveFrom(this.#storageDir, id)\n if (fromPrimary !== undefined) {\n return fromPrimary\n }\n\n if (this.#legacyStorageDir !== undefined) {\n const fromLegacy = await this.#tryRetrieveFrom(this.#legacyStorageDir, id)\n if (fromLegacy !== undefined) {\n return fromLegacy\n }\n }\n\n throw new SecretNotFoundError(`Secret not found in file store: ${id}`)\n }\n\n async delete(id: string): Promise<void> {\n const entryPath = getEntryPath(this.#storageDir, id)\n\n try {\n await fs.unlink(entryPath)\n return\n } catch (err) {\n if (!(err instanceof Error && 'code' in err && err.code === 'ENOENT')) {\n throw toFilesystemError(err, 'secret file', entryPath, 'delete')\n }\n }\n\n if (this.#legacyStorageDir !== undefined) {\n const legacyEntryPath = getEntryPath(this.#legacyStorageDir, id)\n try {\n await fs.unlink(legacyEntryPath)\n return\n } catch (err) {\n if (!(err instanceof Error && 'code' in err && err.code === 'ENOENT')) {\n throw toFilesystemError(err, 'secret file', legacyEntryPath, 'delete')\n }\n }\n }\n\n throw new SecretNotFoundError(`Secret not found in file store: ${id}`)\n }\n\n async exists(id: string): Promise<boolean> {\n if (await FileBackend.#entryExists(this.#storageDir, id)) {\n return true\n }\n if (this.#legacyStorageDir !== undefined) {\n return FileBackend.#entryExists(this.#legacyStorageDir, id)\n }\n return false\n }\n\n static async #entryExists(storageDir: string, id: string): Promise<boolean> {\n try {\n await fs.access(getEntryPath(storageDir, id))\n return true\n } catch {\n return false\n }\n }\n\n async list(): Promise<string[]> {\n const ids = new Set<string>()\n for (const storageDir of [this.#storageDir, this.#legacyStorageDir].filter(\n (dir): dir is string => dir !== undefined,\n )) {\n for (const id of await FileBackend.#listEntries(storageDir)) {\n ids.add(id)\n }\n }\n return Array.from(ids)\n }\n\n static async #listEntries(storageDir: string): Promise<string[]> {\n let entries: string[]\n try {\n entries = await fs.readdir(storageDir)\n } catch {\n return []\n }\n return entries\n .filter((f) => f.endsWith('.enc'))\n .map((f) => Buffer.from(f.slice(0, -4), 'hex').toString('utf8'))\n }\n\n // --- Signing contract (SigningBackend) ---\n\n /** On-disk path of the encrypted private key for a signing-key id. */\n #signingKeyPath(id: string): string {\n const safeId = Buffer.from(id, 'utf8').toString('hex')\n return path.join(this.#signingDir, `${safeId}.pem.enc`)\n }\n\n /**\n * Load and decrypt the PKCS#8 private key PEM for `id`, or throw\n * {@link SigningKeyNotFoundError} when no signing key exists under `id`.\n */\n async #loadSigningKeyPem(id: string): Promise<string> {\n const keyPath = this.#signingKeyPath(id)\n let encoded: string\n try {\n encoded = await fs.readFile(keyPath, 'utf8')\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n throw new SigningKeyNotFoundError(\n `Signing key not found: ${displayKeyName(id)}`,\n displayKeyName(id),\n )\n }\n throw toFilesystemError(err, 'signing key', keyPath, 'read')\n }\n const wrapKey = await getOrCreateKey(this.#storageDir)\n try {\n return decryptGcm(wrapKey, encoded)\n } catch (err) {\n throw new DecryptionError(\n `Failed to decrypt signing key: ${err instanceof Error ? err.message : String(err)}`,\n keyPath,\n )\n }\n }\n\n async generateSigningKey(id: string, algorithm: SigningAlgorithm): Promise<void> {\n // Runtime guard for JS callers that may bypass the compile-time type.\n if (!SUPPORTED_SIGNING_ALGORITHMS.includes(algorithm)) {\n throw new InvalidAlgorithmError(\n `Unsupported signing algorithm '${algorithm}'. Supported: ${SUPPORTED_SIGNING_ALGORITHMS.join(', ')}.`,\n algorithm,\n [...SUPPORTED_SIGNING_ALGORITHMS],\n )\n }\n await ensureStorageDir(this.#storageDir)\n try {\n await fs.mkdir(this.#signingDir, { recursive: true, mode: 0o700 })\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code !== 'EEXIST') {\n throw toFilesystemError(err, 'signing-key directory', this.#signingDir, 'create')\n }\n }\n\n const keyPath = this.#signingKeyPath(id)\n // Never silently replace an existing signing key — a regenerated key would\n // invalidate every previously exported/pinned public key (a signature-trust\n // break). Probe for an existing key, but distinguish the three outcomes:\n // - access() succeeds -> a key exists; refuse (already-exists).\n // - access() fails w/ ENOENT -> confirmed absent; safe to generate.\n // - access() fails otherwise -> a transient/permission fault (e.g. EACCES).\n // Treating that as \"absent\" could clobber an existing key, so surface it\n // as a typed FilesystemError instead of proceeding.\n let keyExists = false\n try {\n await fs.access(keyPath)\n keyExists = true\n } catch (err) {\n if (!(err instanceof Error && 'code' in err && err.code === 'ENOENT')) {\n throw toFilesystemError(err, 'signing key', keyPath, 'read')\n }\n // ENOENT: confirmed absent — fall through to generation.\n }\n if (keyExists) {\n throw new SigningKeyAlreadyExistsError(\n `Signing key already exists: ${displayKeyName(id)}`,\n displayKeyName(id),\n )\n }\n\n const { privateKey } = crypto.generateKeyPairSync('ed25519')\n const pkcs8Pem = privateKey.export({ type: 'pkcs8', format: 'pem' }).toString()\n const wrapKey = await getOrCreateKey(this.#storageDir)\n const encrypted = encryptGcm(wrapKey, pkcs8Pem)\n try {\n // wx: fail if the path was created between our probe and here (TOCTOU),\n // so a concurrent enrollment can never be silently overwritten either.\n await fs.writeFile(keyPath, encrypted, { mode: 0o600, flag: 'wx' })\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'EEXIST') {\n throw new SigningKeyAlreadyExistsError(\n `Signing key already exists: ${displayKeyName(id)}`,\n displayKeyName(id),\n )\n }\n throw toFilesystemError(err, 'signing key', keyPath, 'write')\n }\n }\n\n /**\n * Load, decrypt, and parse the private key for `id` into a `KeyObject`.\n *\n * A parse failure means the decrypted-at-rest material is corrupt or tampered\n * (it decrypted cleanly but is not a valid PKCS#8 private key). It is\n * translated into a typed {@link InvalidKeyMaterialError} — never allowed to\n * surface as a raw Node crypto exception — and the message never echoes any\n * part of the key material.\n */\n async #loadSigningKeyObject(id: string): Promise<crypto.KeyObject> {\n const pkcs8Pem = await this.#loadSigningKeyPem(id)\n try {\n return crypto.createPrivateKey(pkcs8Pem)\n } catch {\n throw new InvalidKeyMaterialError(\n `The stored signing key for \"${displayKeyName(id)}\" is not valid private key material ` +\n '(it may be corrupt or tampered).',\n )\n }\n }\n\n async getPublicKey(id: string): Promise<SigningPublicKey> {\n const privateKey = await this.#loadSigningKeyObject(id)\n const publicKey = crypto.createPublicKey(privateKey)\n const publicKeyPem = publicKey.export({ type: 'spki', format: 'pem' }).toString()\n const spkiDer = publicKey.export({ type: 'spki', format: 'der' })\n return {\n publicKeyPem,\n algorithm: 'EdDSA',\n kid: computeKid(spkiDer),\n }\n }\n\n async signWithKey(id: string, data: Buffer): Promise<Buffer> {\n const privateKey = await this.#loadSigningKeyObject(id)\n // Ed25519: the algorithm is implicit in the key, so pass null.\n return crypto.sign(null, data, privateKey)\n }\n}\n","/**\n * CLI spawn wrapper for executing external commands.\n */\n\nimport { spawn } from 'node:child_process'\nimport { PluginNotFoundError, ExecError } from '../errors.js'\n\n/** Options for command execution. */\nexport interface ExecCommandOptions {\n /** Input to write to stdin */\n stdin?: string | undefined\n /** Timeout in milliseconds */\n timeoutMs?: number | undefined\n}\n\n/** Result of a command execution. */\nexport interface ExecCommandResult {\n stdout: string\n stderr: string\n exitCode: number\n}\n\n/**\n * Execute a command and return stdout.\n * @throws {ExecError} if the command exits with a non-zero code, or if the\n * process cannot be spawned for any reason other than the binary being\n * missing (e.g. `EACCES`).\n * @throws {PluginNotFoundError} if the command binary is not found (`ENOENT`).\n */\nexport async function execCommand(\n command: string,\n args: string[],\n options?: ExecCommandOptions,\n): Promise<string> {\n const result = await execCommandFull(command, args, options)\n if (result.exitCode !== 0) {\n throw new ExecError(\n `Command failed with exit code ${String(result.exitCode)}: ${result.stderr}`,\n command,\n )\n }\n return result.stdout.trim()\n}\n\n/**\n * Execute a command and return the full result.\n */\nexport function execCommandFull(\n command: string,\n args: string[],\n options?: ExecCommandOptions,\n): Promise<ExecCommandResult> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, {\n stdio: [options?.stdin !== undefined ? 'pipe' : 'ignore', 'pipe', 'pipe'],\n })\n let stdout = ''\n let stderr = ''\n // Undefined when no timeoutMs was given, or once the timer has fired.\n // Tracked so 'close'/'error' can clear it — otherwise an already-settled\n // promise still leaves the timer pending, which keeps the event loop\n // alive until it fires and calls proc.kill() on an already-exited\n // process (regression: PR #164 review, issue #127).\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n\n proc.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString()\n })\n\n proc.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString()\n })\n\n if (options?.stdin !== undefined && proc.stdin) {\n proc.stdin.write(options.stdin)\n proc.stdin.end()\n }\n\n if (options?.timeoutMs !== undefined) {\n timeoutHandle = setTimeout(() => {\n // The timer has already fired, so there is nothing left to clear —\n // reset to undefined so the later 'close'/'error' handler's guard\n // matches reality instead of calling clearTimeout on a stale handle.\n timeoutHandle = undefined\n proc.kill('SIGTERM')\n reject(new ExecError(`Command timed out after ${String(options.timeoutMs)}ms`, command))\n }, options.timeoutMs)\n }\n\n proc.on('close', (code) => {\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle)\n }\n resolve({ stdout, stderr, exitCode: code ?? 1 })\n })\n\n proc.on('error', (error) => {\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle)\n }\n if ('code' in error && error.code === 'ENOENT') {\n reject(\n new PluginNotFoundError(\n `'${command}' is not installed or not found in PATH`,\n command,\n '',\n ),\n )\n } else {\n // Any other spawn failure (EACCES on the binary, EMFILE, ...) must\n // surface typed, not as the raw Node error — the last plain-error\n // escape on this utility's failure paths.\n reject(new ExecError(`Failed to spawn '${command}': ${error.message}`, command))\n }\n })\n })\n}\n","/**\n * macOS Keychain backend implementation.\n *\n * @remarks\n * Stores secrets as base64-encoded generic passwords in the macOS Keychain\n * using the `security` CLI tool. Service name format: `vaultkeeper:<id>`.\n */\n\nimport { execCommand, execCommandFull } from '../util/exec.js'\nimport { SecretNotFoundError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\nconst ACCOUNT = 'vaultkeeper'\nconst SERVICE_PREFIX = 'vaultkeeper:'\n\n/**\n * macOS Keychain secret backend.\n *\n * @remarks\n * Only available on Darwin (macOS). Uses `security` CLI to store/retrieve\n * generic passwords. Secrets are base64-encoded before storage.\n *\n * @internal\n */\nexport class KeychainBackend implements ListableBackend {\n readonly type = 'keychain'\n readonly displayName = 'macOS Keychain'\n\n async isAvailable(): Promise<boolean> {\n if (process.platform !== 'darwin') {\n return false\n }\n try {\n const result = await execCommandFull('security', ['version'])\n return result.exitCode === 0\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const service = `${SERVICE_PREFIX}${id}`\n const encoded = Buffer.from(secret, 'utf8').toString('base64')\n // Delete existing entry first (ignore errors) then add fresh\n await execCommandFull('security', ['delete-generic-password', '-a', ACCOUNT, '-s', service])\n await execCommand('security', [\n 'add-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n '-w',\n encoded,\n ])\n }\n\n async retrieve(id: string): Promise<string> {\n const service = `${SERVICE_PREFIX}${id}`\n const result = await execCommandFull('security', [\n 'find-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n '-w',\n ])\n if (result.exitCode !== 0) {\n throw new SecretNotFoundError(`Secret not found in macOS Keychain: ${id}`)\n }\n const encoded = result.stdout.trim()\n return Buffer.from(encoded, 'base64').toString('utf8')\n }\n\n async delete(id: string): Promise<void> {\n const service = `${SERVICE_PREFIX}${id}`\n const result = await execCommandFull('security', [\n 'delete-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n ])\n if (result.exitCode !== 0) {\n throw new SecretNotFoundError(`Secret not found in macOS Keychain: ${id}`)\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const service = `${SERVICE_PREFIX}${id}`\n const result = await execCommandFull('security', [\n 'find-generic-password',\n '-a',\n ACCOUNT,\n '-s',\n service,\n ])\n return result.exitCode === 0\n }\n\n async list(): Promise<string[]> {\n const result = await execCommandFull('security', ['dump-keychain'])\n if (result.exitCode !== 0) {\n return []\n }\n const ids: string[] = []\n const servicePattern = /0x00000007 <blob>=\"vaultkeeper:([^\"]+)\"/g\n let match: RegExpExecArray | null = servicePattern.exec(result.stdout)\n while (match !== null) {\n const id = match[1]\n if (id !== undefined) {\n ids.push(id)\n }\n match = servicePattern.exec(result.stdout)\n }\n return ids\n }\n}\n","/**\n * Windows DPAPI backend implementation.\n *\n * @remarks\n * Stores secrets using Windows Data Protection API (DPAPI) via PowerShell.\n * DPAPI encrypts data using the current user's credentials and machine key.\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { execCommand, execCommandFull } from '../util/exec.js'\nimport { SecretNotFoundError, toFilesystemError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\n/**\n * Resolve the storage directory for a DpapiBackend instance.\n *\n * When `configuredPath` is provided (from `BackendConfig.path`), encrypted\n * blobs are stored directly under that directory. Otherwise the default\n * `$HOME/.vaultkeeper/dpapi` location is used.\n */\nfunction resolveStorageDir(configuredPath?: string): string {\n // Config validation (see validateConfig) rejects empty/whitespace-only\n // paths, so any defined value here is guaranteed non-blank.\n if (configuredPath !== undefined) {\n return configuredPath\n }\n return path.join(os.homedir(), '.vaultkeeper', 'dpapi')\n}\n\nfunction getEntryPath(storageDir: string, id: string): string {\n // Use hex encoding of id for safe filenames\n const safeId = Buffer.from(id, 'utf8').toString('hex')\n return path.join(storageDir, `${safeId}.enc`)\n}\n\n/**\n * Windows DPAPI secret backend.\n *\n * @remarks\n * Only available on Windows. Uses PowerShell with\n * [System.Security.Cryptography.ProtectedData] to encrypt/decrypt secrets.\n * Encrypted blobs are stored in ~/.vaultkeeper/dpapi/.\n *\n * @internal\n */\nexport class DpapiBackend implements ListableBackend {\n readonly type = 'dpapi'\n readonly displayName = 'Windows DPAPI'\n\n readonly #storageDir: string\n\n /**\n * @param storageDir - Directory in which encrypted blobs are stored.\n * Sourced from `BackendConfig.path`. Defaults to `$HOME/.vaultkeeper/dpapi`.\n */\n constructor(storageDir?: string) {\n this.#storageDir = resolveStorageDir(storageDir)\n }\n\n async isAvailable(): Promise<boolean> {\n if (process.platform !== 'win32') {\n return false\n }\n try {\n const result = await execCommandFull('powershell', [\n '-NoProfile',\n '-Command',\n '[System.Security.Cryptography.ProtectedData] | Out-Null; exit 0',\n ])\n return result.exitCode === 0\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const storageDir = this.#storageDir\n await fs.mkdir(storageDir, { recursive: true })\n const entryPath = getEntryPath(storageDir, id)\n\n const script = [\n 'Add-Type -AssemblyName System.Security',\n `$bytes = [System.Text.Encoding]::UTF8.GetBytes(${JSON.stringify(secret)})`,\n '$entropy = $null',\n '$scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser',\n '$encrypted = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $entropy, $scope)',\n `[System.IO.File]::WriteAllBytes(${JSON.stringify(entryPath)}, $encrypted)`,\n ].join('; ')\n\n await execCommand('powershell', ['-NoProfile', '-Command', script])\n }\n\n async retrieve(id: string): Promise<string> {\n const storageDir = this.#storageDir\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n } catch {\n throw new SecretNotFoundError(`Secret not found in Windows DPAPI store: ${id}`)\n }\n\n const script = [\n 'Add-Type -AssemblyName System.Security',\n `$encrypted = [System.IO.File]::ReadAllBytes(${JSON.stringify(entryPath)})`,\n '$entropy = $null',\n '$scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser',\n '$bytes = [System.Security.Cryptography.ProtectedData]::Unprotect($encrypted, $entropy, $scope)',\n 'Write-Output ([System.Text.Encoding]::UTF8.GetString($bytes))',\n ].join('; ')\n\n return execCommand('powershell', ['-NoProfile', '-Command', script])\n }\n\n async delete(id: string): Promise<void> {\n const storageDir = this.#storageDir\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.unlink(entryPath)\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n throw new SecretNotFoundError(`Secret not found in Windows DPAPI store: ${id}`)\n }\n // Same contract as FileBackend.delete (#126): a non-ENOENT unlink\n // failure surfaces as a typed FilesystemError, never a raw Node error.\n throw toFilesystemError(err, 'secret file', entryPath, 'delete')\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const storageDir = this.#storageDir\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n return true\n } catch {\n return false\n }\n }\n\n async list(): Promise<string[]> {\n const storageDir = this.#storageDir\n let entries: string[]\n try {\n entries = await fs.readdir(storageDir)\n } catch {\n return []\n }\n return entries\n .filter((f) => f.endsWith('.enc'))\n .map((f) => Buffer.from(f.slice(0, -4), 'hex').toString('utf8'))\n }\n}\n","/**\n * Linux secret-tool backend implementation.\n *\n * @remarks\n * Stores secrets using the `secret-tool` CLI which interfaces with the\n * GNOME Keyring or any other Secret Service API implementation via D-Bus.\n */\n\nimport { execCommand, execCommandFull } from '../util/exec.js'\nimport { SecretNotFoundError } from '../errors.js'\nimport type { ListableBackend } from './types.js'\n\nconst ATTRIBUTE_KEY = 'vaultkeeper-id'\nconst LABEL_PREFIX = 'vaultkeeper: '\n\n/**\n * Linux secret-tool (Secret Service API) backend.\n *\n * @remarks\n * Only available on Linux with secret-tool installed. Requires a running\n * Secret Service (e.g., GNOME Keyring or KWallet with Secret Service plugin).\n *\n * @internal\n */\nexport class SecretToolBackend implements ListableBackend {\n readonly type = 'secret-tool'\n readonly displayName = 'Linux Secret Service (secret-tool)'\n\n async isAvailable(): Promise<boolean> {\n if (process.platform !== 'linux') {\n return false\n }\n try {\n const result = await execCommandFull('secret-tool', ['--version'])\n return result.exitCode === 0\n } catch {\n return false\n }\n }\n\n async store(id: string, secret: string): Promise<void> {\n const label = `${LABEL_PREFIX}${id}`\n await execCommand('secret-tool', ['store', '--label', label, ATTRIBUTE_KEY, id], {\n stdin: secret,\n })\n }\n\n async retrieve(id: string): Promise<string> {\n const result = await execCommandFull('secret-tool', ['lookup', ATTRIBUTE_KEY, id])\n if (result.exitCode !== 0 || result.stdout.trim() === '') {\n throw new SecretNotFoundError(`Secret not found in Secret Service: ${id}`)\n }\n return result.stdout.trim()\n }\n\n async delete(id: string): Promise<void> {\n const result = await execCommandFull('secret-tool', ['clear', ATTRIBUTE_KEY, id])\n if (result.exitCode !== 0) {\n throw new SecretNotFoundError(`Secret not found in Secret Service: ${id}`)\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const result = await execCommandFull('secret-tool', ['lookup', ATTRIBUTE_KEY, id])\n return result.exitCode === 0 && result.stdout.trim() !== ''\n }\n\n async list(): Promise<string[]> {\n const result = await execCommandFull('secret-tool', ['search', ATTRIBUTE_KEY, ''])\n if (result.exitCode !== 0) {\n return []\n }\n const ids: string[] = []\n const attrPattern = new RegExp(`attribute\\\\.${ATTRIBUTE_KEY} = (.+)`, 'g')\n let match: RegExpExecArray | null = attrPattern.exec(result.stdout)\n while (match !== null) {\n const id = match[1]\n if (id !== undefined) {\n ids.push(id)\n }\n match = attrPattern.exec(result.stdout)\n }\n return ids\n }\n}\n","/**\n * Shared 1Password item read/write operations.\n *\n * @remarks\n * Both `OnePasswordBackend` (session client) and `one-password-worker.ts` (the\n * per-access worker process spawned for a fresh biometric approval) look items\n * up by title the same way, and must create-or-update / delete a\n * `Password`-category item identically — see issue #211. Centralising that\n * logic here keeps the two call sites from diverging.\n *\n * All SDK types are imported `import type` only, so this module carries no\n * runtime dependency on `@1password/sdk` and stays lazy-load-safe like the\n * rest of the 1Password integration: callers pass in an already-created\n * `Client` plus the SDK's own `ItemCategory`/`ItemFieldType` enum members\n * (obtained from their own dynamically-loaded SDK instance).\n *\n * @internal\n */\n\nimport type { Client, Item, ItemOverview, ItemCategory, ItemFieldType } from '@1password/sdk'\n\n/** Tag applied to every item vaultkeeper manages, used to scope list/find calls. */\nexport const TAG = 'vaultkeeper'\n\n/** Title of the field that carries the secret value. */\nexport const PASSWORD_FIELD_TITLE = 'password'\n\n/**\n * List all items in the vault tagged \"vaultkeeper\" and find one with the\n * matching title (= secret ID). Returns `undefined` if not found.\n */\nexport async function findItemOverviewByTitle(\n client: Client,\n vaultId: string,\n title: string,\n): Promise<ItemOverview | undefined> {\n const overviews = await client.items.list(vaultId)\n for (const overview of overviews) {\n if (overview.title === title && overview.tags.includes(TAG)) {\n return overview\n }\n }\n return undefined\n}\n\n/**\n * Fetch the full item for a given secret id. Returns `undefined` when no\n * tagged item with that title exists; rejects if the item fetch itself fails\n * (the overview was found but `items.get` errored).\n */\nexport async function findItemByTitle(\n client: Client,\n vaultId: string,\n title: string,\n): Promise<Item | undefined> {\n const overview = await findItemOverviewByTitle(client, vaultId, title)\n if (overview === undefined) return undefined\n return client.items.get(vaultId, overview.id)\n}\n\n/**\n * Extract the concealed password field value from an item, or `undefined` if\n * the item has no `password`-titled field.\n */\nexport function extractPasswordField(item: Item): string | undefined {\n for (const field of item.fields) {\n if (field.title === PASSWORD_FIELD_TITLE) {\n return field.value\n }\n }\n return undefined\n}\n\n/**\n * Create-or-update a `Password`-category item's concealed password field.\n *\n * @remarks\n * Updates the existing item's password field (appending one if missing) via\n * `items.put`, or creates a new tagged item via `items.create` when none\n * exists yet under `title`. `passwordCategory`/`concealedFieldType` are the\n * caller's own `ItemCategory.Password` / `ItemFieldType.Concealed` enum\n * members — passed in rather than imported here so this module never needs a\n * value import of the optional `@1password/sdk` peer.\n */\nexport async function storeSecretItem(\n client: Client,\n vaultId: string,\n title: string,\n secret: string,\n passwordCategory: ItemCategory,\n concealedFieldType: ItemFieldType,\n): Promise<void> {\n const existing = await findItemByTitle(client, vaultId, title)\n\n if (existing !== undefined) {\n const hasPasswordField = existing.fields.some((f) => f.title === PASSWORD_FIELD_TITLE)\n const updatedFields = hasPasswordField\n ? existing.fields.map((f) => (f.title === PASSWORD_FIELD_TITLE ? { ...f, value: secret } : f))\n : [\n ...existing.fields,\n {\n id: 'password',\n title: PASSWORD_FIELD_TITLE,\n fieldType: concealedFieldType,\n value: secret,\n },\n ]\n await client.items.put({ ...existing, fields: updatedFields })\n } else {\n await client.items.create({\n category: passwordCategory,\n vaultId,\n title,\n tags: [TAG],\n fields: [\n {\n id: 'password',\n title: PASSWORD_FIELD_TITLE,\n fieldType: concealedFieldType,\n value: secret,\n },\n ],\n })\n }\n}\n\n/**\n * Delete the tagged item matching `title`.\n * @returns `true` if a matching item was found and deleted, `false` if none matched.\n */\nexport async function deleteSecretItem(\n client: Client,\n vaultId: string,\n title: string,\n): Promise<boolean> {\n const overview = await findItemOverviewByTitle(client, vaultId, title)\n if (overview === undefined) return false\n await client.items.delete(vaultId, overview.id)\n return true\n}\n","/**\n * Shared constants for 1Password SDK integration.\n *\n * @remarks\n * Centralised here so the backend, worker, and discovery modules stay in sync.\n *\n * @internal\n */\n\nimport { readFileSync, existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { SetupError } from '../errors.js'\n\n/** Name reported to the 1Password SDK for integration tracking. */\nexport const INTEGRATION_NAME = 'vaultkeeper'\n\n/** npm package name of the optional 1Password SDK peer dependency. */\nexport const SDK_PACKAGE = '@1password/sdk'\n\n/** Installation instructions surfaced when the SDK is missing. */\nexport const SDK_INSTALL_URL = 'https://developer.1password.com/docs/sdks/'\n\n/**\n * Single source of truth for the \"SDK not installed\" error message, so the\n * backend, worker, and discovery modules report it identically.\n */\nexport const SDK_NOT_INSTALLED_MESSAGE = `1Password SDK (${SDK_PACKAGE}) is not installed. Install it to use the 1Password backend.`\n\n/**\n * How long the per-access worker waits for `createClient()` to resolve during\n * a presence-covered `store`/`delete` write before treating the fresh action\n * as timed out (`PresenceTimeoutError`).\n *\n * @remarks\n * Shared between the worker (which starts the timer) and the backend (which\n * reports this value on the resulting {@link PresenceTimeoutError}), so the\n * two never drift. Reads are unaffected — issue #211 only extends presence\n * coverage to writes; see {@link https://github.com/mike-north/vaultkeeper/issues/211}.\n */\nexport const PRESENCE_WRITE_TIMEOUT_MS = 30_000\n\n/**\n * Whether an error thrown by `import('@1password/sdk')` means the module could\n * not be resolved (i.e. the optional peer is not installed), as opposed to a\n * present-but-broken SDK (native binding failure, init throw, incompatible\n * Node). Only the former should be reported as \"not installed\" — the latter\n * must surface its real error so users don't reinstall something already there.\n *\n * @remarks\n * Node's loader rejects a missing import with `code` set directly on the error;\n * some loaders/wrappers instead attach the original via `error.cause`, so one\n * level of cause is inspected too.\n */\nexport function isModuleNotFoundError(error: unknown): boolean {\n const hasNotFoundCode = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object' || !('code' in value)) {\n return false\n }\n const { code } = value\n return code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND'\n }\n if (hasNotFoundCode(error)) {\n return true\n }\n if (error !== null && typeof error === 'object' && 'cause' in error) {\n return hasNotFoundCode(error.cause)\n }\n return false\n}\n\nlet cachedVersion: string | undefined\n\n/**\n * Version reported to the 1Password SDK.\n *\n * @remarks\n * Lazily derived from packages/vaultkeeper/package.json on first call so that\n * consumers who never use the 1Password backend pay no I/O cost at import time.\n * The result is memoized for subsequent calls.\n *\n * @internal\n */\nexport function getIntegrationVersion(): string {\n if (cachedVersion !== undefined) return cachedVersion\n\n const dir = dirname(fileURLToPath(import.meta.url))\n // Source: src/backend/ → ../../package.json\n // Bundled: dist/ → ../package.json\n const candidates = [resolve(dir, '..', '..', 'package.json'), resolve(dir, '..', 'package.json')]\n for (const candidate of candidates) {\n if (!existsSync(candidate)) continue\n const raw: unknown = JSON.parse(readFileSync(candidate, 'utf8'))\n if (\n raw !== null &&\n typeof raw === 'object' &&\n 'version' in raw &&\n typeof raw.version === 'string'\n ) {\n cachedVersion = raw.version\n return cachedVersion\n }\n }\n throw new SetupError(\n `Could not read version from vaultkeeper package.json. Tried paths: ${candidates.join(', ')}`,\n 'vaultkeeper package.json',\n )\n}\n","/**\n * 1Password SDK-based backend implementation.\n *\n * @remarks\n * Stores secrets in 1Password using the `@1password/sdk` package.\n * Each secret is stored as a \"Password\" item in the specified vault.\n *\n * Supports two access modes:\n * - `session`: A single SDK client is created on first use and cached for all operations.\n * - `per-access`: Every keyed operation (`retrieve()`, `store()`, `delete()`) spawns a child\n * process that creates a fresh SDK client (triggering biometric auth) for that single\n * operation. `exists()`/`list()` still use the cached session client — they are read-only\n * probes, not the presence-gated path.\n *\n * Presence-per-use follows directly from this: in `per-access` mode the instance forces a\n * fresh biometric for `read`, `store`, and `delete`, so {@link OnePasswordBackend.getCapabilities}\n * reports `presencePerUse: true` scoped to `presenceEnforcedOperations: ['read', 'store', 'delete']`.\n * `session` mode reports `false`.\n *\n * @see https://github.com/mike-north/vaultkeeper/issues/211\n */\n\nimport { spawn } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\nimport { dirname, join } from 'node:path'\nimport {\n SecretNotFoundError,\n PluginNotFoundError,\n BackendLockedError,\n BackendUnavailableError,\n AuthorizationDeniedError,\n ConfigValidationError,\n PresenceDeclinedError,\n PresenceTimeoutError,\n} from '../errors.js'\nimport type { ListableBackend, PresenceCapableBackend, BackendCapabilities } from './types.js'\nimport {\n TAG,\n findItemOverviewByTitle,\n findItemByTitle,\n extractPasswordField,\n storeSecretItem,\n deleteSecretItem,\n} from './one-password-item-ops.js'\n\n// ---- SDK type imports (runtime-dynamic, not static imports) ----\n// We import the SDK dynamically so that the backend degrades gracefully\n// when the native SDK library is not available on the host system.\n\ntype SdkModule = typeof import('@1password/sdk')\ntype Client = import('@1password/sdk').Client\n\nconst SESSION_TIMEOUT_MS = 30_000\nimport {\n INTEGRATION_NAME,\n SDK_INSTALL_URL,\n SDK_NOT_INSTALLED_MESSAGE,\n SDK_PACKAGE,\n PRESENCE_WRITE_TIMEOUT_MS,\n getIntegrationVersion,\n isModuleNotFoundError,\n} from './one-password-constants.js'\n\n/** Options accepted by `OnePasswordBackend`. */\nexport interface OnePasswordBackendOptions {\n /** Vault ID to store/retrieve secrets from. */\n vault: string\n /** Account name or UUID for desktop app authentication (mutually exclusive with serviceAccountToken). */\n account?: string\n /** Service account token for headless CI/CD use (mutually exclusive with account). */\n serviceAccountToken?: string\n /** Access mode: 'session' (default) or 'per-access'. */\n accessMode?: 'session' | 'per-access'\n /**\n * Override the session timeout in milliseconds.\n * Defaults to 30000ms. Exposed for testing only.\n * @internal\n */\n sessionTimeoutMs?: number\n}\n\n/** Worker response shape for successful retrieval. */\ninterface WorkerSuccess {\n value: string\n}\n\n/** Worker response shape for a retrieval failure. */\ninterface WorkerFailure {\n error: string\n code: string\n}\n\ntype WorkerResponse = WorkerSuccess | WorkerFailure\n\nfunction isWorkerSuccess(res: WorkerResponse): res is WorkerSuccess {\n return 'value' in res\n}\n\nfunction isWorkerResponse(value: unknown): value is WorkerResponse {\n if (value === null || typeof value !== 'object') return false\n if ('value' in value && typeof value.value === 'string') return true\n if (\n 'error' in value &&\n typeof value.error === 'string' &&\n 'code' in value &&\n typeof value.code === 'string'\n )\n return true\n return false\n}\n\n/** Worker response shape for a successful `store`/`delete` (no value to report). */\ninterface WorkerWriteSuccess {\n ok: true\n}\n\ntype WorkerWriteResponse = WorkerWriteSuccess | WorkerFailure\n\nfunction isWorkerWriteSuccess(res: WorkerWriteResponse): res is WorkerWriteSuccess {\n // Check the VALUE, not just key presence: a malformed/buggy worker response\n // like `{ ok: false, error, code }` passes isWorkerWriteResponse via its\n // failure branch and must never be classified as a successful write.\n const record: Record<string, unknown> = { ...res }\n return record.ok === true\n}\n\nfunction isWorkerWriteResponse(value: unknown): value is WorkerWriteResponse {\n if (value === null || typeof value !== 'object') return false\n if ('ok' in value && value.ok === true) return true\n if (\n 'error' in value &&\n typeof value.error === 'string' &&\n 'code' in value &&\n typeof value.code === 'string'\n )\n return true\n return false\n}\n\n/**\n * 1Password backend via the `@1password/sdk` package.\n *\n * @remarks\n * Requires the `@1password/sdk` package to be installed and, when using desktop\n * authentication, the 1Password desktop application to be running and unlocked.\n *\n * @internal\n */\nexport class OnePasswordBackend implements ListableBackend, PresenceCapableBackend {\n readonly type = '1password'\n readonly displayName = '1Password'\n\n private readonly vaultId: string\n private readonly account: string | undefined\n private readonly serviceAccountToken: string | undefined\n private readonly accessMode: 'session' | 'per-access'\n private readonly sessionTimeoutMs: number\n\n /** In-flight or resolved client promise — prevents duplicate createClient calls. */\n private clientPromise: Promise<Client> | undefined\n\n constructor(options: OnePasswordBackendOptions) {\n if (options.accessMode === 'per-access' && options.serviceAccountToken !== undefined) {\n throw new ConfigValidationError(\n 'per-access mode requires desktop biometric authentication and cannot be used with a service account token',\n 'options.accessMode',\n )\n }\n if (options.account !== undefined && options.serviceAccountToken !== undefined) {\n throw new ConfigValidationError(\n 'account and serviceAccountToken are mutually exclusive — provide one or the other, not both',\n 'options.serviceAccountToken',\n )\n }\n this.vaultId = options.vault\n this.sessionTimeoutMs = options.sessionTimeoutMs ?? SESSION_TIMEOUT_MS\n if (options.account !== undefined) {\n this.account = options.account\n }\n if (options.serviceAccountToken !== undefined) {\n this.serviceAccountToken = options.serviceAccountToken\n }\n this.accessMode = options.accessMode ?? 'session'\n }\n\n async isAvailable(): Promise<boolean> {\n const sdk = await this.tryLoadSdk()\n return sdk !== null\n }\n\n /**\n * Report this instance's capabilities.\n *\n * @remarks\n * `presencePerUse` is `true` only in `per-access` mode, where every keyed\n * operation (`retrieve()`, `store()`, `delete()`) spawns a fresh worker\n * process that creates a new SDK client and triggers a per-operation\n * biometric approval that cannot be satisfied from the cached session\n * client. In the default `session` mode a single client is cached for all\n * operations, so operations ride one earlier unlock — that mode reports\n * `false`.\n *\n * **Operation coverage:** the per-access biometric path gates `retrieve()`,\n * `store()`, and `delete()` — every keyed operation reachable from\n * `presenceEnforcedOperations`. `exists()`/`list()` are read-only probes,\n * not keyed operations the presence contract covers, so they continue to\n * use the cached session client. This reports\n * `presenceEnforcedOperations: ['read', 'store', 'delete']` (issue #211\n * closed the earlier `store`/`delete` gap — see\n * {@link https://github.com/mike-north/vaultkeeper/issues/211}).\n *\n * **Truth-basis / cached-OS-unlock caveat:** even for a covered operation\n * the fresh action is \"a fresh SDK client plus whatever the OS enforces at\n * that moment\" — a \"fresh process/SDK client\" is **not** the same as a\n * guaranteed fresh hardware action. A per-access call can still ride a\n * cached OS-level Touch ID / Windows Hello unlock if the OS does not\n * re-prompt. The strongest per-use hardware guarantee comes from a touch\n * device (YubiKey / gpg smartcard).\n */\n getCapabilities(): Promise<BackendCapabilities> {\n if (this.accessMode === 'per-access') {\n return Promise.resolve({\n presencePerUse: true,\n presenceEnforcedOperations: ['read', 'store', 'delete'],\n })\n }\n return Promise.resolve({ presencePerUse: false })\n }\n\n // ---- Session client management ----\n\n /**\n * Dynamically import the SDK. Returns `null` if the SDK is not installed or\n * the native library cannot be loaded. Used by {@link isAvailable}, which\n * only needs a yes/no answer; call {@link loadSdkOrThrow} on paths that must\n * report *why* the SDK could not be loaded.\n */\n private async tryLoadSdk(): Promise<SdkModule | null> {\n try {\n const sdk = await import('@1password/sdk')\n return sdk\n } catch {\n return null\n }\n }\n\n /**\n * Dynamically import the SDK, throwing a typed {@link PluginNotFoundError}\n * only when the module cannot be resolved (the optional peer is not\n * installed). A present-but-broken SDK (native binding failure, init throw,\n * incompatible Node) surfaces its real error instead of a misleading\n * \"not installed\" message.\n */\n private async loadSdkOrThrow(): Promise<SdkModule> {\n try {\n return await import('@1password/sdk')\n } catch (error: unknown) {\n if (isModuleNotFoundError(error)) {\n throw new PluginNotFoundError(SDK_NOT_INSTALLED_MESSAGE, SDK_PACKAGE, SDK_INSTALL_URL)\n }\n throw error\n }\n }\n\n /**\n * Acquire (or create) a cached SDK client.\n * Wraps `createClient` with a configurable timeout (default 30 s) to handle\n * the known beta SDK hang after session expiry.\n */\n private acquireClient(): Promise<Client> {\n this.clientPromise ??= this.createClientInternal().catch((err: unknown) => {\n // Reset the promise so future calls retry\n this.clientPromise = undefined\n throw err\n })\n return this.clientPromise\n }\n\n private async createClientInternal(): Promise<Client> {\n const sdk = await this.loadSdkOrThrow()\n\n const auth = this.buildAuth(sdk)\n\n let timerId: ReturnType<typeof setTimeout> | undefined\n const timeoutPromise = new Promise<never>((_resolve, reject) => {\n timerId = setTimeout(() => {\n reject(\n new BackendLockedError('1Password session timed out waiting for authentication', true),\n )\n }, this.sessionTimeoutMs)\n })\n\n try {\n const client = await Promise.race([\n sdk.createClient({\n auth,\n integrationName: INTEGRATION_NAME,\n integrationVersion: getIntegrationVersion(),\n }),\n timeoutPromise,\n ])\n return client\n } catch (err) {\n if (err instanceof BackendLockedError) {\n throw err\n }\n if (err instanceof sdk.DesktopSessionExpiredError) {\n throw new BackendLockedError('1Password session has expired. Please unlock the app.', true)\n }\n throw new AuthorizationDeniedError(`1Password authentication failed: ${String(err)}`)\n } finally {\n if (timerId !== undefined) {\n clearTimeout(timerId)\n }\n }\n }\n\n private buildAuth(sdk: SdkModule): string | import('@1password/sdk').DesktopAuth {\n if (this.serviceAccountToken !== undefined) {\n return this.serviceAccountToken\n }\n const accountName = this.account ?? ''\n return new sdk.DesktopAuth(accountName)\n }\n\n // ---- SecretBackend / ListableBackend implementation ----\n\n async store(id: string, secret: string): Promise<void> {\n if (this.accessMode === 'per-access') {\n return this.writeViaWorker('store', id, secret)\n }\n const { ItemCategory, ItemFieldType } = await this.requireSdk()\n const client = await this.acquireClient()\n await storeSecretItem(\n client,\n this.vaultId,\n id,\n secret,\n ItemCategory.Password,\n ItemFieldType.Concealed,\n )\n }\n\n async retrieve(id: string): Promise<string> {\n if (this.accessMode === 'per-access') {\n return this.retrieveViaWorker(id)\n }\n return this.retrieveViaSession(id)\n }\n\n private async retrieveViaSession(id: string): Promise<string> {\n const client = await this.acquireClient()\n const item = await findItemByTitle(client, this.vaultId, id)\n if (item === undefined) {\n throw new SecretNotFoundError(`Secret not found in 1Password: ${id}`)\n }\n const value = extractPasswordField(item)\n if (value === undefined) {\n throw new SecretNotFoundError(`Secret found in 1Password but missing password field: ${id}`)\n }\n return value\n }\n\n /**\n * Spawn the per-access worker script that triggers a fresh biometric prompt\n * for each retrieval, then returns the secret from its stdout.\n */\n private retrieveViaWorker(id: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const workerPath = join(dirname(fileURLToPath(import.meta.url)), 'one-password-worker.js')\n\n const accountArg = this.account ?? ''\n const child = spawn(process.execPath, [workerPath, accountArg, this.vaultId, id], {\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n\n const stdoutChunks: Buffer[] = []\n const stderrChunks: Buffer[] = []\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk)\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk)\n })\n\n child.on('close', (code, signal) => {\n const raw = Buffer.concat(stdoutChunks).toString('utf8').trim()\n\n // If worker produced no stdout, use exit code + stderr for diagnostics\n if (raw === '') {\n const stderr = Buffer.concat(stderrChunks).toString('utf8').trim()\n const exitDescription =\n typeof signal === 'string'\n ? `terminated by signal ${signal}`\n : `exit code ${String(code)}`\n const detail = stderr !== '' ? stderr : exitDescription\n reject(\n new BackendUnavailableError(\n `1Password per-access worker crashed for secret ${id}: ${detail}`,\n 'worker-crashed',\n ['1password'],\n ),\n )\n return\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n reject(new SecretNotFoundError(`Worker returned unparseable output for secret: ${id}`))\n return\n }\n if (!isWorkerResponse(parsed)) {\n reject(\n new SecretNotFoundError(`Worker returned unexpected response shape for secret: ${id}`),\n )\n return\n }\n if (isWorkerSuccess(parsed)) {\n resolve(parsed.value)\n } else {\n switch (parsed.code) {\n case 'PLUGIN_NOT_FOUND':\n reject(\n new PluginNotFoundError(SDK_NOT_INSTALLED_MESSAGE, SDK_PACKAGE, SDK_INSTALL_URL),\n )\n break\n case 'NOT_FOUND':\n reject(new SecretNotFoundError(`Secret not found in 1Password: ${id}`))\n break\n case 'AUTH_DENIED':\n reject(new AuthorizationDeniedError('1Password authentication was denied'))\n break\n case 'LOCKED':\n reject(new BackendLockedError('1Password is locked. Please unlock and retry.', true))\n break\n case 'INTERNAL':\n // A worker-internal failure (e.g. a present-but-broken SDK that\n // could not be loaded) is a backend problem, not a missing\n // secret — surface it as such with the worker's real detail so it\n // isn't misclassified as SecretNotFoundError.\n reject(\n new BackendUnavailableError(\n `1Password per-access worker failed for secret ${id}: ${parsed.error}`,\n 'worker-internal-error',\n ['1password'],\n ),\n )\n break\n default:\n reject(new SecretNotFoundError(`Worker failed for secret ${id}: ${parsed.error}`))\n }\n }\n })\n\n child.on('error', (err) => {\n reject(\n new BackendUnavailableError(\n `Failed to spawn 1Password per-access worker at ${workerPath}: ${String(err)}`,\n 'worker-spawn-failed',\n ['1password'],\n ),\n )\n })\n })\n }\n\n /**\n * Spawn the per-access worker script to perform a `store` or `delete`,\n * triggering a fresh biometric prompt for this single write (issue #211).\n *\n * @remarks\n * For `store`, `secret` is delivered to the worker over **stdin**, never\n * argv — it must never appear in a process listing, shell history, or log.\n * `delete` needs no payload, so no stdin is written and the worker's stdin\n * is left `'ignore'`d, mirroring the retrieve path's spawn options.\n */\n private writeViaWorker(op: 'store' | 'delete', id: string, secret?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const workerPath = join(dirname(fileURLToPath(import.meta.url)), 'one-password-worker.js')\n\n const accountArg = this.account ?? ''\n const needsStdin = secret !== undefined\n const child = spawn(process.execPath, [workerPath, accountArg, this.vaultId, id, op], {\n stdio: [needsStdin ? 'pipe' : 'ignore', 'pipe', 'pipe'],\n })\n\n if (needsStdin && child.stdin !== null) {\n // A worker that exits before draining stdin (e.g. a protocol\n // validation failure) makes this write raise EPIPE, which without a\n // handler becomes an unhandled 'error' event and crashes the parent.\n // The worker's own failure is already reported through the close\n // handler below, so the stream error itself is safe to swallow.\n child.stdin.on('error', () => {\n /* reported via the close handler */\n })\n child.stdin.write(secret, 'utf8')\n child.stdin.end()\n }\n\n const stdoutChunks: Buffer[] = []\n const stderrChunks: Buffer[] = []\n // The ternary in `stdio` above (rather than a fixed literal tuple) means\n // TS can't narrow `stdout`/`stderr` to non-null from `spawn`'s overloads\n // — both are always piped regardless, so optional chaining here mirrors\n // the same null-safety idiom `execCommandFull` already uses in `util/exec.ts`.\n child.stdout?.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk)\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk)\n })\n\n child.on('close', (code, signal) => {\n const raw = Buffer.concat(stdoutChunks).toString('utf8').trim()\n\n if (raw === '') {\n const stderr = Buffer.concat(stderrChunks).toString('utf8').trim()\n // A signal-terminated worker reports code null — name the signal\n // instead of an unhelpful 'exit code null'.\n const exitDescription =\n typeof signal === 'string'\n ? `terminated by signal ${signal}`\n : `exit code ${String(code)}`\n const detail = stderr !== '' ? stderr : exitDescription\n reject(\n new BackendUnavailableError(\n `1Password per-access worker crashed during ${op} of secret ${id}: ${detail}`,\n 'worker-crashed',\n ['1password'],\n ),\n )\n return\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n reject(\n new BackendUnavailableError(\n `Worker returned unparseable output during ${op} of secret ${id}`,\n 'worker-internal-error',\n ['1password'],\n ),\n )\n return\n }\n if (!isWorkerWriteResponse(parsed)) {\n reject(\n new BackendUnavailableError(\n `Worker returned unexpected response shape during ${op} of secret ${id}`,\n 'worker-internal-error',\n ['1password'],\n ),\n )\n return\n }\n if (isWorkerWriteSuccess(parsed)) {\n resolve()\n return\n }\n switch (parsed.code) {\n case 'PLUGIN_NOT_FOUND':\n reject(new PluginNotFoundError(SDK_NOT_INSTALLED_MESSAGE, SDK_PACKAGE, SDK_INSTALL_URL))\n break\n case 'NOT_FOUND':\n reject(new SecretNotFoundError(`Secret not found in 1Password: ${id}`))\n break\n case 'LOCKED':\n reject(new BackendLockedError('1Password is locked. Please unlock and retry.', true))\n break\n case 'PRESENCE_DECLINED':\n reject(\n new PresenceDeclinedError(\n `1Password ${op} presence action was declined for secret ${id}`,\n '1password',\n ),\n )\n break\n case 'PRESENCE_TIMEOUT':\n reject(\n new PresenceTimeoutError(\n `1Password ${op} presence action timed out for secret ${id}`,\n '1password',\n PRESENCE_WRITE_TIMEOUT_MS,\n ),\n )\n break\n case 'INTERNAL':\n reject(\n new BackendUnavailableError(\n `1Password per-access worker failed during ${op} of secret ${id}: ${parsed.error}`,\n 'worker-internal-error',\n ['1password'],\n ),\n )\n break\n default:\n reject(\n new BackendUnavailableError(\n `Worker failed during ${op} of secret ${id}: ${parsed.error}`,\n 'worker-internal-error',\n ['1password'],\n ),\n )\n }\n })\n\n child.on('error', (err) => {\n reject(\n new BackendUnavailableError(\n `Failed to spawn 1Password per-access worker at ${workerPath}: ${String(err)}`,\n 'worker-spawn-failed',\n ['1password'],\n ),\n )\n })\n })\n }\n\n async delete(id: string): Promise<void> {\n if (this.accessMode === 'per-access') {\n return this.writeViaWorker('delete', id)\n }\n const client = await this.acquireClient()\n const deleted = await deleteSecretItem(client, this.vaultId, id)\n if (!deleted) {\n throw new SecretNotFoundError(`Secret not found in 1Password: ${id}`)\n }\n }\n\n async exists(id: string): Promise<boolean> {\n const client = await this.acquireClient()\n const overview = await findItemOverviewByTitle(client, this.vaultId, id)\n return overview !== undefined\n }\n\n async list(): Promise<string[]> {\n const client = await this.acquireClient()\n const overviews = await client.items.list(this.vaultId)\n const ids: string[] = []\n for (const overview of overviews) {\n if (overview.tags.includes(TAG)) {\n ids.push(overview.title)\n }\n }\n return ids\n }\n\n // ---- Private helpers ----\n\n /**\n * Load SDK, throwing a typed {@link PluginNotFoundError} when it is not\n * installed and surfacing the real error when it is present but broken.\n */\n private requireSdk(): Promise<SdkModule> {\n return this.loadSdkOrThrow()\n }\n}\n","/**\n * YubiKey backend implementation.\n *\n * @remarks\n * Stores secrets protected by a YubiKey using the `ykman` CLI tool.\n * Secrets are encrypted using AES-256-GCM with a key derived from the\n * YubiKey's HMAC-SHA1 challenge-response (slot 2) via HKDF-SHA-256.\n *\n * Encrypted file format (version 1, all parts base64-encoded, colon-separated):\n * 1:<iv>:<authTag>:<ciphertext>\n *\n * The leading \"1:\" version prefix allows future format migrations and enables\n * detection of legacy CBC files (which lack this prefix).\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport * as crypto from 'node:crypto'\nimport { execCommandFull } from '../util/exec.js'\nimport {\n SecretNotFoundError,\n PluginNotFoundError,\n DeviceNotPresentError,\n DecryptionError,\n SetupError,\n ExecError,\n} from '../errors.js'\nimport type { ListableBackend, PresenceCapableBackend, BackendCapabilities } from './types.js'\n\nconst YKMAN_INSTALL_URL = 'https://developers.yubico.com/yubikey-manager/'\nconst STORAGE_DIR_NAME = path.join('.vaultkeeper', 'yubikey')\nconst METADATA_FILE = 'metadata.json'\nconst DEVICE_TIMEOUT_MS = 5000\n\n/** AES-256-GCM constants */\nconst GCM_IV_BYTES = 12\nconst GCM_KEY_BYTES = 32\nconst GCM_TAG_LENGTH_BITS = 128\n\n/** Version prefix written at the start of every encrypted file. */\nconst FORMAT_VERSION = '1'\n\ninterface YubikeyMetadata {\n entries: Record<string, string>\n}\n\n/**\n * Resolve the storage directory for a YubikeyBackend instance.\n *\n * When `configuredPath` is provided (from `BackendConfig.path`), encrypted\n * secrets are stored directly under that directory. Otherwise the default\n * `$HOME/.vaultkeeper/yubikey` location is used.\n */\nfunction resolveStorageDir(configuredPath?: string): string {\n // Config validation (see validateConfig) rejects empty/whitespace-only\n // paths, so any defined value here is guaranteed non-blank.\n if (configuredPath !== undefined) {\n return configuredPath\n }\n return path.join(os.homedir(), STORAGE_DIR_NAME)\n}\n\nfunction getEntryPath(storageDir: string, id: string): string {\n const safeId = Buffer.from(id, 'utf8').toString('hex')\n return path.join(storageDir, `${safeId}.enc`)\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (value === null || typeof value !== 'object') {\n return false\n }\n return Object.values(value).every((v) => typeof v === 'string')\n}\n\nasync function loadMetadata(storageDir: string): Promise<YubikeyMetadata> {\n const metaPath = path.join(storageDir, METADATA_FILE)\n try {\n const raw = await fs.readFile(metaPath, 'utf8')\n const parsed: unknown = JSON.parse(raw)\n if (\n parsed !== null &&\n typeof parsed === 'object' &&\n 'entries' in parsed &&\n isStringRecord(parsed.entries)\n ) {\n return { entries: parsed.entries }\n }\n return { entries: {} }\n } catch {\n return { entries: {} }\n }\n}\n\nasync function saveMetadata(storageDir: string, metadata: YubikeyMetadata): Promise<void> {\n const metaPath = path.join(storageDir, METADATA_FILE)\n await fs.writeFile(metaPath, JSON.stringify(metadata, null, 2), { mode: 0o600 })\n}\n\n/** Expected byte length of a YubiKey HMAC-SHA1 response (20 bytes = 40 hex chars). */\nconst HMAC_RESPONSE_HEX_LENGTH = 40\n\n/** Regex for a valid HMAC-SHA1 hex response: exactly 40 lowercase or uppercase hex digits. */\nconst HMAC_RESPONSE_RE = /^[0-9a-fA-F]{40}$/\n\n/**\n * Derive a 256-bit AES key from the YubiKey HMAC-SHA1 response using HKDF-SHA-256.\n *\n * The HMAC-SHA1 response is 20 bytes — too short and too biased to use\n * directly as an AES-256 key. HKDF expands it to exactly 32 bytes while\n * binding the key to the secret `id` via the `info` field.\n *\n * Throws if `hmacResponse` is not exactly 40 hex characters (20 bytes), which\n * would indicate a malformed or truncated ykman response.\n */\nfunction deriveKey(hmacResponse: string, id: string): Buffer {\n const trimmed = hmacResponse.trim()\n if (!HMAC_RESPONSE_RE.test(trimmed)) {\n throw new SetupError(\n `Invalid YubiKey HMAC response: expected exactly ${String(HMAC_RESPONSE_HEX_LENGTH)} hex characters (20 bytes), got ${String(trimmed.length)} characters`,\n 'ykman',\n )\n }\n // The ykman response is a hex string; convert to raw bytes as the IKM.\n const ikm = Buffer.from(trimmed, 'hex')\n const info = Buffer.from(`vaultkeeper-yubikey:${id}`, 'utf8')\n // Node's hkdfSync returns an ArrayBuffer; wrap without copying.\n const keyMaterial = crypto.hkdfSync('sha256', ikm, Buffer.alloc(0), info, GCM_KEY_BYTES)\n return Buffer.from(keyMaterial)\n}\n\n/**\n * Encrypt `plaintext` with AES-256-GCM using `key`.\n * Returns a versioned, colon-separated string: `1:<iv>:<authTag>:<ciphertext>`\n * (all binary fields base64-encoded).\n *\n * The key and all intermediate buffers are zeroed in the finally block,\n * guaranteeing cleanup even if `createCipheriv` or `cipher.final()` throws.\n */\nfunction encryptGcm(key: Buffer, plaintext: string): string {\n const iv = crypto.randomBytes(GCM_IV_BYTES)\n let encrypted: Buffer | undefined\n let authTag: Buffer | undefined\n try {\n const cipher = crypto.createCipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH_BITS / 8,\n })\n encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()])\n authTag = cipher.getAuthTag()\n\n return [\n FORMAT_VERSION,\n iv.toString('base64'),\n authTag.toString('base64'),\n encrypted.toString('base64'),\n ].join(':')\n } finally {\n // Zero all secret material regardless of success or failure.\n key.fill(0)\n iv.fill(0)\n encrypted?.fill(0)\n authTag?.fill(0)\n }\n}\n\n/**\n * Decrypt a versioned GCM blob produced by `encryptGcm`.\n *\n * Version detection distinguishes three cases:\n * - First segment is a number matching `FORMAT_VERSION` → current format, proceed.\n * - First segment is a different number → unsupported future version, throw a\n * clear \"unsupported version N\" error.\n * - First segment is not a number at all → legacy/corrupt format (e.g. an\n * AES-256-CBC file written before this implementation), throw a migration error.\n *\n * The key buffer is always zeroed in a finally block, guaranteeing cleanup even\n * if `createDecipheriv` or `setAuthTag` throws before the decrypt attempt.\n *\n * @param path - The path of the encrypted entry, for attribution on a thrown\n * {@link DecryptionError}.\n */\nfunction decryptGcm(key: Buffer, encoded: string, path: string): string {\n const parts = encoded.split(':')\n const versionSegment = parts[0] ?? ''\n\n // Determine whether the first segment is a numeric version prefix at all.\n const parsedVersion = parseInt(versionSegment, 10)\n const isNumericVersion = String(parsedVersion) === versionSegment && !Number.isNaN(parsedVersion)\n\n if (!isNumericVersion) {\n // No recognisable version prefix — treat as legacy CBC or corrupt file.\n key.fill(0)\n throw new DecryptionError(\n 'Encrypted file uses a legacy format (AES-256-CBC). ' +\n 'Delete the secret and re-store it to migrate to AES-256-GCM.',\n path,\n )\n }\n\n if (versionSegment !== FORMAT_VERSION) {\n // A future format version this binary does not know how to decode.\n key.fill(0)\n throw new DecryptionError(\n `Unsupported encrypted file version: ${versionSegment}. ` +\n `This vaultkeeper build only supports version ${FORMAT_VERSION}. ` +\n 'Upgrade vaultkeeper to read this secret.',\n path,\n )\n }\n\n if (parts.length !== 4) {\n key.fill(0)\n throw new DecryptionError(\n `Invalid encrypted file format: expected ${FORMAT_VERSION}:iv:authTag:ciphertext`,\n path,\n )\n }\n\n const [_version, ivB64, authTagB64, ciphertextB64] = parts\n if (ivB64 === undefined || authTagB64 === undefined || ciphertextB64 === undefined) {\n key.fill(0)\n throw new DecryptionError('Invalid encrypted file format: missing part', path)\n }\n\n let decrypted: Buffer | undefined\n try {\n const iv = Buffer.from(ivB64, 'base64')\n const authTag = Buffer.from(authTagB64, 'base64')\n const ciphertext = Buffer.from(ciphertextB64, 'base64')\n\n // createDecipheriv/setAuthTag sit inside this try too: the iv and\n // authTag lengths come from the on-disk file, so a truncated/corrupt\n // entry can throw a native RangeError/TypeError before decryption even\n // starts — every native crypto failure must wrap as DecryptionError.\n try {\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv, {\n authTagLength: GCM_TAG_LENGTH_BITS / 8,\n })\n decipher.setAuthTag(authTag)\n decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])\n } catch (err) {\n throw new DecryptionError(\n `GCM authentication failed — ciphertext may be tampered or corrupt: ${err instanceof Error ? err.message : String(err)}`,\n path,\n )\n }\n\n const plaintext = decrypted.toString('utf8')\n return plaintext\n } finally {\n // Zero all secret material regardless of success or failure.\n key.fill(0)\n decrypted?.fill(0)\n }\n}\n\n/**\n * YubiKey backend via `ykman` CLI.\n *\n * @remarks\n * Requires ykman to be installed and a YubiKey to be connected.\n * Secrets are stored in files encrypted using AES-256-GCM. The encryption\n * key is derived from the YubiKey's HMAC-SHA1 challenge-response (slot 2)\n * via HKDF-SHA-256, binding each secret to its `id`.\n *\n * @internal\n */\nexport class YubikeyBackend implements ListableBackend, PresenceCapableBackend {\n readonly type = 'yubikey'\n readonly displayName = 'YubiKey'\n\n readonly #storageDir: string\n\n /**\n * Whether the configured challenge-response slot enforces a touch for every\n * operation. When `true`, each `store`/`retrieve`/`delete` requires a fresh\n * physical tap (see {@link YubikeyBackend.getCapabilities}). Sourced from\n * configuration, not hardcoded by type — a slot without a touch policy\n * reports `false`.\n */\n readonly #requireTouch: boolean\n\n /**\n * @param storageDir - Directory in which encrypted secrets and metadata are\n * stored. Sourced from `BackendConfig.path`. Defaults to\n * `$HOME/.vaultkeeper/yubikey`.\n * @param requireTouch - Whether the configured challenge-response slot\n * enforces a touch-per-operation policy. Defaults to `false`. Sourced from\n * the operator's configuration and must match the physical slot's policy\n * (verify with `ykman otp info`); it governs the value reported by\n * {@link YubikeyBackend.getCapabilities}.\n */\n constructor(storageDir?: string, requireTouch = false) {\n this.#storageDir = resolveStorageDir(storageDir)\n this.#requireTouch = requireTouch\n }\n\n /**\n * Report this instance's capabilities.\n *\n * @remarks\n * `presencePerUse` is `true` only when the configured slot enforces a\n * touch-per-operation policy (`requireTouch`), in which case every\n * challenge-response — and therefore every `store`/`retrieve`/`delete` — forces\n * a fresh physical tap that cannot be satisfied from any cached state. A slot\n * without a touch policy reports `false`; the answer is never derived from the\n * backend `type` alone. Truth-basis: the reported value comes from the\n * operator-declared `touchPolicy` configuration; confirm it matches the\n * physical slot with `ykman otp info` (a manual verification).\n */\n getCapabilities(): Promise<BackendCapabilities> {\n return Promise.resolve({ presencePerUse: this.#requireTouch })\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const result = await execCommandFull('ykman', ['--version'])\n if (result.exitCode !== 0) {\n return false\n }\n // Also verify a YubiKey is connected\n const listResult = await execCommandFull('ykman', ['list'])\n return listResult.exitCode === 0 && listResult.stdout.trim() !== ''\n } catch {\n return false\n }\n }\n\n private async requireDevice(): Promise<void> {\n const available = await this.isAvailable()\n if (!available) {\n const hasYkman = await execCommandFull('ykman', ['--version']).then(\n (r) => r.exitCode === 0,\n () => false,\n )\n if (!hasYkman) {\n throw new PluginNotFoundError('ykman is not installed', 'ykman', YKMAN_INSTALL_URL)\n }\n throw new DeviceNotPresentError('No YubiKey device detected', DEVICE_TIMEOUT_MS)\n }\n }\n\n /**\n * Perform the YubiKey HMAC-SHA1 challenge-response for `id` and return the\n * raw hex response string. Throws on device failure.\n */\n private async challengeResponse(id: string): Promise<string> {\n const challenge = Buffer.from(`vaultkeeper:${id}`, 'utf8').toString('hex')\n const responseResult = await execCommandFull('ykman', ['otp', 'calculate', '2', challenge])\n if (responseResult.exitCode !== 0) {\n throw new ExecError(`YubiKey challenge-response failed: ${responseResult.stderr}`, 'ykman')\n }\n return responseResult.stdout.trim()\n }\n\n async store(id: string, secret: string): Promise<void> {\n await this.requireDevice()\n\n const storageDir = this.#storageDir\n await fs.mkdir(storageDir, { recursive: true, mode: 0o700 })\n\n const hmacResponse = await this.challengeResponse(id)\n const key = deriveKey(hmacResponse, id)\n const encrypted = encryptGcm(key, secret)\n\n const entryPath = getEntryPath(storageDir, id)\n await fs.writeFile(entryPath, encrypted, { mode: 0o600 })\n\n const metadata = await loadMetadata(storageDir)\n metadata.entries[id] = entryPath\n await saveMetadata(storageDir, metadata)\n }\n\n async retrieve(id: string): Promise<string> {\n await this.requireDevice()\n\n const storageDir = this.#storageDir\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n } catch {\n throw new SecretNotFoundError(`Secret not found in YubiKey store: ${id}`)\n }\n\n const encoded = await fs.readFile(entryPath, 'utf8')\n const hmacResponse = await this.challengeResponse(id)\n const key = deriveKey(hmacResponse, id)\n\n return decryptGcm(key, encoded, entryPath)\n }\n\n async delete(id: string): Promise<void> {\n await this.requireDevice()\n\n const storageDir = this.#storageDir\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.unlink(entryPath)\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {\n throw new SecretNotFoundError(`Secret not found in YubiKey store: ${id}`)\n }\n throw err\n }\n\n const metadata = await loadMetadata(storageDir)\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete metadata.entries[id]\n await saveMetadata(storageDir, metadata)\n }\n\n async exists(id: string): Promise<boolean> {\n const storageDir = this.#storageDir\n const entryPath = getEntryPath(storageDir, id)\n\n try {\n await fs.access(entryPath)\n return true\n } catch {\n return false\n }\n }\n\n async list(): Promise<string[]> {\n const storageDir = this.#storageDir\n const metadata = await loadMetadata(storageDir)\n return Object.keys(metadata.entries)\n }\n}\n","/**\n * Side-effect module that registers all built-in backends with the {@link BackendRegistry}.\n *\n * @remarks\n * Imported from the package entry point (`index.ts`) so that built-in backends\n * are available immediately after `import 'vaultkeeper'`.\n *\n * @see https://github.com/mike-north/vaultkeeper/issues/21\n */\n\nimport type { BackendConfig } from '../types.js'\nimport { BackendRegistry } from './registry.js'\nimport { FileBackend } from './file-backend.js'\nimport { KeychainBackend } from './keychain-backend.js'\nimport { DpapiBackend } from './dpapi-backend.js'\nimport { SecretToolBackend } from './secret-tool-backend.js'\nimport { OnePasswordBackend } from './one-password-backend.js'\nimport type { OnePasswordBackendOptions } from './one-password-backend.js'\nimport { YubikeyBackend } from './yubikey-backend.js'\n\n/**\n * Register all built-in backends with the {@link BackendRegistry}.\n *\n * @remarks\n * Called automatically as a module side-effect. Also exported so that tests\n * can re-register builtins after calling `BackendRegistry.clearBackends()`.\n *\n * @internal\n */\nexport function registerBuiltinBackends(): void {\n BackendRegistry.register(\n 'file',\n (config?: BackendConfig, configDir?: string) => new FileBackend(config?.path, configDir),\n )\n BackendRegistry.register('keychain', () => new KeychainBackend())\n BackendRegistry.register('dpapi', (config?: BackendConfig) => new DpapiBackend(config?.path))\n BackendRegistry.register('secret-tool', () => new SecretToolBackend())\n BackendRegistry.register('1password', (config?: BackendConfig) => {\n const opts = config?.options\n const vaultId = opts?.vault ?? ''\n const opOptions: OnePasswordBackendOptions = {\n vault: vaultId,\n // 'session' is the safer default — 'per-access' re-prompts on every read.\n accessMode: opts?.accessMode === 'per-access' ? 'per-access' : 'session',\n }\n const account = opts?.account\n if (account !== undefined) {\n opOptions.account = account\n }\n const serviceAccountToken = opts?.serviceAccountToken\n if (serviceAccountToken !== undefined) {\n opOptions.serviceAccountToken = serviceAccountToken\n }\n return new OnePasswordBackend(opOptions)\n })\n BackendRegistry.register(\n 'yubikey',\n (config?: BackendConfig) =>\n // `touchPolicy: 'required'` in the backend options declares that the\n // configured challenge-response slot enforces a touch per operation, which\n // is what makes the instance presence-per-use capable (see\n // YubikeyBackend.getCapabilities). Any other value (or absent) reports\n // false — presence is never assumed from the backend type alone.\n new YubikeyBackend(config?.path, config?.options?.touchPolicy === 'required'),\n )\n}\n\nregisterBuiltinBackends()\n","/**\n * Backend abstraction layer types for vaultkeeper.\n */\n\n// Import Buffer from node:buffer (rather than relying on the ambient global) so\n// the API Extractor rollup sees a single Buffer symbol shared with types.ts —\n// otherwise it disambiguates them as `Buffer` / `Buffer$1` in the generated\n// .d.ts and docs.\nimport type { Buffer } from 'node:buffer'\n\n/**\n * Factory function for creating a SecretBackend instance.\n *\n * @remarks\n * Factories may optionally accept a {@link BackendConfig} to configure the\n * backend from the user's vaultkeeper config file, and the resolved config\n * directory (the same directory config and key material are read from) so\n * file-based backends can default their storage under it. Factories that do\n * not need either can ignore the parameters.\n *\n * @public\n */\n// Inline import() avoids a circular dependency: ../types.js imports from this barrel.\nexport type BackendFactory = (\n config?: import('../types.js').BackendConfig,\n configDir?: string,\n) => SecretBackend\n\n/**\n * Abstraction interface for all secret storage backends.\n *\n * @remarks\n * Each backend implementation must handle its own availability check and\n * secret lifecycle (store, retrieve, delete, exists).\n *\n * @public\n */\nexport interface SecretBackend {\n /** Unique type identifier for this backend. */\n readonly type: string\n\n /** Human-readable display name for this backend. */\n readonly displayName: string\n\n /**\n * Check whether this backend is available on the current system.\n * @returns true if the backend can be used, false otherwise\n */\n isAvailable(): Promise<boolean>\n\n /**\n * Store a secret under the given id.\n * @param id - Unique identifier for the secret\n * @param secret - The secret value to store\n */\n store(id: string, secret: string): Promise<void>\n\n /**\n * Retrieve a secret by id.\n * @param id - Unique identifier for the secret\n * @returns The stored secret value\n * @throws SecretNotFoundError if the secret does not exist\n */\n retrieve(id: string): Promise<string>\n\n /**\n * Delete a secret by id.\n * @param id - Unique identifier for the secret\n * @throws SecretNotFoundError if the secret does not exist\n */\n delete(id: string): Promise<void>\n\n /**\n * Check whether a secret exists for the given id.\n * @param id - Unique identifier for the secret\n * @returns true if the secret exists, false otherwise\n */\n exists(id: string): Promise<boolean>\n}\n\n/**\n * Backend that can enumerate stored secret IDs.\n * @public\n */\nexport interface ListableBackend extends SecretBackend {\n /**\n * List IDs of all secrets managed by this backend.\n * @returns Array of secret identifiers\n */\n list(): Promise<string[]>\n}\n\n/**\n * Type guard for backends that support listing.\n * @public\n */\nexport function isListableBackend(backend: SecretBackend): backend is ListableBackend {\n return 'list' in backend && typeof backend.list === 'function'\n}\n\n/**\n * A keyed backend operation that a presence-per-use requirement can gate.\n *\n * @remarks\n * Used by {@link BackendCapabilities.presenceEnforcedOperations} to express that\n * an instance forces a fresh per-use action for only *some* operations. `'read'`\n * covers the secret read behind `setup`/`exec`; `'store'`, `'delete'`, and\n * `'sign'` are the write, removal, and signing paths.\n *\n * @public\n */\nexport type PresenceOperation = 'read' | 'store' | 'delete' | 'sign'\n\n/**\n * The set of security capabilities a configured backend instance advertises.\n *\n * @remarks\n * Capabilities describe what a **specific configured instance** guarantees, not\n * what its backend *type* is generally able to do. Two instances of the same\n * backend type can report different capabilities depending on their\n * configuration (e.g. a YubiKey slot with a touch policy vs. one without, or\n * 1Password in `per-access` vs. `session` mode). Never derive a capability from\n * the backend's `type` alone.\n *\n * The shape is intentionally open to extension: new capability flags may be\n * added over time, so consumers should read only the fields they understand and\n * treat a missing/unknown field as absent.\n *\n * @public\n */\nexport interface BackendCapabilities {\n /**\n * `true` when this configured instance can force a distinct, fresh physical\n * human action (e.g. a YubiKey touch, a gpg-smartcard tap, or a 1Password\n * per-use biometric approval) — a deliberate action taken *for this operation,\n * right now*, not merely \"a vault was unlocked at some point.\"\n *\n * The guarantee is **operation-scoped**, not blanket: when `presencePerUse` is\n * `true`, that fresh action is available and **non-bypassably enforced** for\n * exactly the operations listed in\n * {@link BackendCapabilities.presenceEnforcedOperations} (all keyed operations\n * when that field is omitted). For a covered operation, a\n * {@link https://github.com/mike-north/vaultkeeper/issues/122 | `--require-presence-per-use`}\n * request drives a fresh action that cannot be satisfied from a cached or\n * session-unlocked state. For an operation **outside** that set, the request is\n * **refused** with a `NotCapableError` — it is never silently satisfied from a\n * cached unlock. A backend that only caches an unlock, or that is\n * encryption-only with no per-use action, reports `false`.\n *\n * Backends that do not implement {@link PresenceCapableBackend} are treated as\n * `false` by {@link getBackendCapabilities} — an unknown backend never\n * silently claims presence.\n */\n readonly presencePerUse: boolean\n\n /**\n * The keyed operations for which this instance actually forces a fresh per-use\n * human action. When **omitted**, a `presencePerUse: true` instance is taken\n * to force presence for **all** keyed operations — the default for a touch\n * device (e.g. a YubiKey whose challenge-response touch fires on every\n * `store`/`retrieve`/`delete`).\n *\n * A backend that can force presence for only *some* operations must list\n * exactly those, so a `--require-presence-per-use` request for an **uncovered**\n * operation fails closed with a `NotCapableError` rather than silently passing\n * without a fresh action. For example, 1Password `per-access` forces a fresh\n * biometric on reads (`setup`/`exec`) but routes `store`/`delete` through the\n * cached session client, so it reports `['read']` — a flagged `store`/`delete`\n * is then correctly refused.\n *\n * Ignored when {@link BackendCapabilities.presencePerUse} is `false`.\n */\n readonly presenceEnforcedOperations?: readonly PresenceOperation[]\n}\n\n/**\n * Backend that can report its security {@link BackendCapabilities} for its\n * configured instance.\n *\n * @remarks\n * This is an optional extension interface, mirroring {@link ListableBackend} and\n * {@link SigningBackend}: it is **not** a required member of\n * {@link SecretBackend}. Prefer {@link getBackendCapabilities} over calling\n * {@link PresenceCapableBackend.getCapabilities} directly, so a backend that\n * does not implement the interface safely defaults to no capabilities rather\n * than being assumed to have them.\n *\n * {@link PresenceCapableBackend.getCapabilities} is asynchronous and describes\n * the **current configured/live state** of the instance — it must reflect\n * configuration (or a live device/session probe) rather than a hardcoded\n * per-type answer, and must not itself trigger a human-presence prompt.\n *\n * @public\n */\nexport interface PresenceCapableBackend extends SecretBackend {\n /**\n * Report the capabilities of this configured instance.\n * @returns The instance's {@link BackendCapabilities}.\n */\n getCapabilities(): Promise<BackendCapabilities>\n}\n\n/**\n * Type guard for backends that implement the capability-reporting contract.\n * @public\n */\nexport function isPresenceCapableBackend(\n backend: SecretBackend,\n): backend is PresenceCapableBackend {\n return 'getCapabilities' in backend && typeof backend.getCapabilities === 'function'\n}\n\n/**\n * Resolve a backend's {@link BackendCapabilities}, defaulting safely for\n * backends that do not implement {@link PresenceCapableBackend}.\n *\n * @remarks\n * A backend without the capability interface reports `{ presencePerUse: false }`\n * — an unknown backend never silently claims a security guarantee it cannot\n * prove. This is the only supported way to query capabilities; callers must not\n * assume a capability from a backend's `type`.\n *\n * @param backend - The backend instance to query.\n * @returns The instance's capabilities, or the safe default for a backend that\n * does not implement {@link PresenceCapableBackend}.\n * @public\n */\nexport async function getBackendCapabilities(backend: SecretBackend): Promise<BackendCapabilities> {\n if (isPresenceCapableBackend(backend)) {\n return backend.getCapabilities()\n }\n return { presencePerUse: false }\n}\n\n/**\n * Backend that can enroll and use signing keys entirely on its own side.\n *\n * @remarks\n * Signing keys are a distinct resource from secrets: a private key must never\n * flow through {@link SecretBackend.store}/{@link SecretBackend.retrieve} or a\n * capability token's claims. A signing backend generates the keypair, exposes\n * only the public half, and performs the signature itself — the private key\n * never leaves the backend. This is what keeps a key out of any JWE claims\n * token and lets a presence-per-use backend enforce its guarantee for signing.\n *\n * Implementations must keep signing keys in a namespace that cannot collide\n * with or be read as ordinary secrets.\n *\n * @public\n */\nexport interface SigningBackend extends SecretBackend {\n /**\n * Enroll a new signing keypair under `id`.\n * @param id - Namespaced signing-key identifier.\n * @param algorithm - The JOSE algorithm to generate a key for.\n * @throws If a signing key already exists under `id`, or `algorithm` is not\n * supported by this backend.\n */\n generateSigningKey(id: string, algorithm: import('../types.js').SigningAlgorithm): Promise<void>\n\n /**\n * Return the public half of the signing key stored under `id`.\n * @param id - Namespaced signing-key identifier.\n * @throws A `SigningKeyNotFoundError` if no signing key exists under `id`.\n */\n getPublicKey(id: string): Promise<import('../types.js').SigningPublicKey>\n\n /**\n * Sign `data` with the private key stored under `id`, returning the raw\n * signature bytes. The private key never leaves the backend.\n * @param id - Namespaced signing-key identifier.\n * @param data - The exact bytes to sign (e.g. a JWS signing input).\n * @throws A `SigningKeyNotFoundError` if no signing key exists under `id`.\n */\n signWithKey(id: string, data: Buffer): Promise<Buffer>\n}\n\n/**\n * Type guard for backends that implement the signing contract.\n * @public\n */\nexport function isSigningBackend(backend: SecretBackend): backend is SigningBackend {\n return (\n 'generateSigningKey' in backend &&\n typeof backend.generateSigningKey === 'function' &&\n 'getPublicKey' in backend &&\n typeof backend.getPublicKey === 'function' &&\n 'signWithKey' in backend &&\n typeof backend.signWithKey === 'function'\n )\n}\n","/**\n * Executable hashing utilities.\n */\n\nimport * as crypto from 'node:crypto'\nimport * as fs from 'node:fs'\nimport { FilesystemError } from '../errors.js'\n\n/**\n * Compute the SHA-256 digest of the file at `filePath`.\n *\n * @param filePath - Absolute or relative path to the binary to hash.\n * @returns Hex-encoded SHA-256 digest string.\n * @throws {@link FilesystemError} If the file does not exist or cannot be read.\n * @internal\n */\nexport function hashExecutable(filePath: string): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const hash = crypto.createHash('sha256')\n const stream = fs.createReadStream(filePath)\n\n stream.on('data', (chunk: Buffer | string) => {\n hash.update(chunk)\n })\n\n stream.on('end', () => {\n resolve(hash.digest('hex'))\n })\n\n stream.on('error', (err: Error) => {\n reject(\n new FilesystemError(\n `Cannot read executable at ${filePath}: ${err.message}`,\n filePath,\n 'read',\n err,\n ),\n )\n })\n })\n}\n","/**\n * Trust manifest management — load, save, and query approved executable hashes.\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport { FilesystemError, toFilesystemError } from '../errors.js'\nimport type { TrustManifest, TrustManifestEntry } from './types.js'\n\nconst MANIFEST_FILENAME = 'trust-manifest.json'\n\n/** Raw shape persisted to disk (plain object, not a Map). */\ninterface RawManifest {\n version: number\n entries: Record<string, TrustManifestEntry>\n}\n\n/**\n * Type guard that checks `value` is an object with a `version: number` and\n * `entries` object property, matching {@link RawManifest}.\n *\n * We avoid type assertions by narrowing through the `in` operator and\n * `typeof` checks. The discriminated union `unknown → object` chain lets\n * TypeScript track narrowness without any `as` casts.\n */\nfunction isRawManifest(value: unknown): value is RawManifest {\n if (typeof value !== 'object' || value === null) return false\n if (!('version' in value) || typeof value.version !== 'number') return false\n if (!('entries' in value) || typeof value.entries !== 'object' || value.entries === null)\n return false\n return true\n}\n\n/**\n * Type guard for a single {@link TrustManifestEntry}.\n */\nfunction isTrustManifestEntry(value: unknown): value is TrustManifestEntry {\n if (typeof value !== 'object' || value === null) return false\n if (!('hashes' in value) || !Array.isArray(value.hashes)) return false\n if (!('trustTier' in value)) return false\n const { trustTier } = value\n if (trustTier !== 1 && trustTier !== 2 && trustTier !== 3) return false\n return true\n}\n\n/**\n * Load the trust manifest from `configDir`.\n * Returns an empty `Map` if the manifest file does not yet exist.\n * @throws {@link FilesystemError} If the file exists but cannot be read, or its\n * contents are not valid JSON.\n * @internal\n */\nexport async function loadManifest(configDir: string): Promise<TrustManifest> {\n const manifestPath = path.join(configDir, MANIFEST_FILENAME)\n let rawText: string\n try {\n rawText = await fs.readFile(manifestPath, 'utf8')\n } catch (err) {\n if (typeof err === 'object' && err !== null && 'code' in err && err.code === 'ENOENT') {\n return new Map()\n }\n const detail = err instanceof Error ? err.message : String(err)\n throw new FilesystemError(\n `Cannot read trust manifest at ${manifestPath}: ${detail}`,\n manifestPath,\n 'read',\n err,\n )\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(rawText)\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err)\n throw new FilesystemError(\n `Trust manifest at ${manifestPath} is not valid JSON: ${detail}`,\n manifestPath,\n 'read',\n err,\n )\n }\n\n if (!isRawManifest(parsed)) {\n return new Map()\n }\n\n const manifest: TrustManifest = new Map()\n for (const [namespace, entry] of Object.entries(parsed.entries)) {\n if (isTrustManifestEntry(entry)) {\n manifest.set(namespace, { hashes: [...entry.hashes], trustTier: entry.trustTier })\n }\n }\n return manifest\n}\n\n/**\n * Persist `manifest` to `configDir`, creating the directory if necessary.\n * @throws {@link FilesystemError} If the directory cannot be created or the\n * manifest file cannot be written.\n * @internal\n */\nexport async function saveManifest(configDir: string, manifest: TrustManifest): Promise<void> {\n const manifestPath = path.join(configDir, MANIFEST_FILENAME)\n // Split try/catches so each failure blames the path and operation that\n // actually failed: a shared catch would report a config-dir mkdir EACCES\n // as a failed manifest *write* at manifestPath (issue #228 audit).\n try {\n await fs.mkdir(configDir, { recursive: true })\n } catch (err) {\n throw toFilesystemError(err, 'trust-manifest directory', configDir, 'create')\n }\n const entries: Record<string, TrustManifestEntry> = {}\n for (const [namespace, entry] of manifest) {\n entries[namespace] = entry\n }\n const raw: RawManifest = { version: 1, entries }\n try {\n await fs.writeFile(manifestPath, JSON.stringify(raw, null, 2), 'utf8')\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err)\n throw new FilesystemError(\n `Cannot write trust manifest at ${manifestPath}: ${detail}`,\n manifestPath,\n 'write',\n err,\n )\n }\n}\n\n/**\n * Return a new manifest that includes `hash` under `namespace`.\n * If the namespace does not yet exist it is created with tier 3 (Unverified).\n * The trust tier of an existing entry is not changed.\n * @internal\n */\nexport function addTrustedHash(\n manifest: TrustManifest,\n namespace: string,\n hash: string,\n): TrustManifest {\n const next = new Map(manifest)\n const existing = next.get(namespace)\n if (existing === undefined) {\n next.set(namespace, { hashes: [hash], trustTier: 3 })\n } else if (!existing.hashes.includes(hash)) {\n next.set(namespace, { hashes: [...existing.hashes, hash], trustTier: existing.trustTier })\n }\n return next\n}\n\n/**\n * Return `true` if `hash` is in the approved list for `namespace`.\n * @internal\n */\nexport function isTrusted(manifest: TrustManifest, namespace: string, hash: string): boolean {\n const entry = manifest.get(namespace)\n if (entry === undefined) return false\n return entry.hashes.includes(hash)\n}\n","/**\n * Trust classification for executables.\n *\n * Tier 1 — Sigstore: cryptographic provenance verified via Sigstore (lazy import).\n * Tier 2 — Registry: hash found in the approved trust manifest.\n * Tier 3 — Unverified: default fallback when no stronger evidence is available.\n *\n * TOFU (Trust On First Use): on the first encounter with an executable the hash\n * is recorded. If the hash changes on a subsequent call a `tofuConflict` is\n * signalled so the caller can prompt for re-approval.\n *\n * Dev-mode bypass: when the executable path is the literal string `\"dev\"` all\n * hash verification is skipped and Tier 3 unverified is returned immediately.\n */\n\nimport { hashExecutable } from './hash.js'\nimport { loadManifest, saveManifest, addTrustedHash, isTrusted } from './manifest.js'\nimport { IdentityMismatchError } from '../errors.js'\nimport type { TrustVerificationResult, TrustOptions, PendingTrust } from './types.js'\n\n/** Attempt Sigstore bundle verification (Tier 1). Returns `true` on success. */\nasync function trySigstore(execPath: string): Promise<boolean> {\n try {\n // Dynamic import so the library works without sigstore installed.\n // @ts-expect-error — sigstore is an optional peer dependency not listed in\n // package.json; the import will fail at runtime if not installed, which is\n // the intended behaviour. We catch that case below.\n const sigstore: unknown = await import('sigstore')\n // sigstore.verify expects a bundle; for executable verification we check\n // whether the library is present and functional. If the import succeeds but\n // the verify function is not available we fall through gracefully.\n if (typeof sigstore !== 'object' || sigstore === null) {\n return false\n }\n if (!('verify' in sigstore) || typeof sigstore.verify !== 'function') {\n return false\n }\n // Executable bundles are not universally available; treat any error as a\n // Tier-1 failure rather than a hard error.\n void execPath // execPath would be used in a full Sigstore bundle lookup\n return false // Full Sigstore bundle verification not yet available for arbitrary binaries\n } catch {\n return false\n }\n}\n\n/**\n * Verify the trust tier of the executable at `execPath` without writing\n * anything to the trust manifest.\n *\n * This is the verify phase of the verify/commit split: it computes the\n * executable's hash and classifies it against the existing manifest state,\n * but a first-encounter (Tier 3) or Sigstore (Tier 1) result — which would\n * otherwise record a new hash — is only staged on\n * {@link PendingTrust.pendingWrite}. Nothing is persisted until the caller\n * invokes {@link commitTrust} with the returned value, which callers should do\n * only once the operation the trust decision was gating (e.g. reading the\n * secret) has actually succeeded. This prevents a failed operation from\n * durably pre-seeding TOFU trust for an executable that never completed a\n * legitimate first encounter.\n *\n * A TOFU conflict never stages a write (`pendingWrite` is `undefined`) — the\n * pre-existing manifest state is authoritative and a conflict must always\n * fail without recording the new, unapproved hash.\n *\n * @param execPath - Path to the executable, or `\"dev\"` to enable dev-mode bypass.\n * @param options - Optional trust configuration.\n * @internal\n */\nexport async function verifyTrustPending(\n execPath: string,\n options?: TrustOptions,\n): Promise<PendingTrust> {\n const configDir = options?.configDir ?? '.vaultkeeper'\n\n // Dev-mode bypass: skip all verification for the sentinel value \"dev\".\n if (execPath === 'dev') {\n return {\n identity: { hash: 'dev', trustTier: 3, verified: false },\n tofuConflict: false,\n approvedHashes: [],\n reason: 'Dev mode — hash verification skipped',\n pendingWrite: undefined,\n configDir,\n }\n }\n\n const namespace = options?.namespace ?? execPath\n\n // Compute the current hash of the executable.\n const currentHash = await hashExecutable(execPath)\n\n // Load the manifest for TOFU and registry checks.\n const manifest = await loadManifest(configDir)\n\n // Hashes already approved for this namespace (empty on a first encounter).\n const approvedHashes = manifest.get(namespace)?.hashes ?? []\n\n // --- Tier 1: Sigstore ---\n if (options?.skipSigstore !== true) {\n const sigstoreVerified = await trySigstore(execPath)\n if (sigstoreVerified) {\n return {\n identity: { hash: currentHash, trustTier: 1, verified: true },\n tofuConflict: false,\n approvedHashes,\n reason: 'Sigstore bundle verified',\n pendingWrite: { namespace, hash: currentHash },\n configDir,\n }\n }\n }\n\n // --- Tier 2: Registry (manifest) ---\n if (isTrusted(manifest, namespace, currentHash)) {\n return {\n identity: { hash: currentHash, trustTier: 2, verified: true },\n tofuConflict: false,\n approvedHashes,\n reason: 'Hash found in trust manifest',\n pendingWrite: undefined,\n configDir,\n }\n }\n\n // --- TOFU check ---\n const existing = manifest.get(namespace)\n if (existing !== undefined && existing.hashes.length > 0) {\n // The namespace is known but the current hash is not approved — TOFU\n // conflict. Never stage a write: the new hash must not be recorded.\n return {\n identity: { hash: currentHash, trustTier: 3, verified: false },\n tofuConflict: true,\n approvedHashes,\n reason: `Hash changed from a previously approved value — re-approval required`,\n pendingWrite: undefined,\n configDir,\n }\n }\n\n // --- Tier 3: First encounter — stage the hash for TOFU recording ---\n // `reason` describes staging, not persistence: nothing is written until a\n // caller invokes commitTrust (see PendingTrust.pendingWrite above).\n return {\n identity: { hash: currentHash, trustTier: 3, verified: false },\n tofuConflict: false,\n approvedHashes,\n reason: 'First encounter — hash staged for TOFU recording',\n pendingWrite: { namespace, hash: currentHash },\n configDir,\n }\n}\n\n/**\n * Commit phase of the verify/commit split: persist a {@link PendingTrust}'s\n * staged trust-manifest entry, if any.\n *\n * A no-op when {@link PendingTrust.pendingWrite} is `undefined` (a registry\n * match, a TOFU conflict, or dev-mode bypass never write).\n *\n * Verification and commit are not atomic — another process can write to the\n * manifest in between (e.g. approving a different executable, or the same\n * one). To avoid clobbering that concurrent write, this reloads the manifest\n * from disk immediately before saving and re-classifies the staged\n * `(namespace, hash)` entry against the *current* state, rather than\n * persisting a snapshot captured back in {@link verifyTrustPending} (#209):\n *\n * - Already trusted (e.g. a concurrent commit for the same executable landed\n * first) — a no-op; skipping the redundant `saveManifest` avoids\n * unnecessary I/O and shrinks the window for a last-writer-wins race.\n * - The namespace has approved hashes that do **not** include the staged one\n * — a concurrent process recorded a *different* executable for this\n * namespace in the window since verification. Merging anyway would\n * silently approve a second hash for one namespace, bypassing the\n * TOFU-conflict record-nothing rule enforced at verify time (#148). This\n * re-classifies as a conflict: throws {@link IdentityMismatchError} and\n * writes nothing.\n * - The namespace has no entry yet — merges the staged entry in, as before.\n *\n * @param pending - The result of {@link verifyTrustPending} to commit.\n * @throws {@link IdentityMismatchError} If a concurrent process recorded a\n * different hash for the same namespace since verification.\n * @internal\n */\nexport async function commitTrust(pending: PendingTrust): Promise<void> {\n if (pending.pendingWrite === undefined) {\n return\n }\n const { namespace, hash } = pending.pendingWrite\n const current = await loadManifest(pending.configDir)\n const existing = current.get(namespace)\n if (existing?.hashes.includes(hash) === true) {\n return\n }\n if (existing !== undefined && existing.hashes.length > 0) {\n const previousHash = existing.hashes.at(-1) ?? hash\n throw new IdentityMismatchError(\n 'Executable hash changed — re-approval required',\n previousHash,\n hash,\n )\n }\n const merged = addTrustedHash(current, namespace, hash)\n await saveManifest(pending.configDir, merged)\n}\n\n/**\n * Verify the trust tier of the executable at `execPath`, recording any\n * first-encounter (TOFU) or Sigstore hash immediately.\n *\n * This is an eager convenience wrapper around {@link verifyTrustPending} +\n * {@link commitTrust} for callers that don't need to defer the manifest write\n * until after a later operation succeeds. {@link VaultKeeper.setup} uses the\n * split form directly so a failed `setup()` call never pre-seeds the trust\n * manifest — see issue #148.\n *\n * @param execPath - Path to the executable, or `\"dev\"` to enable dev-mode bypass.\n * @param options - Optional trust configuration.\n * @internal\n */\nexport async function verifyTrust(\n execPath: string,\n options?: TrustOptions,\n): Promise<TrustVerificationResult> {\n const pending = await verifyTrustPending(execPath, options)\n await commitTrust(pending)\n const { identity, tofuConflict, approvedHashes, pendingWrite } = pending\n // verifyTrustPending's `reason` describes staging, since verification alone\n // never writes. This wrapper just committed the write above, though, so a\n // first-encounter result should keep its pre-split, persisted-tense wording\n // for existing external callers rather than surfacing \"staged\" language for\n // something that, by this point, has actually been recorded.\n const reason =\n pendingWrite !== undefined && identity.trustTier === 3\n ? 'First encounter — hash recorded via TOFU'\n : pending.reason\n return { identity, tofuConflict, approvedHashes, reason }\n}\n","/**\n * Capability token management.\n *\n * Tokens are backed by a `WeakMap` whose keys are `CapabilityToken` instances,\n * so the actual claims are never reachable from outside this module. Private\n * class fields enforce that no property on the token object leaks data.\n */\n\nimport type { VaultClaims, SigningClaims } from './types.js'\nimport { AuthorizationDeniedError } from '../errors.js'\n\n/**\n * The claims a capability token can wrap: either an ordinary secret's\n * {@link VaultClaims} or a signing key's {@link SigningClaims}. The two are\n * discriminated by the presence of a `keyType` field so secret-access and\n * signing paths can each reject the wrong kind of token.\n *\n * @internal\n */\nexport type StoredClaims = VaultClaims | SigningClaims\n\n/**\n * An opaque handle to authorized secret claims.\n *\n * A `CapabilityToken` is produced by {@link VaultKeeper.authorize} and\n * deliberately exposes no readable data. The underlying claims — including the\n * secret value — are held in a module-private `WeakMap` that this class does\n * not reference, and its private fields keep any property from leaking them\n * (`toString()` returns only a debug identifier). There is intentionally no\n * public API for reading the claims directly.\n *\n * To use the secret, pass the token to a {@link VaultKeeper} access method —\n * {@link VaultKeeper.getSecret}, {@link VaultKeeper.fetch},\n * {@link VaultKeeper.exec}, or {@link VaultKeeper.sign} — which resolve the\n * claims internally.\n *\n * @public\n */\nexport class CapabilityToken {\n // Private field ensures no public surface leaks claims.\n readonly #brand: symbol\n\n constructor() {\n this.#brand = Symbol('CapabilityToken')\n }\n\n /**\n * Return a non-enumerable identifier for debugging purposes only.\n * Does NOT expose claims.\n */\n toString(): string {\n return `[CapabilityToken ${this.#brand.toString()}]`\n }\n}\n\n/** Internal storage for claims — inaccessible outside the module closure. */\nconst claimsStore = new WeakMap<CapabilityToken, StoredClaims>()\n\n/**\n * Create a capability token that wraps secret `claims`.\n * The claims are stored in a module-private `WeakMap` and cannot be reached\n * without calling `validateCapabilityToken`.\n * @internal\n */\nexport function createCapabilityToken(claims: VaultClaims): CapabilityToken {\n const token = new CapabilityToken()\n claimsStore.set(token, claims)\n return token\n}\n\n/**\n * Create a capability token that wraps signing-key `claims`.\n *\n * The claims carry only references (`kid`, `backendRef`, `keyType`) — never any\n * private key material — so a signing token can never leak a key even if the\n * WeakMap entry were somehow observed.\n * @internal\n */\nexport function createSigningCapabilityToken(claims: SigningClaims): CapabilityToken {\n const token = new CapabilityToken()\n claimsStore.set(token, claims)\n return token\n}\n\n/**\n * Retrieve the claims associated with `token`.\n *\n * @throws {AuthorizationDeniedError} if the token was not created by this\n * module (i.e. it has no claims entry in the store).\n * @internal\n */\nexport function validateCapabilityToken(token: CapabilityToken): StoredClaims {\n const claims = claimsStore.get(token)\n if (claims === undefined) {\n throw new AuthorizationDeniedError('Invalid or unrecognized capability token')\n }\n return claims\n}\n\n/**\n * Narrow stored claims to {@link SigningClaims}.\n *\n * This guards a security discriminator, so it validates the full invariants\n * rather than trusting the shape: the `keyType` must be exactly\n * `'signing-key'`, `kid` and `backendRef` must be present non-empty strings,\n * and — defense in depth — the claims must carry no `val` field. A claims\n * object that presents both the signing markers and secret material (`val`) is\n * malformed or hostile and is rejected outright rather than treated as a\n * signing key.\n *\n * @internal\n */\nexport function isSigningClaims(claims: StoredClaims): claims is SigningClaims {\n // Inspect via an index-signature view so each check is a real runtime\n // validation, not a type-level tautology over the pre-narrowed union.\n const record: Record<string, unknown> = { ...claims }\n const kid = record.kid\n const backendRef = record.backendRef\n return (\n record.keyType === 'signing-key' &&\n typeof kid === 'string' &&\n kid.length > 0 &&\n typeof backendRef === 'string' &&\n backendRef.length > 0 &&\n !('val' in record)\n )\n}\n","/**\n * Key management for vaultkeeper, including generation, rotation, revocation,\n * and grace-period tracking.\n */\n\nimport * as crypto from 'node:crypto'\nimport { RotationInProgressError, SetupError } from '../errors.js'\nimport type { KeyMaterial, KeyState, KeyStateSnapshot } from './types.js'\n\n/**\n * Manage cryptographic keys with rotation and grace-period semantics.\n *\n * @remarks\n * Whether a rotation is \"in progress\" is derived entirely from\n * {@link KeyManager.isInGracePeriod} — a grace period is active exactly while a\n * previous key is still usable. This makes the state serializable via\n * {@link KeyManager.snapshot}/{@link KeyManager.hydrate}, so the guard against a\n * second rotation survives a process restart (see `keys/storage.ts`) rather than\n * relying on a live in-process timer.\n * @internal\n */\nexport class KeyManager {\n #state: KeyState | undefined = undefined\n #gracePeriodTimer: ReturnType<typeof setTimeout> | undefined = undefined\n #gracePeriodExpiresAt: number | undefined = undefined\n\n /** Generate a new 32-byte key with a timestamp-based id. */\n generateKey(): KeyMaterial {\n const randomSuffix = crypto.randomBytes(4).toString('hex')\n return {\n id: `k-${String(Date.now())}-${randomSuffix}`,\n key: new Uint8Array(crypto.randomBytes(32)),\n createdAt: new Date(),\n }\n }\n\n /**\n * Initialize the manager with a freshly generated key.\n * Safe to call multiple times; subsequent calls are no-ops.\n */\n init(): Promise<void> {\n if (this.#state === undefined) {\n this.#state = { current: this.generateKey() }\n }\n return Promise.resolve()\n }\n\n /**\n * Replace the in-memory state with a persisted snapshot.\n *\n * An expired grace period in the snapshot is dropped: the previous key is\n * discarded and no grace period is restored. When the grace period is still\n * active, a fresh timer is armed for the remaining duration so the previous\n * key is eventually freed in long-running processes; correctness never depends\n * on that timer (grace is always re-checked against the wall clock).\n * @internal\n */\n hydrate(snapshot: KeyStateSnapshot): void {\n this.#clearGracePeriodTimer()\n\n if (\n snapshot.previous !== undefined &&\n snapshot.gracePeriodExpiresAt !== undefined &&\n Date.now() < snapshot.gracePeriodExpiresAt\n ) {\n this.#state = { current: snapshot.current, previous: snapshot.previous }\n this.#gracePeriodExpiresAt = snapshot.gracePeriodExpiresAt\n this.#armGracePeriodTimer(snapshot.gracePeriodExpiresAt - Date.now())\n } else {\n this.#state = { current: snapshot.current }\n this.#gracePeriodExpiresAt = undefined\n }\n }\n\n /**\n * Capture the current state as a serializable snapshot for persistence.\n * The previous key and grace expiry are included only while the grace period\n * is still active.\n * @internal\n */\n snapshot(): KeyStateSnapshot {\n const state = this.#requireState()\n const result: KeyStateSnapshot = { current: state.current }\n const previous = this.getPreviousKey()\n if (previous !== undefined && this.#gracePeriodExpiresAt !== undefined) {\n result.previous = previous\n result.gracePeriodExpiresAt = this.#gracePeriodExpiresAt\n }\n return result\n }\n\n /** Return the current (encryption) key. Throws if not initialized. */\n getCurrentKey(): KeyMaterial {\n const state = this.#requireState()\n return state.current\n }\n\n /**\n * Return the previous key if we are still inside a grace period,\n * otherwise `undefined`.\n */\n getPreviousKey(): KeyMaterial | undefined {\n const state = this.#requireState()\n // Grace is authoritative: even if a timer has not yet fired to clear the\n // reference, an expired grace period means the previous key is unusable.\n if (!this.isInGracePeriod()) {\n return undefined\n }\n return state.previous\n }\n\n /**\n * Find a key by its id, searching current then previous.\n * Returns `undefined` if the key is not found (or the previous key's\n * grace period has expired).\n */\n findKeyById(kid: string): KeyMaterial | undefined {\n const state = this.#requireState()\n if (state.current.id === kid) {\n return state.current\n }\n const previous = this.getPreviousKey()\n if (previous?.id === kid) {\n return previous\n }\n return undefined\n }\n\n /**\n * Rotate the current key: the current key becomes previous, a new key\n * becomes current. A grace-period timer is started; when it fires the\n * previous key is cleared automatically.\n *\n * @throws {RotationInProgressError} if a rotation is already underway (i.e. a\n * previous key is still within its grace period).\n */\n rotateKey(gracePeriodMs: number): void {\n const state = this.#requireState()\n\n if (this.isInGracePeriod()) {\n throw new RotationInProgressError('A key rotation is already in progress')\n }\n\n // Cancel any stale timer (e.g. from a grace period that has already\n // elapsed) before starting a new rotation.\n this.#clearGracePeriodTimer()\n\n const newKey = this.generateKey()\n this.#state = { current: newKey, previous: state.current }\n this.#gracePeriodExpiresAt = Date.now() + gracePeriodMs\n this.#armGracePeriodTimer(gracePeriodMs)\n }\n\n /**\n * Emergency revocation: immediately clear the previous key and generate\n * a brand-new current key. Any in-flight grace period is cancelled.\n */\n revokeKey(): void {\n this.#clearGracePeriodTimer()\n this.#gracePeriodExpiresAt = undefined\n\n const newKey = this.generateKey()\n this.#state = { current: newKey }\n }\n\n /**\n * Return `true` while a rotation grace period is active (i.e. the previous\n * key is still accessible).\n */\n isInGracePeriod(): boolean {\n if (this.#gracePeriodExpiresAt === undefined) {\n return false\n }\n return Date.now() < this.#gracePeriodExpiresAt\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n #requireState(): KeyState {\n if (this.#state === undefined) {\n throw new SetupError('KeyManager has not been initialized — call init() first', 'KeyManager')\n }\n return this.#state\n }\n\n #armGracePeriodTimer(delayMs: number): void {\n this.#gracePeriodTimer = setTimeout(() => {\n if (this.#state !== undefined) {\n // Remove the previous key once the grace period elapses.\n this.#state = { current: this.#state.current }\n }\n this.#gracePeriodExpiresAt = undefined\n this.#gracePeriodTimer = undefined\n }, delayMs)\n\n // Allow the timer to be GC'd without keeping the process alive.\n if (typeof this.#gracePeriodTimer.unref === 'function') {\n this.#gracePeriodTimer.unref()\n }\n }\n\n #clearGracePeriodTimer(): void {\n if (this.#gracePeriodTimer !== undefined) {\n clearTimeout(this.#gracePeriodTimer)\n this.#gracePeriodTimer = undefined\n }\n }\n}\n","/**\n * Persistence for {@link KeyManager} state.\n *\n * @remarks\n * Key material is written under the vaultkeeper config directory, encrypted at\n * rest with AES-256-GCM via the shared {@link encryptGcm}/{@link decryptGcm}\n * helpers (the same authenticated cipher the {@link FileBackend} uses — no\n * bespoke crypto). Two owner-only (mode `0o600`) files are used:\n *\n * - `keys.enc` — the AES-256-GCM envelope of the JSON-serialized key state.\n * - `.keys.wrap` — the random 32-byte wrapping key that protects `keys.enc`.\n *\n * Persisting key material lets a JWE minted by one CLI process be authorized by\n * a later process within the token's validity window: the `kid` a token embeds\n * still resolves to a known key after the minting process exits. Without this,\n * every process generated fresh keys, so a cached token always failed\n * authorization with {@link KeyRevokedError}.\n *\n * @internal\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport { encryptGcm, decryptGcm, getOrCreateWrapKey } from '../util/at-rest.js'\nimport { toFilesystemError } from '../errors.js'\nimport type { KeyMaterial, KeyStateSnapshot } from './types.js'\n\nconst KEY_STATE_FILE = 'keys.enc'\nconst KEY_WRAP_FILE = '.keys.wrap'\n\n/** On-disk JSON shape for a single key (raw bytes base64-encoded). */\ninterface RawKeyMaterial {\n id: string\n key: string\n createdAt: string\n}\n\n/** On-disk JSON shape for the whole key state. */\ninterface RawKeyState {\n version: number\n current: RawKeyMaterial\n previous?: RawKeyMaterial\n gracePeriodExpiresAt?: number\n}\n\nfunction serializeKey(key: KeyMaterial): RawKeyMaterial {\n return {\n id: key.id,\n key: Buffer.from(key.key).toString('base64'),\n createdAt: key.createdAt.toISOString(),\n }\n}\n\n/**\n * Type guard for a single {@link RawKeyMaterial}. Validates every field so a\n * corrupt or truncated file is treated as \"no persisted state\" rather than\n * yielding a malformed key.\n */\nfunction isRawKeyMaterial(value: unknown): value is RawKeyMaterial {\n if (typeof value !== 'object' || value === null) return false\n if (!('id' in value) || typeof value.id !== 'string' || value.id === '') return false\n if (!('key' in value) || typeof value.key !== 'string' || value.key === '') return false\n if (!('createdAt' in value) || typeof value.createdAt !== 'string') return false\n return true\n}\n\nfunction deserializeKey(raw: RawKeyMaterial): KeyMaterial | undefined {\n const bytes = Buffer.from(raw.key, 'base64')\n // A 32-byte AES-256 key is required; reject anything else as corrupt.\n if (bytes.byteLength !== 32) return undefined\n const createdAt = new Date(raw.createdAt)\n if (Number.isNaN(createdAt.getTime())) return undefined\n return { id: raw.id, key: new Uint8Array(bytes), createdAt }\n}\n\n/**\n * Type guard for {@link RawKeyState}.\n */\nfunction isRawKeyState(value: unknown): value is RawKeyState {\n if (typeof value !== 'object' || value === null) return false\n if (!('version' in value) || typeof value.version !== 'number') return false\n if (!('current' in value) || !isRawKeyMaterial(value.current)) return false\n if ('previous' in value && value.previous !== undefined && !isRawKeyMaterial(value.previous)) {\n return false\n }\n if (\n 'gracePeriodExpiresAt' in value &&\n value.gracePeriodExpiresAt !== undefined &&\n typeof value.gracePeriodExpiresAt !== 'number'\n ) {\n return false\n }\n return true\n}\n\n/**\n * Load persisted key state from `configDir`, or `undefined` when no valid state\n * exists yet (first run, or an unreadable/corrupt file).\n * @internal\n */\nexport async function loadKeyState(configDir: string): Promise<KeyStateSnapshot | undefined> {\n const statePath = path.join(configDir, KEY_STATE_FILE)\n\n let envelope: string\n try {\n envelope = await fs.readFile(statePath, 'utf8')\n } catch {\n return undefined\n }\n\n const wrapKey = await getOrCreateWrapKey(path.join(configDir, KEY_WRAP_FILE))\n let json: string\n try {\n json = decryptGcm(wrapKey, envelope, statePath)\n } catch {\n // Envelope failed authentication (tampered, or wrap key lost/rotated).\n // Treat as absent so a fresh key state is generated rather than crashing.\n return undefined\n } finally {\n wrapKey.fill(0)\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(json)\n } catch {\n return undefined\n }\n\n if (!isRawKeyState(parsed)) return undefined\n\n const current = deserializeKey(parsed.current)\n if (current === undefined) return undefined\n\n const snapshot: KeyStateSnapshot = { current }\n\n if (parsed.previous !== undefined && parsed.gracePeriodExpiresAt !== undefined) {\n const previous = deserializeKey(parsed.previous)\n // Only surface the previous key while its grace period is still active; an\n // expired grace period is equivalent to no previous key at all.\n if (previous !== undefined && Date.now() < parsed.gracePeriodExpiresAt) {\n snapshot.previous = previous\n snapshot.gracePeriodExpiresAt = parsed.gracePeriodExpiresAt\n }\n }\n\n return snapshot\n}\n\n/**\n * Persist `snapshot` to `configDir`, creating the directory if necessary. The\n * state file and its wrapping key are both written owner-only (`0o600`).\n *\n * Uses atomic write-then-rename so a concurrent {@link loadKeyState} never sees\n * a half-written envelope.\n * @internal\n */\nexport async function saveKeyState(configDir: string, snapshot: KeyStateSnapshot): Promise<void> {\n // Creating the config directory can fail (e.g. its parent is read-only) on\n // the first `store`, which persists key state before any secret is written.\n // Surface a typed FilesystemError rather than leaking the raw Node\n // `EACCES: … mkdir '<path>'` text (issue #228).\n try {\n await fs.mkdir(configDir, { recursive: true, mode: 0o700 })\n } catch (err) {\n throw toFilesystemError(err, 'config directory', configDir, 'create')\n }\n\n const raw: RawKeyState = {\n version: 1,\n current: serializeKey(snapshot.current),\n }\n if (snapshot.previous !== undefined && snapshot.gracePeriodExpiresAt !== undefined) {\n raw.previous = serializeKey(snapshot.previous)\n raw.gracePeriodExpiresAt = snapshot.gracePeriodExpiresAt\n }\n\n const wrapKey = await getOrCreateWrapKey(path.join(configDir, KEY_WRAP_FILE))\n let envelope: string\n try {\n envelope = encryptGcm(wrapKey, JSON.stringify(raw))\n } finally {\n wrapKey.fill(0)\n }\n\n const statePath = path.join(configDir, KEY_STATE_FILE)\n const tmpPath = `${statePath}.${String(process.pid)}.tmp`\n // Keep the write and the rename in separate try/catch blocks so the reported\n // FilesystemError path matches whichever step actually failed: the temp file\n // on a write failure (e.g. EACCES/ENOSPC creating it), the final state file\n // on a rename failure. A single shared catch would always blame `statePath`.\n try {\n await fs.writeFile(tmpPath, envelope, { encoding: 'utf8', mode: 0o600 })\n } catch (err) {\n throw toFilesystemError(err, 'key state file', tmpPath, 'write')\n }\n try {\n await fs.rename(tmpPath, statePath)\n } catch (err) {\n throw toFilesystemError(err, 'key state file', statePath, 'write')\n }\n}\n","/**\n * JWE token creation and decryption using `jose` with `dir` + `A256GCM`.\n */\n\nimport { CompactEncrypt, compactDecrypt } from 'jose'\nimport type { VaultClaims } from '../types.js'\nimport { InvalidTokenError } from '../errors.js'\n\nconst ALGORITHM = 'dir'\nconst ENCRYPTION = 'A256GCM'\n\n/**\n * Options for token creation.\n * @internal\n */\nexport interface CreateTokenOptions {\n /** Optional key ID to embed in the JWE header for rotation tracking. */\n kid?: string | undefined\n}\n\n/**\n * Creates a compact JWE string from the given claims.\n *\n * Uses `dir` (direct key agreement) with `A256GCM` content encryption.\n * The 256-bit key must be exactly 32 bytes.\n *\n * @param key - 32-byte symmetric key (AES-256)\n * @param claims - VaultClaims payload to encrypt\n * @param options - Optional token creation options\n * @returns Compact JWE string\n * @internal\n */\nexport async function createToken(\n key: Uint8Array,\n claims: VaultClaims,\n options?: CreateTokenOptions,\n): Promise<string> {\n const plaintext = new TextEncoder().encode(JSON.stringify(claims))\n\n const header: { alg: typeof ALGORITHM; enc: typeof ENCRYPTION; kid?: string } = {\n alg: ALGORITHM,\n enc: ENCRYPTION,\n }\n\n if (options?.kid !== undefined) {\n header.kid = options.kid\n }\n\n return new CompactEncrypt(plaintext).setProtectedHeader(header).encrypt(key)\n}\n\n/**\n * Type guard that checks whether an unknown value is a non-null object.\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Parses a raw JSON payload object into VaultClaims, validating that all required fields\n * are present and of the correct types. Returns `undefined` if validation fails.\n */\nfunction parseVaultClaims(raw: unknown): VaultClaims | undefined {\n if (!isObject(raw)) {\n return undefined\n }\n\n const { jti, exp, iat, sub, exe, use, tid, bkd, val, ref } = raw\n\n if (typeof jti !== 'string') return undefined\n if (typeof exp !== 'number') return undefined\n if (typeof iat !== 'number') return undefined\n if (typeof sub !== 'string') return undefined\n if (typeof exe !== 'string') return undefined\n if (use !== null && typeof use !== 'number') return undefined\n if (tid !== 1 && tid !== 2 && tid !== 3) return undefined\n if (typeof bkd !== 'string') return undefined\n if (typeof val !== 'string') return undefined\n if (typeof ref !== 'string') return undefined\n\n return { jti, exp, iat, sub, exe, use: use ?? null, tid, bkd, val, ref }\n}\n\n/**\n * Decrypts a compact JWE string and returns the VaultClaims payload.\n *\n * @param key - 32-byte symmetric key (AES-256)\n * @param jwe - Compact JWE string to decrypt\n * @returns Decrypted VaultClaims\n * @throws VaultError if decryption fails or the payload is malformed\n * @internal\n */\nexport async function decryptToken(key: Uint8Array, jwe: string): Promise<VaultClaims> {\n let plaintext: Uint8Array\n try {\n const result = await compactDecrypt(jwe, key)\n plaintext = result.plaintext\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new InvalidTokenError(`JWE decryption failed: ${message}`)\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(new TextDecoder().decode(plaintext))\n } catch {\n throw new InvalidTokenError('JWE payload is not valid JSON')\n }\n\n const claims = parseVaultClaims(parsed)\n if (claims === undefined) {\n throw new InvalidTokenError('JWE payload does not match VaultClaims schema')\n }\n\n return claims\n}\n\n/**\n * Extracts the `kid` header from a compact JWE without decrypting it.\n *\n * The protected header in compact JWE is the first Base64URL-encoded segment.\n *\n * @param jwe - Compact JWE string\n * @returns The kid value, or undefined if not present\n * @throws VaultError if the JWE structure is invalid\n * @internal\n */\nexport function extractKid(jwe: string): string | undefined {\n const parts = jwe.split('.')\n if (parts.length !== 5) {\n throw new InvalidTokenError('Invalid JWE compact serialization: expected 5 parts')\n }\n const headerSegment = parts[0]\n if (headerSegment === undefined || headerSegment === '') {\n throw new InvalidTokenError('Invalid JWE compact serialization: missing header segment')\n }\n let headerJson: string\n try {\n headerJson = Buffer.from(headerSegment, 'base64url').toString('utf-8')\n } catch {\n throw new InvalidTokenError('Invalid JWE compact serialization: header is not valid Base64URL')\n }\n\n let header: unknown\n try {\n header = JSON.parse(headerJson)\n } catch {\n throw new InvalidTokenError('Invalid JWE compact serialization: header is not valid JSON')\n }\n\n if (!isObject(header)) {\n return undefined\n }\n\n const kid = header.kid\n if (typeof kid !== 'string') {\n return undefined\n }\n return kid\n}\n","/**\n * VaultClaims validation and in-memory token blocklist.\n */\n\nimport type { VaultClaims } from '../types.js'\nimport {\n TokenExpiredError,\n TokenRevokedError,\n UsageLimitExceededError,\n VaultError,\n} from '../errors.js'\n\n/**\n * Maximum number of JTIs the in-memory blocklist will retain.\n * When the cap is reached, the oldest inserted entry is evicted (FIFO/LRU).\n * This prevents unbounded growth for long-running processes.\n */\nconst BLOCKLIST_MAX_SIZE = 10_000\n\n/**\n * In-memory blocklist for revoked token JTIs. This is process-local and non-persistent.\n * For production use, a distributed blocklist (e.g., Redis) should be layered on top.\n *\n * A Map is used instead of a Set because Map preserves insertion order, which\n * allows O(1) eviction of the oldest entry (first key in iteration order).\n * The map values are always `true` — only the keys matter for lookup.\n */\nconst blocklist = new Map<string, true>()\n\n/**\n * Adds a JTI to the in-memory blocklist, preventing further use of that token.\n * If the blocklist has reached its maximum size, the oldest entry is evicted first.\n *\n * @param jti - The unique token ID to block\n * @internal\n */\nexport function blockToken(jti: string): void {\n if (blocklist.has(jti)) {\n // Already blocked — re-inserting would not change insertion order in Map,\n // so we delete and re-add to refresh the recency position.\n blocklist.delete(jti)\n } else if (blocklist.size >= BLOCKLIST_MAX_SIZE) {\n // Evict the oldest entry (first key in insertion-order iteration).\n const oldestKey = blocklist.keys().next().value\n if (oldestKey !== undefined) {\n blocklist.delete(oldestKey)\n }\n }\n blocklist.set(jti, true)\n}\n\n/**\n * Returns true if the given JTI has been blocked.\n *\n * @param jti - The unique token ID to check\n * @internal\n */\nexport function isBlocked(jti: string): boolean {\n return blocklist.has(jti)\n}\n\n/**\n * Clears all blocked JTIs from the in-memory blocklist.\n * Primarily intended for use in tests.\n * @internal\n */\nexport function clearBlocklist(): void {\n blocklist.clear()\n}\n\n/**\n * Validates all claims in a VaultClaims payload.\n * @internal\n *\n * Checks performed:\n * - Required fields present (jti, exp, iat, sub, exe, tid, bkd, val, ref)\n * - Token is not expired (exp vs. current time)\n * - Token is not on the blocklist\n * - Usage limit (use) is not exceeded if a positive limit is set\n * - Trust tier (tid) is valid (1, 2, or 3)\n *\n * @param claims - VaultClaims payload to validate\n * @param usedCount - How many times the token has been used already (for `use` limit checking)\n * @throws TokenExpiredError if the token is expired\n * @throws TokenRevokedError if the token has been blocked\n * @throws UsageLimitExceededError if the usage count has been exhausted\n * @throws VaultError for missing or malformed required fields\n */\nexport function validateClaims(claims: VaultClaims, usedCount = 0): void {\n // Validate required string fields are non-empty\n if (claims.jti.trim() === '') {\n throw new VaultError('Invalid token: jti must not be empty')\n }\n if (claims.sub.trim() === '') {\n throw new VaultError('Invalid token: sub must not be empty')\n }\n if (claims.exe.trim() === '') {\n throw new VaultError('Invalid token: exe must not be empty')\n }\n if (claims.bkd.trim() === '') {\n throw new VaultError('Invalid token: bkd must not be empty')\n }\n if (claims.val.trim() === '') {\n throw new VaultError('Invalid token: val must not be empty')\n }\n if (claims.ref.trim() === '') {\n throw new VaultError('Invalid token: ref must not be empty')\n }\n\n // Validate timestamp ordering\n if (claims.iat > claims.exp) {\n throw new VaultError('Invalid token: iat must not be after exp')\n }\n\n // Check expiration\n const nowSec = Math.floor(Date.now() / 1000)\n if (nowSec >= claims.exp) {\n throw new TokenExpiredError(\n `Token expired at ${String(claims.exp)} (now: ${String(nowSec)})`,\n false,\n )\n }\n\n // Check blocklist\n if (isBlocked(claims.jti)) {\n throw new TokenRevokedError(`Token ${claims.jti} has been revoked`)\n }\n\n // Check usage limit\n if (claims.use !== null) {\n if (claims.use <= 0) {\n throw new UsageLimitExceededError(\n `Token ${claims.jti} has a non-positive usage limit: ${String(claims.use)}`,\n )\n }\n if (usedCount >= claims.use) {\n throw new UsageLimitExceededError(\n `Token ${claims.jti} usage limit of ${String(claims.use)} exceeded (used: ${String(usedCount)})`,\n )\n }\n }\n}\n","/**\n * Placeholder replacement utilities for delegated access patterns.\n *\n * Supports two modes:\n * - **Single-secret:** `{{secret}}` is replaced with a single secret value\n * - **Named-secret:** `{{secret:name}}` is replaced with the corresponding\n * named secret from a `Record<string, string>` map\n */\n\nimport { VaultError } from '../errors.js'\n\n/** Literal placeholder for single-secret mode. */\nexport const PLACEHOLDER = '{{secret}}'\n\n/** Regex matching `{{secret:name}}` named placeholders. */\nconst NAMED_PLACEHOLDER_RE = /\\{\\{secret:([^}]+)\\}\\}/g\n\n/** Regex matching any secret placeholder (named or unnamed). */\nexport const ANY_PLACEHOLDER_RE = /\\{\\{secret(?::[^}]+)?\\}\\}/\n\n/**\n * Replace placeholders in a string with secret values.\n *\n * When `secrets` is a `string`, every `{{secret}}` occurrence is replaced.\n * When `secrets` is a `Record`, every `{{secret:name}}` occurrence is\n * resolved from the corresponding map entry.\n *\n * @param value - The string containing placeholders\n * @param secrets - A single secret string (replaces `{{secret}}`) or a\n * name-to-value map (replaces `{{secret:name}}`)\n * @returns The string with all matching placeholders resolved\n * @throws {VaultError} If a named placeholder references a name not in the map\n * @internal\n */\nexport function resolvePlaceholders(\n value: string,\n secrets: string | Record<string, string>,\n): string {\n if (typeof secrets === 'string') {\n return value.replaceAll(PLACEHOLDER, secrets)\n }\n return value.replace(NAMED_PLACEHOLDER_RE, (_match, name: string) => {\n const secret = secrets[name]\n if (secret === undefined) {\n const available = Object.keys(secrets).join(', ')\n throw new VaultError(\n `Unknown secret name in placeholder: {{secret:${name}}}. Available names: ${available}`,\n )\n }\n return secret\n })\n}\n\n/**\n * Replace placeholders in all values of a string record.\n *\n * @param record - Key-value pairs whose values may contain placeholders\n * @param secrets - A single secret string or a name-to-value map\n * @returns A new record with all placeholders in values resolved\n * @internal\n */\nexport function resolvePlaceholdersInRecord(\n record: Record<string, string>,\n secrets: string | Record<string, string>,\n): Record<string, string> {\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n result[key] = resolvePlaceholders(value, secrets)\n }\n return result\n}\n","/**\n * Delegated HTTP fetch access pattern.\n *\n * Replaces `{{secret}}` or `{{secret:name}}` placeholders in the request\n * URL, headers, and body with actual secret values, then executes the fetch.\n */\n\nimport type { FetchRequest } from '../types.js'\nimport { FetchError } from '../errors.js'\nimport { resolvePlaceholders, resolvePlaceholdersInRecord } from './placeholder.js'\n\n/**\n * Remove any secret material from an underlying error's text before it is\n * surfaced in a thrown message. Network/DNS/TLS errors routinely embed the\n * requested (placeholder-resolved) URL in their own message — e.g.\n * `getaddrinfo ENOTFOUND host-containing-secret` — so the resolved URL and\n * every raw secret value must be stripped. Uses literal `split`/`join`\n * (not regex) so secret contents are never interpreted as a pattern.\n */\nfunction redactSecretMaterial(\n detail: string,\n resolvedUrl: string,\n urlTemplate: string,\n secretValues: readonly string[],\n): string {\n let out = detail\n if (resolvedUrl !== urlTemplate) {\n out = out.split(resolvedUrl).join(urlTemplate)\n }\n for (const value of secretValues) {\n if (value.length > 0) {\n out = out.split(value).join('[REDACTED]')\n }\n }\n return out\n}\n\n/**\n * Execute a delegated HTTP fetch with secrets injected into the request.\n *\n * @param secrets - A single secret string (replaces `{{secret}}`) or a\n * name-to-value map (replaces `{{secret:name}}`)\n * @param request - The fetch request template with placeholders\n * @returns The fetch Response\n * @throws {FetchError} If the URL is malformed or the underlying network\n * request fails (e.g. DNS failure, connection refused, TLS error).\n * @internal\n */\nexport async function delegatedFetch(\n secrets: string | Record<string, string>,\n request: FetchRequest,\n): Promise<Response> {\n const url = resolvePlaceholders(request.url, secrets)\n const headers =\n request.headers !== undefined\n ? resolvePlaceholdersInRecord(request.headers, secrets)\n : undefined\n const body = request.body !== undefined ? resolvePlaceholders(request.body, secrets) : undefined\n\n const init: RequestInit = {}\n if (request.method !== undefined) {\n init.method = request.method\n }\n if (headers !== undefined) {\n init.headers = headers\n }\n if (body !== undefined) {\n init.body = body\n }\n\n try {\n return await fetch(url, init)\n } catch (error) {\n const rawDetail = error instanceof Error ? error.message : String(error)\n // The underlying error's message can embed the placeholder-resolved URL\n // (with the injected secret) — e.g. `getaddrinfo ENOTFOUND <secret-host>`.\n // Redact the resolved URL and every secret value before including it, and\n // report the unresolved template (`request.url`), never the resolved `url`,\n // so no secret is echoed into the thrown message or the `url` field. The\n // original error is deliberately not attached as `cause`: its message\n // cannot be redacted in place and would reintroduce the leak.\n const secretValues = typeof secrets === 'string' ? [secrets] : Object.values(secrets)\n const detail = redactSecretMaterial(rawDetail, url, request.url, secretValues)\n throw new FetchError(`Fetch failed for ${request.url}: ${detail}`, request.url)\n }\n}\n","/**\n * Secret redaction for captured process output.\n *\n * The single source of truth for how an injected secret value is scrubbed from\n * text. Both the library's delegated `exec()` (which buffers full output) and\n * the CLI's streaming `RedactingStream` (which redacts live) route their\n * substitution through {@link redactSecrets}, so the redaction behavior can\n * never drift between the two surfaces.\n */\n\n/**\n * The token substituted for a redacted secret value.\n *\n * @public\n */\nexport const REDACTED = '[REDACTED]'\n\n/**\n * Replace every occurrence of each secret value in `text` with `replacement`.\n *\n * This is used to scrub captured child-process `stdout`/`stderr` so a secret\n * injected into a delegated command never surfaces in the returned output.\n *\n * Before redacting, the secret set is normalized so masking is complete and\n * order-independent:\n *\n * - **Empty/whitespace-only values are dropped.** An empty string matches\n * between every character, and a whitespace-only value matches ubiquitous\n * whitespace, so redacting either would blank the text rather than a secret.\n * - **Duplicates are removed** so each distinct value is processed once.\n * - **Longer values are redacted first.** If one secret is a substring or\n * prefix of another — common for keys that share a prefix — redacting the\n * shorter one first would leave the longer secret's remaining suffix visible\n * (redacting `\"abc\"` before `\"abc123\"` yields `\"[REDACTED]123\"`, leaking\n * `\"123\"`). Sorting by length descending guarantees each longer value is\n * fully masked before any shorter substring pass runs.\n *\n * Both arguments are treated fully literally: the secret is matched as a\n * plain substring (never as a regular expression), and `replacement` is\n * inserted verbatim — `String.prototype.replaceAll`'s `$`-substitution\n * patterns are disabled, since a replacement containing `$&` would otherwise\n * re-expand to the matched secret and silently defeat the redaction.\n *\n * @param text - The text to scrub.\n * @param secrets - The secret values to redact. Every non-empty, non-whitespace\n * value has all of its occurrences replaced.\n * @param replacement - The token to substitute for each occurrence, inserted\n * literally. Defaults to {@link REDACTED}.\n * @returns `text` with every occurrence of each redactable secret replaced.\n *\n * @public\n */\nexport function redactSecrets(\n text: string,\n secrets: readonly string[],\n replacement: string = REDACTED,\n): string {\n const ordered = [...new Set(secrets)]\n .filter((secret) => secret.trim().length > 0)\n .sort((a, b) => b.length - a.length)\n\n // '$' doubles to '$$' so replaceAll inserts the replacement verbatim\n // instead of interpreting $&/$`/$' substitution patterns.\n const literalReplacement = replacement.replaceAll('$', '$$$$')\n let result = text\n for (const secret of ordered) {\n result = result.replaceAll(secret, literalReplacement)\n }\n return result\n}\n","/**\n * Delegated command execution access pattern.\n *\n * Replaces `{{secret}}` or `{{secret:name}}` placeholders in environment\n * values, then executes the command. Placeholders are rejected in the\n * `command` and `args` fields — process arguments (and the command name)\n * are visible to other processes via `ps` and often collected in logs and\n * telemetry, so secrets must be injected via `env` instead.\n *\n * By default the captured `stdout`/`stderr` is scrubbed of every injected\n * secret value (replaced with `[REDACTED]`) before it is returned, so a\n * command that echoes the secret never leaks it back through the return value.\n * `request.redact === false` opts out and returns raw output.\n */\n\nimport { spawn } from 'node:child_process'\nimport type { ExecRequest, ExecResult } from '../types.js'\nimport { ExecError, VaultError } from '../errors.js'\nimport { ANY_PLACEHOLDER_RE, resolvePlaceholdersInRecord } from './placeholder.js'\nimport { redactSecrets } from './redact.js'\n\n/**\n * Execute a delegated command with secrets injected into env.\n *\n * @param secrets - A single secret string (replaces `{{secret}}`) or a\n * name-to-value map (replaces `{{secret:name}}`)\n * @param request - The exec request template with placeholders. Placeholders\n * are only resolved in `env`; `command` and `args` reject them with\n * `ExecError`.\n * @returns The command result (stdout, stderr, exitCode)\n * @internal\n */\nexport async function delegatedExec(\n secrets: string | Record<string, string>,\n request: ExecRequest,\n): Promise<ExecResult> {\n if (ANY_PLACEHOLDER_RE.test(request.command)) {\n throw new ExecError(\n `Secret placeholders are not supported in the command field. Use env instead.`,\n request.command,\n )\n }\n\n const args = request.args ?? []\n for (const arg of args) {\n if (ANY_PLACEHOLDER_RE.test(arg)) {\n throw new ExecError(\n `Secret placeholders are not supported in the args field — process arguments are visible to other processes via ps. Use env instead.`,\n request.command,\n )\n }\n }\n\n // Every value that could have been injected into the child's environment.\n // These are what we scrub from captured output so an echoed secret never\n // leaks back through stdout/stderr. Redacting values that were not actually\n // injected is harmless (they simply won't be present) and keeps the set\n // conservative.\n const secretValues = typeof secrets === 'string' ? [secrets] : Object.values(secrets)\n const shouldRedact = request.redact !== false\n\n let env: Record<string, string> | undefined\n try {\n env = request.env !== undefined ? resolvePlaceholdersInRecord(request.env, secrets) : undefined\n } catch (error) {\n if (error instanceof VaultError) {\n throw new ExecError(error.message, request.command)\n }\n throw error\n }\n\n return new Promise((resolve, reject) => {\n const spawnOptions: Parameters<typeof spawn>[2] = {\n stdio: ['ignore', 'pipe', 'pipe'],\n }\n if (env !== undefined) {\n spawnOptions.env = { ...process.env, ...env }\n }\n if (request.cwd !== undefined) {\n spawnOptions.cwd = request.cwd\n }\n\n const proc = spawn(request.command, args, spawnOptions)\n let stdout = ''\n let stderr = ''\n\n proc.stdout?.on('data', (data: Buffer) => {\n stdout += data.toString()\n })\n\n proc.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString()\n })\n\n proc.on('close', (code) => {\n resolve({\n stdout: shouldRedact ? redactSecrets(stdout, secretValues) : stdout,\n stderr: shouldRedact ? redactSecrets(stderr, secretValues) : stderr,\n exitCode: code ?? 1,\n })\n })\n\n proc.on('error', (error) => {\n const isEnoent = error instanceof Error && 'code' in error && error.code === 'ENOENT'\n if (isEnoent) {\n reject(\n new ExecError(\n `Command not found: ${request.command}. Verify the command exists and is in PATH.`,\n request.command,\n ),\n )\n } else {\n reject(\n new ExecError(\n `Failed to execute command: ${request.command}. ${error instanceof Error ? error.message : String(error)}`,\n request.command,\n ),\n )\n }\n })\n })\n}\n","/**\n * Controlled direct access pattern.\n *\n * Provides a `SecretAccessor` backed by a Proxy that:\n * - Exposes a single `.read()` method\n * - Passes a Buffer containing the secret to the callback\n * - Zeros the buffer after the callback returns\n * - Passes the callback's return value back through to the caller\n * - Prevents double-read (throws a descriptive Error on second call)\n * - Redacts itself from Node.js inspect output\n */\n\nimport type { SecretAccessor } from '../types.js'\nimport { AccessorConsumedError } from '../errors.js'\n\nconst INSPECT_CUSTOM = Symbol.for('nodejs.util.inspect.custom')\n\n/** Extended accessor that also supports custom inspect. */\ninterface SecretAccessorInternal extends SecretAccessor {\n [INSPECT_CUSTOM](): string\n}\n\n/**\n * Proxy target class that satisfies SecretAccessorInternal.\n *\n * Instances have their prototype set to null and are made non-extensible\n * after construction, so all proxy invariants can be met consistently:\n * - getPrototypeOf trap returns null (matches actual prototype)\n * - isExtensible trap returns false (matches actual extensibility)\n * - ownKeys trap includes all own keys (matches non-extensible contract)\n */\nclass SecretAccessorTarget implements SecretAccessorInternal {\n readonly read: <T>(callback: (buf: Buffer) => T) => T\n readonly [INSPECT_CUSTOM]: () => string\n\n constructor(readImpl: <T>(callback: (buf: Buffer) => T) => T, inspectImpl: () => string) {\n this.read = readImpl\n this[INSPECT_CUSTOM] = inspectImpl\n }\n}\n\n/**\n * Create a `SecretAccessor` for the given secret value.\n * @internal\n *\n * The accessor is backed by a Proxy with all 13 traps implemented. The\n * `consumed` flag blocks re-execution after the first `read()` call, and the\n * buffer containing the secret is zeroed in the `finally` block regardless of\n * whether the callback throws. No proxy revocation is used: the `consumed`\n * flag already prevents double-reads, and revocation would surface a raw V8\n * `TypeError: Cannot perform 'get' on a proxy that has been revoked` before\n * the descriptive error message can be thrown.\n */\nexport function createSecretAccessor(secretValue: string): SecretAccessor {\n let consumed = false\n\n // Close over the actual read logic. The callback's return value is passed\n // through so callers can derive a value (string, hash, ...) from the secret;\n // the buffer is still zeroed in `finally` before the value is returned, so\n // returning the raw buffer would only ever yield zeroed bytes.\n function readImpl<T>(callback: (buf: Buffer) => T): T {\n if (consumed) {\n throw new AccessorConsumedError(\n 'SecretAccessor has already been consumed — call getSecret() again to obtain a new accessor',\n )\n }\n consumed = true\n\n const buf = Buffer.from(secretValue, 'utf8')\n try {\n return callback(buf)\n } finally {\n buf.fill(0)\n }\n }\n\n function inspectImpl(): string {\n return '[SecretAccessor]'\n }\n\n // Build the proxy target: a class instance with null prototype and\n // non-extensible to satisfy V8's proxy invariants for those traps.\n const target = new SecretAccessorTarget(readImpl, inspectImpl)\n Object.setPrototypeOf(target, null)\n Object.preventExtensions(target)\n\n // All 13 proxy handler traps.\n const handler: Required<ProxyHandler<SecretAccessorInternal>> = {\n get(_t, prop, _receiver) {\n if (prop === 'read') return readImpl\n if (prop === INSPECT_CUSTOM) return inspectImpl\n return undefined\n },\n set(_t, _prop, _value, _receiver) {\n return false\n },\n has(_t, prop) {\n return prop === 'read' || prop === INSPECT_CUSTOM\n },\n deleteProperty(_t, _prop) {\n return false\n },\n apply(_t, _thisArg, _args) {\n throw new TypeError('SecretAccessor is not a function')\n },\n construct(_t, _args, _newTarget) {\n throw new TypeError('SecretAccessor is not a constructor')\n },\n defineProperty(_t, _prop, _descriptor) {\n return false\n },\n getOwnPropertyDescriptor(_t, prop) {\n if (prop === 'read') {\n return { configurable: true, enumerable: true, writable: false, value: readImpl }\n }\n if (prop === INSPECT_CUSTOM) {\n return { configurable: true, enumerable: false, writable: false, value: inspectImpl }\n }\n return undefined\n },\n getPrototypeOf(_t) {\n // Null prototype — matches the actual target prototype after setPrototypeOf(target, null).\n return null\n },\n setPrototypeOf(_t, _proto) {\n return false\n },\n isExtensible(_t) {\n // Non-extensible — matches the actual target extensibility.\n return false\n },\n preventExtensions(_t) {\n // Already non-extensible — trap returns true (success) matching target state.\n return true\n },\n ownKeys(_t) {\n // Must include all own keys of the non-extensible target.\n // The target has 'read' and INSPECT_CUSTOM as own properties.\n return ['read', INSPECT_CUSTOM]\n },\n }\n\n return new Proxy(target, handler)\n}\n","/**\n * Detached-payload Compact JWS assembly and verification.\n *\n * The signature format is the documented, stable contract for `sign`/`verify`:\n * a detached-payload Compact JWS (RFC 7515 §7.2.2 + RFC 7797 `b64:false`,\n * `crit:[\"b64\"]`). The serialization is `<protected>..<signature>` with the\n * payload omitted; the algorithm is `EdDSA` (Ed25519); all encoding is\n * base64url without padding. The output is byte-for-byte what `jose`'s\n * `CompactSign` produces for the same header and payload, so any standards\n * compliant JOSE library verifies it independently.\n *\n * Signing is performed by a caller-supplied signer so the private key can stay\n * inside the backend — this module never sees key material during signing.\n *\n * @see https://www.rfc-editor.org/rfc/rfc7515 (JWS)\n * @see https://www.rfc-editor.org/rfc/rfc7797 (Unencoded Payload Option)\n * @internal\n */\n\nimport { Buffer } from 'node:buffer'\nimport { flattenedVerify, importSPKI } from 'jose'\nimport type { VerifyRequest } from '../types.js'\nimport { InvalidKeyMaterialError } from '../errors.js'\n\n/** The single supported JWS `alg` (Ed25519). */\nexport const JWS_ALG = 'EdDSA'\n\n/** Coerce a string|Buffer payload to raw bytes (strings are UTF-8). */\nfunction toBytes(data: string | Buffer): Buffer {\n return Buffer.isBuffer(data) ? data : Buffer.from(data, 'utf8')\n}\n\n/**\n * Build the RFC 7797 (`b64:false`) JWS Signing Input:\n * `ASCII(BASE64URL(UTF8(protected)) || '.') || payload`.\n */\nfunction signingInput(protectedB64: string, payload: Buffer): Buffer {\n return Buffer.concat([Buffer.from(`${protectedB64}.`, 'ascii'), payload])\n}\n\n/**\n * Assemble a detached-payload Compact JWS over `payload`, delegating the raw\n * signature to `sign` (which the backend performs so the key never leaves it).\n *\n * @param kid - Stable key identifier placed in the protected header.\n * @param payload - The detached payload bytes.\n * @param sign - Signer that returns the raw Ed25519 signature over its input.\n * @returns The compact serialization `<protected>..<signature>`.\n * @internal\n */\nexport async function createDetachedJws(\n kid: string,\n payload: string | Buffer,\n sign: (data: Buffer) => Promise<Buffer>,\n): Promise<string> {\n const header = { alg: JWS_ALG, b64: false, crit: ['b64'], kid }\n const protectedB64 = Buffer.from(JSON.stringify(header), 'utf8').toString('base64url')\n const signature = await sign(signingInput(protectedB64, toBytes(payload)))\n return `${protectedB64}..${signature.toString('base64url')}`\n}\n\n/**\n * Shape of the protected header we require for a valid detached JWS. Anything\n * that does not match is treated as a non-verifying signature (not an error).\n *\n * Per RFC 7515 §4.1.11, a verifier MUST reject a JWS whose `crit` lists any\n * extension it does not understand. This verifier understands only the RFC 7797\n * `b64` extension, so `crit` must be exactly `[\"b64\"]` — a `crit` carrying any\n * additional (un-understood) parameter, e.g. `[\"b64\",\"x\"]`, is rejected.\n */\nfunction hasExpectedHeader(header: unknown): boolean {\n if (typeof header !== 'object' || header === null) {\n return false\n }\n const record: Record<string, unknown> = { ...header }\n const crit = record.crit\n return (\n record.alg === JWS_ALG &&\n record.b64 === false &&\n Array.isArray(crit) &&\n crit.length === 1 &&\n crit[0] === 'b64'\n )\n}\n\n/**\n * Verify a detached-payload Compact JWS against a public key, fully offline.\n *\n * Returns `false` for a signature that does not verify — a tampered payload,\n * the wrong key, or a structurally malformed JWS. Throws\n * {@link InvalidKeyMaterialError} only when the *public key* itself is not\n * parseable (or a private key was supplied), which is an operational fault\n * rather than a bad signature.\n *\n * @internal\n */\nexport async function verifyDetachedJws(request: VerifyRequest): Promise<boolean> {\n // Validate the JWS envelope — its structure and, critically, its declared\n // algorithm and `crit` — BEFORE parsing any key material. The algorithm this\n // verifier accepts is fixed (EdDSA); an unsupported algorithm, or a `crit`\n // listing an un-understood extension, must be rejected on the envelope's own\n // terms (RFC 7515 §4.1.11 crit semantics). Doing this first guarantees a\n // malformed key can never mask that decision or be reported in its place.\n const parts = request.jws.trim().split('.')\n if (parts.length !== 3) {\n return false\n }\n const [protectedB64, middle, signatureB64] = parts\n // A detached compact JWS has an empty payload segment.\n if (protectedB64 === undefined || signatureB64 === undefined || middle !== '') {\n return false\n }\n\n let header: unknown\n try {\n header = JSON.parse(Buffer.from(protectedB64, 'base64url').toString('utf8'))\n } catch {\n return false\n }\n if (!hasExpectedHeader(header)) {\n return false\n }\n\n // Only once the algorithm/envelope is accepted do we parse the public key.\n // Reject a private key supplied as the public key with a clear message — the\n // documented contract is an SPKI *public* key only.\n if (request.publicKey.includes('PRIVATE KEY')) {\n throw new InvalidKeyMaterialError(\n 'A private key was supplied where an SPKI public key is required.',\n )\n }\n\n // Strictly parse the input as an SPKI PEM public key for the EdDSA algorithm.\n // Unlike crypto.createPublicKey(), which accepts a range of PEM/DER encodings\n // (PKCS#1, certificates, other curves), importSPKI enforces the exact\n // documented contract: anything that is not an SPKI PEM EdDSA public key —\n // PKCS#1, a wrong-curve/RSA SPKI, or garbage — throws, and we surface it as a\n // typed InvalidKeyMaterialError (an operational fault, not a bad signature).\n let key: Awaited<ReturnType<typeof importSPKI>>\n try {\n key = await importSPKI(request.publicKey, JWS_ALG)\n } catch {\n throw new InvalidKeyMaterialError(\n 'The supplied public key is not an SPKI PEM EdDSA public key.',\n )\n }\n\n try {\n await flattenedVerify(\n { protected: protectedB64, payload: toBytes(request.payload), signature: signatureB64 },\n key,\n { algorithms: [JWS_ALG] },\n )\n return true\n } catch {\n return false\n }\n}\n","/**\n * Individual preflight check functions for each system dependency.\n */\n\nimport { execCommand } from '../util/exec.js'\nimport type { PreflightCheck } from '../types.js'\n\n/**\n * Parse a semver-like version string and return [major, minor, patch].\n * Returns null if unparseable.\n */\nfunction parseVersion(raw: string): [number, number, number] | null {\n const match = /(\\d+)\\.(\\d+)\\.(\\d+)/.exec(raw)\n if (!match) return null\n const major = parseInt(match[1] ?? '0', 10)\n const minor = parseInt(match[2] ?? '0', 10)\n const patch = parseInt(match[3] ?? '0', 10)\n return [major, minor, patch]\n}\n\n/**\n * Returns true if [aMajor, aMinor, aPatch] >= [bMajor, bMinor, bPatch].\n */\nfunction versionGte(a: [number, number, number], b: [number, number, number]): boolean {\n if (a[0] !== b[0]) return a[0] > b[0]\n if (a[1] !== b[1]) return a[1] > b[1]\n return a[2] >= b[2]\n}\n\n/**\n * Check that openssl is present and >= 1.1.1.\n * @internal\n */\nexport async function checkOpenssl(): Promise<PreflightCheck> {\n const name = 'openssl'\n try {\n const output = await execCommand('openssl', ['version'])\n const parsed = parseVersion(output)\n if (!parsed) {\n return {\n name,\n status: 'version-unsupported',\n version: output,\n reason: 'Could not parse openssl version',\n }\n }\n if (!versionGte(parsed, [1, 1, 1])) {\n return {\n name,\n status: 'version-unsupported',\n version: output,\n reason: 'openssl >= 1.1.1 is required',\n }\n }\n return { name, status: 'ok', version: output }\n } catch {\n return { name, status: 'missing', reason: 'openssl not found in PATH' }\n }\n}\n\n/**\n * Check that bash is present.\n * @internal\n */\nexport async function checkBash(): Promise<PreflightCheck> {\n const name = 'bash'\n try {\n const output = await execCommand('bash', ['--version'])\n const firstLine = output.split('\\n')[0] ?? output\n return { name, status: 'ok', version: firstLine }\n } catch {\n return { name, status: 'missing', reason: 'bash not found in PATH' }\n }\n}\n\n/**\n * Check that PowerShell is present (Windows only).\n * @internal\n */\nexport async function checkPowershell(): Promise<PreflightCheck> {\n const name = 'powershell'\n try {\n const output = await execCommand('powershell', ['-Command', '$PSVersionTable.PSVersion'])\n const version = output.trim()\n return { name, status: 'ok', version }\n } catch {\n return { name, status: 'missing', reason: 'powershell not found in PATH' }\n }\n}\n\n/**\n * Check that macOS security CLI is present (macOS only, for Keychain access).\n * @internal\n */\nexport async function checkSecurity(): Promise<PreflightCheck> {\n const name = 'security'\n try {\n // `security help` exits with non-zero but writes to stderr; we only need it to exist\n await execCommand('security', ['help'])\n return { name, status: 'ok' }\n } catch (err) {\n // security help exits non-zero intentionally — if we got stderr output, it's present\n const message = err instanceof Error ? err.message : String(err)\n if (message.includes('security')) {\n // The command exists but help exits with a non-zero code\n return { name, status: 'ok' }\n }\n return {\n name,\n status: 'missing',\n reason: 'security command not found in PATH',\n }\n }\n}\n\n/**\n * Check that secret-tool is present (Linux only).\n * @internal\n */\nexport async function checkSecretTool(): Promise<PreflightCheck> {\n const name = 'secret-tool'\n try {\n const output = await execCommand('secret-tool', ['--version'])\n return { name, status: 'ok', version: output.trim() }\n } catch {\n return {\n name,\n status: 'missing',\n reason: 'secret-tool not found in PATH (install libsecret-tools)',\n }\n }\n}\n\n/**\n * Check that 1Password CLI (op) is present (optional).\n * @internal\n */\nexport async function checkOp(): Promise<PreflightCheck> {\n const name = 'op'\n try {\n const output = await execCommand('op', ['--version'])\n return { name, status: 'ok', version: output.trim() }\n } catch {\n return {\n name,\n status: 'missing',\n reason: 'op (1Password CLI) not found in PATH',\n }\n }\n}\n\n/**\n * Check that ykman (YubiKey Manager CLI) is present (optional).\n * @internal\n */\nexport async function checkYkman(): Promise<PreflightCheck> {\n const name = 'ykman'\n try {\n const output = await execCommand('ykman', ['--version'])\n return { name, status: 'ok', version: output.trim() }\n } catch {\n return {\n name,\n status: 'missing',\n reason: 'ykman (YubiKey Manager) not found in PATH',\n }\n }\n}\n","/**\n * Platform detection utilities.\n */\n\nimport { SetupError } from '../errors.js'\n\n/**\n * The OS platform identifier used for platform-specific behavior.\n * @public\n */\nexport type Platform = 'darwin' | 'win32' | 'linux'\n\n/**\n * Get the current platform.\n * @throws {SetupError} If `process.platform` is not one of the three\n * supported platforms.\n */\nexport function currentPlatform(): Platform {\n const p = process.platform\n if (p === 'darwin' || p === 'win32' || p === 'linux') {\n return p\n }\n throw new SetupError(`Unsupported platform: ${p}`, 'platform')\n}\n\n/** Check if running on macOS. */\nexport function isDarwin(): boolean {\n return process.platform === 'darwin'\n}\n\n/** Check if running on Windows. */\nexport function isWindows(): boolean {\n return process.platform === 'win32'\n}\n\n/** Check if running on Linux. */\nexport function isLinux(): boolean {\n return process.platform === 'linux'\n}\n","/**\n * Doctor runner: orchestrates platform-appropriate checks and aggregates results.\n */\n\nimport * as path from 'node:path'\nimport {\n checkOpenssl,\n checkBash,\n checkPowershell,\n checkSecurity,\n checkSecretTool,\n checkOp,\n checkYkman,\n} from './checks.js'\nimport { currentPlatform } from '../util/platform.js'\nimport { loadConfig } from '../config.js'\nimport {\n ConfigParseError,\n ConfigValidationError,\n FilesystemError,\n UnknownBackendTypeError,\n} from '../errors.js'\nimport type {\n BackendConfig,\n PreflightCheck,\n PreflightCheckError,\n PreflightResult,\n ScopedPreflightCheck,\n} from '../types.js'\nimport type { Platform } from '../util/platform.js'\n\n/**\n * Options for running the doctor.\n * @public\n */\nexport interface RunDoctorOptions {\n /** Override the platform detection (useful for testing). */\n platform?: Platform\n /**\n * When provided, doctor checks are scoped to the given backends.\n * Platform-native dependency checks (e.g. `secret-tool`, `security`,\n * `powershell`) are demoted from required to optional when the\n * corresponding backend is not enabled. Plugin tool checks (`op`,\n * `ykman`) are promoted from optional to required when their backend\n * (`1password`, `yubikey`) is explicitly enabled.\n *\n * When omitted, all platform-default checks are treated as required\n * (backward-compatible behavior).\n */\n backends?: BackendConfig[]\n /**\n * When provided (and `backends` is not explicitly given), doctor loads and\n * validates the config file under this directory, adding a `config`\n * preflight check to the result. A present-but-invalid config file (parse\n * or schema failure) becomes a failing, required check — with the\n * underlying error's message (file path, parse location, remediation hint)\n * as `reason` — so an invalid config is visible in `doctor`'s output and\n * fails the overall `ready` result (issue #68). A missing config file is\n * not an error: `loadConfig` resolves platform defaults and the check\n * reports `ok`.\n */\n configDir?: string\n}\n\n/** A doctor check entry pairing the check function with whether it is required. */\ninterface CheckEntry {\n check: () => Promise<PreflightCheck>\n required: boolean\n}\n\n/** Aggregated check entry with its result. */\ninterface ResolvedEntry {\n required: boolean\n result: PreflightCheck\n}\n\n/**\n * Run all platform-appropriate preflight checks and aggregate the results.\n * @public\n */\nexport async function runDoctor(options?: RunDoctorOptions): Promise<PreflightResult> {\n let platform: Platform\n try {\n platform = options?.platform ?? currentPlatform()\n } catch {\n return {\n checks: [],\n ready: false,\n warnings: [],\n nextSteps: ['Unsupported platform. vaultkeeper supports macOS, Linux, and Windows.'],\n }\n }\n\n // Resolve the config check and backend list together: an explicit\n // `backends` option always wins (backward-compatible, and used by callers\n // that already loaded/validated the config themselves, e.g. VaultKeeper.init\n // after a successful loadConfig). Otherwise, when `configDir` is given,\n // doctor loads and validates the config itself so an invalid config file\n // surfaces as a failing check instead of being invisible to doctor.\n let backends = options?.backends\n let configCheck: ScopedPreflightCheck | undefined\n if (backends === undefined && options?.configDir !== undefined) {\n const configPath = path.join(options.configDir, 'config.json')\n try {\n const config = await loadConfig(options.configDir)\n backends = config.backends\n configCheck = { name: 'config', status: 'ok', version: configPath, required: true }\n } catch (err) {\n configCheck = {\n name: 'config',\n status: 'invalid',\n reason: err instanceof Error ? err.message : String(err),\n error: toPreflightConfigError(err, configPath),\n required: true,\n }\n }\n }\n\n const enabledTypes = enabledBackendTypes(backends)\n const entries: CheckEntry[] = buildCheckList(platform, enabledTypes)\n\n const resolved: ResolvedEntry[] = await Promise.all(\n entries.map(async ({ check, required }) => {\n const result = await check()\n return { required, result }\n }),\n )\n\n const configReady = configCheck === undefined || configCheck.status === 'ok'\n const ready =\n configReady &&\n resolved.every(({ required, result }) => {\n if (!required) return true\n return result.status === 'ok'\n })\n\n const warnings: string[] = []\n const nextSteps: string[] = []\n\n if (configCheck !== undefined && configCheck.status !== 'ok') {\n // The config check is always required — an invalid config means the\n // vault cannot operate, so it always contributes a nextStep, never a\n // mere warning.\n nextSteps.push(configCheck.reason ?? 'Config file is invalid.')\n }\n\n for (const { required, result } of resolved) {\n const reasonSuffix = result.reason !== undefined ? ` — ${result.reason}` : ''\n\n if (result.status === 'missing') {\n if (required) {\n nextSteps.push(`Install missing required dependency: ${result.name}${reasonSuffix}`)\n } else {\n warnings.push(`Optional dependency not found: ${result.name}${reasonSuffix}`)\n }\n } else if (result.status === 'version-unsupported') {\n const msg = `${result.name} version is unsupported${reasonSuffix}`\n if (required) {\n nextSteps.push(`Upgrade required dependency: ${msg}`)\n } else {\n warnings.push(`Optional dependency version unsupported: ${msg}`)\n }\n }\n }\n\n const checks: ScopedPreflightCheck[] = [\n ...(configCheck !== undefined ? [configCheck] : []),\n ...resolved.map(({ required, result }) => ({ ...result, required })),\n ]\n\n return { checks, ready, warnings, nextSteps }\n}\n\n/**\n * Map a config load failure to structured, remediation-free error context\n * for the `config` preflight check. Returns `undefined` for an unrecognized\n * error, in which case only the human-readable `reason` is available.\n */\nfunction toPreflightConfigError(err: unknown, configPath: string): PreflightCheckError | undefined {\n if (err instanceof ConfigParseError) {\n return { kind: 'config-parse', configPath: err.path, location: err.location }\n }\n if (err instanceof UnknownBackendTypeError) {\n // A backend type that names no registered backend — a distinct, richer\n // failure than a generic schema violation. Carry the offending type and\n // the valid options so a consumer can give the same \"Available types: …\"\n // guidance the runtime BackendUnavailableError gives (issue #215). Checked\n // before ConfigValidationError since it is a subclass.\n return {\n kind: 'config-unknown-backend',\n configPath: err.configFilePath ?? configPath,\n field: err.field,\n backendType: err.backendType,\n knownBackendTypes: err.knownTypes,\n }\n }\n if (err instanceof ConfigValidationError) {\n // Carry the structured `field` (e.g. `backends`) so a consumer can render\n // the field-level detail the parse path gets from `location`, without\n // parsing the `reason` prose (issue #202).\n return {\n kind: 'config-validation',\n configPath: err.configFilePath ?? configPath,\n field: err.field,\n }\n }\n if (err instanceof FilesystemError) {\n // A read failure (e.g. EACCES/EPERM on the config file or its parent\n // directory) — `loadConfig` wraps any non-ENOENT read error as a\n // FilesystemError. The errno `code`, when present, lets a consumer pick\n // permission-specific wording; the remediation is never `config init\n // --force`, which cannot fix a read-permission problem.\n return { kind: 'config-read', configPath: err.path, code: err.code }\n }\n return undefined\n}\n\n/**\n * Extract the set of enabled backend type strings from the config.\n * Returns `null` when no backend list was provided, signalling that the\n * caller should fall back to platform defaults (backward-compatible).\n */\nfunction enabledBackendTypes(backends: BackendConfig[] | undefined): Set<string> | null {\n if (backends === undefined) return null\n const types = new Set<string>()\n for (const b of backends) {\n if (b.enabled) types.add(b.type)\n }\n return types\n}\n\nfunction buildCheckList(platform: Platform, enabledTypes: Set<string> | null): CheckEntry[] {\n // Core checks are always required regardless of backends.\n const entries: CheckEntry[] = [{ check: checkOpenssl, required: true }]\n\n if (platform === 'darwin') {\n // `security` is required only if keychain backend is configured (or no\n // backend list was provided, preserving backward-compatible defaults).\n entries.push({\n check: checkSecurity,\n required: enabledTypes === null || enabledTypes.has('keychain'),\n })\n entries.push({ check: checkBash, required: false })\n } else if (platform === 'win32') {\n entries.push({\n check: checkPowershell,\n required: enabledTypes === null || enabledTypes.has('dpapi'),\n })\n } else {\n // linux\n entries.push({ check: checkBash, required: true })\n entries.push({\n check: checkSecretTool,\n required: enabledTypes === null || enabledTypes.has('secret-tool'),\n })\n }\n\n // Plugin backend tools — required only if the corresponding backend is\n // explicitly enabled; otherwise optional (informational).\n entries.push({\n check: checkOp,\n required: enabledTypes?.has('1password') ?? false,\n })\n entries.push({\n check: checkYkman,\n required: enabledTypes?.has('yubikey') ?? false,\n })\n\n return entries\n}\n","/**\n * VaultKeeper main class — wires together all vaultkeeper subsystems.\n */\n\nimport * as crypto from 'node:crypto'\nimport * as path from 'node:path'\nimport type {\n VaultConfig,\n VaultClaims,\n VaultResponse,\n FetchRequest,\n ExecRequest,\n ExecResult,\n SecretAccessor,\n PreflightResult,\n TrustTier,\n SignRequest,\n SignResult,\n VerifyRequest,\n SigningAlgorithm,\n SigningPublicKey,\n} from './types.js'\nimport { loadConfig, getDefaultConfigDir } from './config.js'\nimport { KeyManager } from './keys/manager.js'\nimport { loadKeyState, saveKeyState } from './keys/storage.js'\nimport { BackendRegistry } from './backend/registry.js'\nimport { isSigningBackend, getBackendCapabilities } from './backend/types.js'\nimport type {\n SecretBackend,\n SigningBackend,\n BackendCapabilities,\n PresenceOperation,\n} from './backend/types.js'\nimport { createToken, decryptToken, extractKid, validateClaims, blockToken } from './jwe/index.js'\nimport { verifyTrustPending, commitTrust } from './identity/trust.js'\nimport { hashExecutable } from './identity/hash.js'\nimport { loadManifest, saveManifest, addTrustedHash, isTrusted } from './identity/manifest.js'\nimport {\n CapabilityToken,\n createCapabilityToken,\n createSigningCapabilityToken,\n validateCapabilityToken,\n isSigningClaims,\n} from './identity/session.js'\nimport { delegatedFetch } from './access/delegated-fetch.js'\nimport { delegatedExec } from './access/delegated-exec.js'\nimport { createSecretAccessor } from './access/controlled-direct.js'\nimport { createDetachedJws, verifyDetachedJws } from './access/jws.js'\nimport { runDoctor } from './doctor/runner.js'\nimport type { RunDoctorOptions } from './doctor/runner.js'\nimport {\n AuthorizationDeniedError,\n IdentityMismatchError,\n ExecutableTrustRequiredError,\n BackendUnavailableError,\n VaultError,\n KeyRevokedError,\n SigningNotSupportedError,\n NotCapableError,\n} from './errors.js'\n\n/**\n * Map of named secrets to their capability tokens.\n *\n * Use with `exec()` or `fetch()` to inject multiple secrets into a single\n * request. Each key becomes the name referenced in `{{secret:name}}`\n * placeholders.\n *\n * @example\n * ```ts\n * const { token: apiToken } = await vault.authorize(apiJwe)\n * const { token: dbToken } = await vault.authorize(dbJwe)\n *\n * await vault.exec(\n * { apiKey: apiToken, dbPass: dbToken },\n * { command: 'deploy', env: { API_KEY: '{{secret:apiKey}}', DB: '{{secret:dbPass}}' } },\n * )\n * ```\n *\n * @public\n */\nexport type SecretTokenMap = Record<string, CapabilityToken>\n\n/**\n * Builds a minimal built-in config used when {@link VaultKeeperOptions.backend}\n * is supplied without {@link VaultKeeperOptions.config}. Mirrors the defaults a\n * hand-assembled test config would use (short-lived tokens, dev-mode trust),\n * so an injected backend never requires a config file on disk or a\n * hand-assembled {@link VaultConfig}.\n *\n * Returns a fresh object on every call — `VaultKeeper` mutates `#config` in\n * place (e.g. `setDevelopmentMode()`), so a shared constant would let\n * separate `init()` calls corrupt each other's state.\n */\nfunction createDefaultInjectedBackendConfig(): VaultConfig {\n return {\n version: 1,\n backends: [],\n keyRotation: { gracePeriodDays: 7 },\n defaults: { ttlMinutes: 60, trustTier: 3 },\n }\n}\n\n/**\n * Options for initializing VaultKeeper.\n *\n * @remarks\n * When neither `config` nor a config file (at `configDir`) is present, and\n * {@link VaultKeeperOptions.backend} is not set, the active backend falls back\n * to the safe zero-config default resolved by {@link defaultBackendType} — the\n * `file` backend, on every platform, so a missing config never silently\n * targets the real OS credential store. Inspect\n * {@link VaultKeeper.activeBackendType} after `init()` to confirm which backend\n * a given instance resolved to. To use the OS-native store instead, opt in via\n * an explicit config, or `vaultkeeper config init --backend <type>` from the\n * separate `@vaultkeeper/cli` package (see {@link platformNativeBackendType}).\n * When `backend` is set instead, see that option's own JSDoc for the fallback\n * config used in its place.\n */\nexport interface VaultKeeperOptions {\n /** Override the config directory. */\n configDir?: string | undefined\n /** Supply config directly, skipping file load. */\n config?: VaultConfig | undefined\n /**\n * Inject a {@link SecretBackend} instance directly, bypassing the global\n * {@link BackendRegistry} and `config.backends` resolution entirely.\n *\n * This is the primary hook for tests and embedders that want to store and\n * retrieve secrets without registering a backend globally or hand\n * assembling a full {@link VaultConfig}. When set, this backend instance is\n * used for every `store()`/`retrieve()`/`setup()` call.\n *\n * **Precedence with `config`/`configDir`:**\n * - `backend` always wins over the backend that `config.backends` (or the\n * config loaded from `configDir`) would otherwise resolve — the\n * `backends` array is never consulted when `backend` is set.\n * - Other config fields (`keyRotation`, `defaults`, `developmentMode`)\n * still come from `config`, or from the config loaded from `configDir`,\n * when either is provided.\n * - If `backend` is set and `config` is omitted, a minimal built-in\n * default config is used instead of loading one from `configDir` — so a\n * caller that only needs an injected backend never has to construct a\n * {@link VaultConfig} or touch `configDir` at all.\n */\n backend?: SecretBackend | undefined\n /** Skip the doctor preflight check. */\n skipDoctor?: boolean | undefined\n}\n\n/**\n * Options common to every backend-touching operation that can be gated on a\n * fresh, per-use human presence action.\n *\n * @remarks\n * When `requirePresencePerUse` is `true`, the operation refuses — with a\n * {@link NotCapableError}, before any credential, session, or device is touched\n * — unless the active backend's configured instance advertises\n * {@link BackendCapabilities.presencePerUse}. When the backend is capable, the\n * operation proceeds through the backend's ordinary path, which (by the meaning\n * of the capability) forces a distinct fresh human action for this specific\n * call; a cached or session-unlocked state can never satisfy it. Capabilities\n * are queried fresh on every call and never cached across operations.\n *\n * @public\n */\nexport interface PresenceRequirementOptions {\n /**\n * Require the active backend to force a fresh, per-use human presence action\n * for this operation. Defaults to `false` (no presence requirement).\n */\n requirePresencePerUse?: boolean | undefined\n}\n\n/**\n * Options for {@link VaultKeeper.setup} that are independent of the mandatory\n * executable-trust choice. Intersected with that choice to form\n * {@link SetupOptions}.\n *\n * @public\n */\nexport interface SetupOptionsBase extends PresenceRequirementOptions {\n /** TTL in minutes for the JWE. */\n ttlMinutes?: number | undefined\n /** Usage limit (null for unlimited). */\n useLimit?: number | null | undefined\n /** Trust tier override. */\n trustTier?: TrustTier | undefined\n /** Backend type to use. */\n backendType?: string | undefined\n}\n\n/**\n * Options for the setup operation.\n *\n * @remarks\n * The executable-trust choice is **mandatory and mutually exclusive**, and the\n * type system enforces it: `SetupOptions` is {@link SetupOptionsBase}\n * intersected with a choice of **exactly one** of `executablePath` (run\n * trust-on-first-use verification — the production choice) or `skipTrust: true`\n * (deliberately skip verification — development only). An options object with\n * **neither** field, or with **both**, fails to typecheck; and because\n * {@link VaultKeeper.setup}'s options argument is required, `vault.setup('NAME')`\n * and `vault.setup('NAME', {})` are compile-time type errors rather than\n * runtime-only failures. {@link ExecutableTrustRequiredError} remains a runtime\n * backstop for callers without static typing (e.g. plain JavaScript), and is\n * still thrown if `executablePath` is the retired legacy `'dev'` sentinel.\n *\n * @public\n */\nexport type SetupOptions = SetupOptionsBase &\n (\n | {\n /**\n * Path to the calling executable, used to bind the minted token to that\n * executable's identity. `setup()` runs trust-on-first-use (TOFU)\n * verification: the file is hashed (SHA-256) and checked against the\n * local trust manifest. This is the safe, production choice.\n *\n * A path registered via `setDevelopmentMode` is still exempted from\n * hashing (the established development-mode allowlist); any other path\n * is verified. Mutually exclusive with `skipTrust`.\n *\n * **Rebuild caveat:** for a compiled or bundled entry point the file's\n * hash changes on every rebuild, so binding to a dev build target (e.g.\n * `process.argv[1]`) makes the next `setup()` after a recompile throw\n * `IdentityMismatchError`. In production point this at a **stable**\n * artifact — a released binary, or `process.execPath` to trust the Node\n * runtime; for a frequently-rebuilt local caller you want to keep\n * verifying, use `setDevelopmentMode` instead.\n */\n executablePath: string\n skipTrust?: never\n }\n | {\n /**\n * Development-only escape hatch: skip executable-trust (TOFU)\n * verification. The minted token carries no executable identity binding.\n *\n * **Security warning:** a token minted with `skipTrust: true` is not\n * bound to any calling executable, so any process that obtains the JWE\n * can redeem it. Use this only in local development or tests — never in\n * production. Prefer `executablePath` so executable trust is actually\n * enforced. Mutually exclusive with `executablePath`.\n */\n skipTrust: true\n executablePath?: never\n }\n )\n\n/**\n * Loose trust-choice shape accepted by the internal resolver. Unlike the public\n * {@link SetupOptions} discriminated union, both fields are independently\n * optional here so the runtime mutual-exclusion / missing-choice backstops stay\n * reachable for untyped (plain-JavaScript) callers.\n */\ninterface TrustChoiceInput extends SetupOptionsBase {\n executablePath?: string | undefined\n skipTrust?: boolean | undefined\n}\n\n/**\n * Trust status of an executable, as recorded in the trust-on-first-use (TOFU)\n * trust manifest.\n *\n * Returned by {@link VaultKeeper.approveExecutable} and\n * {@link VaultKeeper.checkExecutableTrust}.\n *\n * @public\n */\nexport interface ExecutableTrustStatus {\n /**\n * Whether the executable's current hash is approved in the trust manifest.\n * When `false`, callers must obtain approval (e.g. an interactive prompt)\n * before granting secret access.\n */\n trusted: boolean\n /** SHA-256 hex digest of the executable's current contents. */\n hash: string\n /**\n * `true` when the executable is already known to the manifest but its\n * current hash does not match any approved value — a TOFU conflict. A\n * conflicting executable is never trusted; callers must re-approve or deny.\n */\n hashMismatch: boolean\n /**\n * Hashes recorded as approved for this executable in the trust manifest, in\n * approval order (empty when the executable has never been approved). When\n * {@link ExecutableTrustStatus.hashMismatch} is `true`, these are the prior\n * approved values that {@link ExecutableTrustStatus.hash} no longer matches;\n * the last element is the most recently approved hash.\n */\n approvedHashes: readonly string[]\n /** Human-readable description of how trust was (or was not) established. */\n reason: string\n}\n\n/**\n * The **built-in** backend type identifiers known to implement the signing\n * contract ({@link SigningBackend}). Surfaced on {@link SigningNotSupportedError}\n * so a caller on a non-signing backend is pointed at a built-in that works.\n * Deliberately a static list of built-ins — a consumer's own registered\n * SigningBackend is not surveyed here (that would mean instantiating every\n * registered backend on an error path).\n */\nconst BUILTIN_SIGNING_BACKENDS = ['file'] as const\n\n/**\n * Human-readable guidance naming the kinds of backends that can satisfy a\n * presence-per-use requirement. Surfaced in {@link NotCapableError} messages so\n * a caller whose configured backend cannot provide the guarantee is pointed at\n * ones that can. Deliberately describes qualifying *configurations* (not a fixed\n * type list), since the capability is per configured instance — a custom\n * backend may also qualify.\n */\nconst PRESENCE_PER_USE_QUALIFYING_BACKENDS =\n 'A qualifying backend forces a distinct, fresh human action per operation — ' +\n 'e.g. a YubiKey slot with a touch-per-operation policy or a gpg smartcard with ' +\n 'touch-to-sign (both cover every operation), or 1Password in per-access mode ' +\n '(which enforces presence for reads only today, not writes). Switch to (or ' +\n 'reconfigure) such a backend, or drop the presence requirement.'\n\n/** Usage tracking for tokens with use limits. */\nconst usageCounts = new Map<string, number>()\n\n/**\n * Maximum number of JTIs the in-memory usage-count map will retain.\n * When the cap is reached, the oldest inserted entry is evicted (FIFO).\n * This prevents unbounded growth for long-running processes.\n */\nconst USAGE_MAP_MAX_SIZE = 10_000\n\n/**\n * Main entry point for vaultkeeper. Orchestrates backends, keys, JWE tokens,\n * identity verification, and access patterns.\n */\nexport class VaultKeeper {\n readonly #config: VaultConfig\n readonly #keyManager: KeyManager\n readonly #configDir: string\n /**\n * Whether key material is persisted to (and reloaded from) `#configDir`.\n * Enabled only when the vault operates against a real on-disk config — i.e.\n * neither `config` nor `backend` was injected in-process (see\n * {@link VaultKeeper.init}). Injected-config/backend instances keep keys\n * purely in memory so tests and embedders stay hermetic.\n */\n readonly #persistKeys: boolean\n #backend: SecretBackend | undefined\n /**\n * Whether {@link #backend} was injected via `init({ backend })` rather than\n * lazily resolved from `#config.backends`. Distinguishes the two so that\n * {@link activeBackendType} reports the injected instance directly instead of\n * consulting the (empty) config backend list. Stays correct after a lazy\n * resolution populates {@link #backend} in the config-driven path.\n */\n readonly #backendInjected: boolean\n\n private constructor(\n config: VaultConfig,\n keyManager: KeyManager,\n configDir: string,\n persistKeys: boolean,\n backend?: SecretBackend,\n ) {\n this.#config = config\n this.#keyManager = keyManager\n this.#configDir = configDir\n this.#persistKeys = persistKeys\n this.#backend = backend\n this.#backendInjected = backend !== undefined\n }\n\n /**\n * Initialize a new VaultKeeper instance.\n * Runs doctor checks (unless skipped), loads config, and sets up the key manager.\n *\n * The configured secret backend is resolved lazily on first use, not during\n * `init()`. Trust-only operations (e.g. {@link VaultKeeper.approveExecutable},\n * {@link VaultKeeper.checkExecutableTrust}) therefore succeed even when the\n * configured backend or plugin is unavailable or unregistered; a\n * misconfigured backend surfaces only when a secret operation is invoked.\n */\n static async init(options?: VaultKeeperOptions): Promise<VaultKeeper> {\n const configDir = options?.configDir ?? getDefaultConfigDir()\n const config =\n options?.config ??\n (options?.backend !== undefined\n ? createDefaultInjectedBackendConfig()\n : await loadConfig(configDir))\n\n if (options?.skipDoctor !== true) {\n const doctorResult = await runDoctor({ backends: config.backends })\n if (!doctorResult.ready) {\n throw new VaultError(`System not ready: ${doctorResult.nextSteps.join('; ')}`)\n }\n }\n\n // Persist key material to disk only when operating against a real on-disk\n // config directory. When either `config` or `backend` is injected, the\n // caller is assembling the vault in-process (tests, embedders), so keys stay\n // in memory and never touch the config dir.\n const persistKeys = options?.config === undefined && options?.backend === undefined\n\n const keyManager = new KeyManager()\n if (persistKeys) {\n const loaded = await loadKeyState(configDir)\n if (loaded !== undefined) {\n keyManager.hydrate(loaded)\n } else {\n await keyManager.init()\n await saveKeyState(configDir, keyManager.snapshot())\n }\n } else {\n await keyManager.init()\n }\n\n return new VaultKeeper(config, keyManager, configDir, persistKeys, options?.backend)\n }\n\n /**\n * Run doctor checks without full initialization.\n *\n * When called without arguments, uses conservative platform defaults —\n * all platform-native dependency checks are treated as required. Pass\n * `{ backends }` to scope checks to only the backends you plan to use.\n *\n * @param options - Optional doctor options (e.g. `{ backends }` to scope checks).\n */\n static async doctor(options?: RunDoctorOptions): Promise<PreflightResult> {\n return runDoctor(options)\n }\n\n /**\n * The type identifier of the active backend — the first enabled backend in\n * the resolved configuration (the one `store()`, `delete()`, and `setup()`\n * operate on).\n *\n * @remarks\n * This is a pure, side-effect-free view of the resolved configuration: it\n * reads the type of the first enabled backend without instantiating the\n * backend or requiring it to be registered or healthy. Reading it therefore\n * never throws for an unavailable or unregistered backend — unlike a secret\n * operation — so it is safe to call purely to introspect an instance.\n *\n * When a backend was injected via `init({ backend })`, config-based\n * resolution is bypassed entirely and this reports the injected instance's\n * declared `type` (see {@link SecretBackend}) — or the stable sentinel\n * `'custom'` if it declares an empty type. It never throws in the injected\n * path.\n *\n * Use it to confirm which backend an instance resolved to, especially when\n * no config file exists and the safe zero-config default applies (see\n * {@link defaultBackendType}). With no config this reads `file` on every\n * platform, so secret operations never silently target the real OS\n * credential store; opt into the native store (see\n * {@link platformNativeBackendType}) via explicit config to change this.\n *\n * @throws A {@link BackendUnavailableError} only when the configuration has\n * no enabled backend at all (a configuration error, not a backend fault).\n * This can only happen in the config-driven path; an injected backend never\n * throws here.\n *\n * @public\n */\n get activeBackendType(): string {\n if (this.#backendInjected && this.#backend !== undefined) {\n // An injected backend wins over config resolution (see init()); report\n // its declared type, falling back to a stable sentinel if it declares none.\n return VaultKeeper.#resolveBackendTypeHint(this.#backend)\n }\n const firstEnabled = this.#config.backends.find((b) => b.enabled)\n if (firstEnabled === undefined) {\n throw new BackendUnavailableError(\n 'No enabled backends configured',\n 'none-enabled',\n this.#config.backends.map((b) => b.type),\n )\n }\n return firstEnabled.type\n }\n\n /**\n * Report the {@link BackendCapabilities} of the active backend's configured\n * instance — the same backend {@link VaultKeeper.store}, {@link VaultKeeper.setup},\n * and {@link VaultKeeper.sign} operate on.\n *\n * @remarks\n * Unlike the pure {@link VaultKeeper.activeBackendType} getter, this resolves\n * (instantiates) the backend, because capabilities are a property of the\n * configured instance, not of the type. The answer reflects configured/live\n * state — e.g. a YubiKey slot's touch policy or 1Password's access mode — and\n * a backend that does not implement {@link PresenceCapableBackend} reports the\n * safe default (`{ presencePerUse: false }`) via {@link getBackendCapabilities}.\n * Reading this never triggers a human-presence prompt.\n *\n * @returns The active backend instance's capabilities.\n * @throws A {@link BackendUnavailableError} if no backend is enabled or the\n * configured backend cannot be built.\n * @public\n */\n async getActiveBackendCapabilities(): Promise<BackendCapabilities> {\n const backend = this.#requireBackend()\n return getBackendCapabilities(backend)\n }\n\n /**\n * Store a secret in the configured backend.\n *\n * This is a convenience method that delegates to the active backend's\n * `store()` method. If a secret with the same name already exists, it is\n * overwritten.\n *\n * @param name - Identifier for the secret. Must not contain `':'` — that\n * character is reserved for the internal `signing-key:` namespace, so a\n * secret name can never collide with a signing key.\n * @param value - The secret value to store.\n * @param options - Optional {@link PresenceRequirementOptions}. When\n * `requirePresencePerUse` is set, the store is refused with a\n * {@link NotCapableError} before the backend is touched unless the active\n * backend forces a fresh per-use human action.\n * @throws {VaultError} If `name` is empty or contains `':'`.\n * @throws {@link NotCapableError} If `options.requirePresencePerUse` is set\n * and the active backend is not presence-per-use capable.\n * @public\n */\n async store(name: string, value: string, options?: PresenceRequirementOptions): Promise<void> {\n VaultKeeper.#validateName(name, 'secret')\n const backend = this.#requireBackend()\n await this.#enforcePresenceRequirement(backend, 'store', options?.requirePresencePerUse)\n await backend.store(name, value)\n }\n\n /**\n * Delete a secret from the configured backend.\n *\n * This is a convenience method that delegates to the active backend's\n * `delete()` method.\n *\n * @param name - Identifier for the secret to delete.\n * @param options - Optional {@link PresenceRequirementOptions}. When\n * `requirePresencePerUse` is set, the delete is refused with a\n * {@link NotCapableError} before the backend is touched unless the active\n * backend forces a fresh per-use human action.\n * @throws {@link NotCapableError} If `options.requirePresencePerUse` is set\n * and the active backend is not presence-per-use capable.\n * @public\n */\n async delete(name: string, options?: PresenceRequirementOptions): Promise<void> {\n // Permissive: a legacy secret whose name contains ':' must remain deletable.\n VaultKeeper.#validateName(name, 'secret', false)\n const backend = this.#requireBackend()\n await this.#enforcePresenceRequirement(backend, 'delete', options?.requirePresencePerUse)\n await backend.delete(name)\n }\n\n /**\n * Check whether a secret exists in the active backend, without retrieving\n * its value, minting a token, or touching the TOFU trust manifest.\n *\n * @remarks\n * This is a lightweight precondition check intended to run before any\n * interactive or trust-gating logic (e.g. `exec`'s caller-approval prompt),\n * so a nonexistent secret is reported immediately and unambiguously instead\n * of being masked by an unrelated approval failure — see issue #69.\n *\n * @param name - Identifier for the secret.\n * @returns `true` if the secret exists, `false` otherwise.\n * @public\n */\n async secretExists(name: string): Promise<boolean> {\n // Permissive: a legacy secret whose name contains ':' must remain checkable.\n VaultKeeper.#validateName(name, 'secret', false)\n const backend = this.#requireBackend()\n return backend.exists(name)\n }\n\n /**\n * Read a stored secret from the backend and mint a JWE token that encapsulates it.\n *\n * @remarks\n * `setup()` requires an explicit executable-trust decision — it has no\n * default and never silently skips verification. Pass `executablePath` (the\n * calling executable's real path) to run trust-on-first-use verification, or\n * `skipTrust: true` to deliberately skip it in development. The {@link SetupOptions}\n * type enforces this choice at compile time (exactly one, and the options\n * argument is required); {@link ExecutableTrustRequiredError} is the runtime\n * backstop for untyped callers.\n *\n * **Seeing a compile error here?** A bare `vault.setup('NAME')` or\n * `vault.setup('NAME', {})` fails to typecheck (e.g. TS2554 \"Expected 2\n * arguments, but got 1\" or TS2345 \"Argument … is not assignable\") precisely\n * because the mandatory trust choice is missing. The fix is to add **exactly\n * one** of `executablePath: '<path>'` (verify the caller — production) or\n * `skipTrust: true` (skip verification — development only). Supplying both\n * fails to typecheck for the same reason.\n *\n * @example\n * ```ts\n * // Production: bind the token to a STABLE executable so a swapped binary is\n * // rejected. Point executablePath at a released binary, or process.execPath\n * // to trust the Node runtime. Do NOT use process.argv[1] for a compiled entry\n * // point — its hash changes on every rebuild, so the next setup() after a\n * // recompile throws IdentityMismatchError (use setDevelopmentMode or\n * // skipTrust for a frequently-rebuilt local caller).\n * const jwe = await vault.setup('MY_API_KEY', { executablePath: '/usr/local/bin/my-tool' })\n *\n * // Local development: skip verification so rebuilds don't reject the caller.\n * const devJwe = await vault.setup('MY_API_KEY', { skipTrust: true })\n * ```\n *\n * @param secretName - Identifier for the secret. Must not contain `':'` (the\n * reserved `signing-key:` namespace separator).\n * @param options - Setup options; must carry exactly one of `executablePath`\n * or `skipTrust: true`\n * @returns Compact JWE string\n * @throws {VaultError} If `secretName` is empty or contains `':'`.\n * @throws {@link ExecutableTrustRequiredError} If neither `executablePath`\n * nor `skipTrust: true` is provided, if both are, or if `executablePath` is\n * the retired legacy `'dev'` opt-out sentinel (use `skipTrust: true`).\n * @throws {@link IdentityMismatchError} If `executablePath`'s current hash no\n * longer matches a previously approved value (TOFU conflict).\n * @throws {@link FilesystemError} If `executablePath` cannot be read or hashed\n * for verification, or the trust manifest cannot be read or written while\n * recording the executable.\n */\n async setup(secretName: string, options: SetupOptions): Promise<string> {\n VaultKeeper.#validateName(secretName, 'secret')\n const backend = this.#requireBackend()\n\n // Resolve (and validate) the executable-trust choice first — before reading\n // any option field or touching the backend — so a malformed call fails fast\n // without a secret read. This also guards the runtime backstop: an untyped\n // (plain-JavaScript) caller can pass `undefined` despite the required type,\n // and this call throws ExecutableTrustRequiredError instead of dereferencing\n // `undefined`. Past this point `options` is guaranteed present.\n //\n // This only *verifies* trust; a first-encounter (TOFU) or Sigstore hash is\n // staged, not written yet. The manifest write is deferred via\n // `commitExecutableTrust` until the whole operation succeeds below — see\n // issue #148 (a failed setup() must never durably pre-seed TOFU trust).\n const { exeIdentity, commit: commitExecutableTrust } =\n await this.#resolveExecutableIdentity(options)\n\n // Enforce a presence-per-use requirement before the backend secret read\n // below — an unsatisfiable requirement fails fast with a NotCapableError\n // without ever touching a credential/session. This runs after the trust\n // resolution above (which throws for a missing choice), so `options` is\n // guaranteed present here and no credential has been touched yet. The\n // operation is 'read' — setup reads the stored secret to mint a token.\n await this.#enforcePresenceRequirement(backend, 'read', options.requirePresencePerUse)\n\n const backendType = VaultKeeper.#resolveBackendTypeHint(backend, options.backendType)\n const ttlMinutes = options.ttlMinutes ?? this.#config.defaults.ttlMinutes\n const trustTier = options.trustTier ?? this.#config.defaults.trustTier\n const useLimit = options.useLimit ?? null\n\n const secretValue = await backend.retrieve(secretName)\n\n const now = Math.floor(Date.now() / 1000)\n const claims: VaultClaims = {\n jti: crypto.randomUUID(),\n exp: now + ttlMinutes * 60,\n iat: now,\n sub: secretName,\n exe: exeIdentity,\n use: useLimit,\n tid: trustTier,\n bkd: backendType,\n val: secretValue,\n ref: secretName,\n }\n\n const currentKey = this.#keyManager.getCurrentKey()\n const token = createToken(currentKey.key, claims, { kid: currentKey.id })\n\n // Only now that the secret was retrieved and the token minted does a\n // first-encounter (or Sigstore) trust decision become a durable manifest\n // write. A failure anywhere above (e.g. SecretNotFoundError) leaves the\n // trust manifest untouched.\n await commitExecutableTrust()\n\n return token\n }\n\n /**\n * Decrypt a JWE, validate claims, verify executable identity, and return\n * an opaque CapabilityToken.\n *\n * @param jwe - Compact JWE string from setup()\n * @returns Object containing an opaque {@link CapabilityToken} for use with\n * fetch/exec/getSecret, and a {@link VaultResponse} describing key status.\n * When the JWE was decrypted with a non-current key,\n * `vaultResponse.rotatedJwt` contains a re-encrypted JWE for the current key.\n */\n async authorize(jwe: string): Promise<{ token: CapabilityToken; vaultResponse: VaultResponse }> {\n const kid = extractKid(jwe)\n const { claims, keyStatus } = await this.#decryptWithKeyResolution(jwe, kid)\n\n // Validate claims (expiry, blocklist, usage)\n const jti = claims.jti\n const currentCount = usageCounts.get(jti) ?? 0\n validateClaims(claims, currentCount)\n\n // Only track usage for tokens with a finite use limit. Unlimited tokens\n // (claims.use === null) never need count checks, so tracking them would\n // waste memory and cause unnecessary evictions of limited-token entries.\n if (claims.use !== null) {\n const newCount = currentCount + 1\n usageCounts.set(jti, newCount)\n\n // Evict the oldest entry when the map exceeds its size cap to prevent\n // unbounded memory growth in long-running processes. Block the evicted\n // JTI so that it cannot be silently re-authorized with a reset count.\n if (usageCounts.size > USAGE_MAP_MAX_SIZE) {\n const oldest = usageCounts.keys().next().value\n if (oldest !== undefined) {\n usageCounts.delete(oldest)\n blockToken(oldest)\n }\n }\n }\n\n const token = createCapabilityToken(claims)\n\n const vaultResponse: VaultResponse = { keyStatus }\n if (keyStatus === 'previous') {\n // Re-encrypt with current key\n const currentKey = this.#keyManager.getCurrentKey()\n const rotatedJwt = await createToken(currentKey.key, claims, { kid: currentKey.id })\n vaultResponse.rotatedJwt = rotatedJwt\n }\n\n return { token, vaultResponse }\n }\n\n /**\n * Execute a delegated HTTP fetch, injecting secrets from the token(s).\n *\n * **Single token:** every `{{secret}}` placeholder in `request.url`,\n * `request.headers`, and `request.body` is replaced with the secret value.\n *\n * **Token map ({@link SecretTokenMap}):** every `{{secret:name}}` placeholder\n * is replaced with the secret from the corresponding named token.\n *\n * The raw secret is never exposed in the return value.\n *\n * @param token - A single `CapabilityToken` or a `SecretTokenMap` mapping\n * names to tokens obtained from `authorize()`.\n * @param request - The fetch request template with placeholders.\n * @returns The `Response` from the underlying `fetch()` call, together with\n * the vault metadata (`vaultResponse`).\n * @throws {AuthorizationDeniedError} If any token is invalid or was not\n * created by this vault instance.\n * @throws {VaultError} If a named placeholder references an unknown\n * secret name.\n * @throws {FetchError} If the URL is malformed or the underlying network\n * request fails.\n */\n async fetch(\n token: CapabilityToken | SecretTokenMap,\n request: FetchRequest,\n ): Promise<{ response: Response; vaultResponse: VaultResponse }> {\n const secrets = VaultKeeper.#resolveSecrets(token)\n const response = await delegatedFetch(secrets, request)\n return {\n response,\n vaultResponse: { keyStatus: 'current' },\n }\n }\n\n /**\n * Execute a delegated command, injecting secrets from the token(s).\n *\n * **Single token:** every `{{secret}}` placeholder in `request.env` values\n * is replaced with the secret value.\n *\n * **Token map ({@link SecretTokenMap}):** every `{{secret:name}}` placeholder\n * is replaced with the secret from the corresponding named token.\n *\n * Secret placeholders are not supported in `request.command` or\n * `request.args` — process arguments are visible to other processes via\n * `ps` and often collected in logs and telemetry.\n *\n * The raw secret is never exposed in the return value: by default the\n * captured `stdout`/`stderr` is scrubbed of every injected secret value\n * (replaced with `[REDACTED]`), so a command that echoes the secret does not\n * leak it back. Pass `request.redact = false` to receive raw, unredacted\n * output — only when a caller genuinely needs it, since that forfeits the\n * guarantee.\n *\n * @param token - A single `CapabilityToken` or a `SecretTokenMap` mapping\n * names to tokens obtained from `authorize()`.\n * @param request - The exec request template with placeholders. Set\n * `redact: false` to opt out of output redaction.\n * @returns The command result (`stdout`, `stderr`, `exitCode`) together with\n * the vault metadata (`vaultResponse`).\n * @throws {AuthorizationDeniedError} If any token is invalid or was not\n * created by this vault instance.\n * @throws {ExecError} If the command cannot be started (e.g. ENOENT),\n * a placeholder references an unknown secret name, or a secret\n * placeholder appears in the `command` or `args` field.\n */\n async exec(\n token: CapabilityToken | SecretTokenMap,\n request: ExecRequest,\n ): Promise<{ result: ExecResult; vaultResponse: VaultResponse }> {\n const secrets = VaultKeeper.#resolveSecrets(token)\n const result = await delegatedExec(secrets, request)\n return {\n result,\n vaultResponse: { keyStatus: 'current' },\n }\n }\n\n /**\n * Create a controlled-direct `SecretAccessor` from a capability token.\n *\n * The accessor wraps the secret in a single-use, auto-zeroing `Buffer`. The\n * secret is accessible only through the `read()` callback and is zeroed\n * immediately after the callback returns.\n *\n * @param token - A `CapabilityToken` obtained from `authorize()`.\n * @returns A `SecretAccessor` that can be read exactly once.\n * @throws {AuthorizationDeniedError} If `token` is invalid or was not created\n * by this vault instance, or if it is a signing-key token — a signing key\n * carries no secret and cannot be read through `getSecret()` (use `sign()`).\n */\n getSecret(token: CapabilityToken): SecretAccessor {\n const claims = validateCapabilityToken(token)\n // Defense in depth: a signing-key token carries no secret and must never be\n // read through the secret-access path.\n if (isSigningClaims(claims)) {\n throw new AuthorizationDeniedError(\n 'This capability token authorizes a signing key, not a secret — ' +\n 'it cannot be read with getSecret(). Use sign() instead.',\n )\n }\n return createSecretAccessor(claims.val)\n }\n\n /**\n * Enroll a new signing keypair under `name` in the active backend.\n *\n * The keypair is generated and stored entirely backend-side (see\n * {@link SigningBackend}); the private key never enters vault claims, a\n * capability token, or the caller's process. Signing keys occupy a namespace\n * distinct from secrets, so a signing key and a secret can share a name\n * without colliding, and a signing key can never be read as a secret.\n *\n * @param name - Caller-facing signing key name. Must not contain `':'` (the\n * `signing-key:` namespace separator).\n * @param algorithm - The JOSE signing algorithm (currently only `'EdDSA'`).\n * @returns The public half of the newly enrolled key.\n * @throws {SigningNotSupportedError} If the active backend cannot sign.\n * @throws {InvalidAlgorithmError} If `algorithm` is not supported.\n * @throws {SigningKeyAlreadyExistsError} If a signing key already exists under `name`.\n * @throws {VaultError} If `name` is empty or contains `':'`.\n * @public\n */\n async createSigningKey(name: string, algorithm: SigningAlgorithm): Promise<SigningPublicKey> {\n VaultKeeper.#validateName(name, 'signing key')\n const backend = this.#requireSigningBackend()\n const id = VaultKeeper.#signingKeyId(name)\n // The backend validates the algorithm (throws InvalidAlgorithmError) — it is\n // the authority on which algorithms it can generate keys for.\n await backend.generateSigningKey(id, algorithm)\n return backend.getPublicKey(id)\n }\n\n /**\n * Export the SPKI PEM public key for the signing key named `name`.\n *\n * @param name - Caller-facing signing key name. Must not contain `':'`.\n * @returns The public key material (SPKI PEM, algorithm, kid).\n * @throws {SigningNotSupportedError} If the active backend cannot sign.\n * @throws {SigningKeyNotFoundError} If no signing key exists under `name`.\n * @throws {VaultError} If `name` is empty or contains `':'`.\n * @public\n */\n async exportPublicKey(name: string): Promise<SigningPublicKey> {\n VaultKeeper.#validateName(name, 'signing key')\n const backend = this.#requireSigningBackend()\n return backend.getPublicKey(VaultKeeper.#signingKeyId(name))\n }\n\n /**\n * Mint a signing-key capability token for the key named `name`.\n *\n * The returned token carries only `{ kid, backendRef, keyType: 'signing-key' }`\n * — never any key material — and is accepted only by {@link VaultKeeper.sign}.\n * Passing it to `getSecret`/`fetch`/`exec` is rejected.\n *\n * @param name - Caller-facing signing key name. Must not contain `':'`.\n * @returns An opaque {@link CapabilityToken} usable with `sign()`.\n * @throws {SigningNotSupportedError} If the active backend cannot sign.\n * @throws {SigningKeyNotFoundError} If no signing key exists under `name`.\n * @throws {VaultError} If `name` is empty or contains `':'`.\n * @public\n */\n async authorizeSigningKey(name: string): Promise<CapabilityToken> {\n VaultKeeper.#validateName(name, 'signing key')\n const backend = this.#requireSigningBackend()\n const id = VaultKeeper.#signingKeyId(name)\n // getPublicKey validates the key exists (throws SigningKeyNotFoundError).\n const pub = await backend.getPublicKey(id)\n return createSigningCapabilityToken({ keyType: 'signing-key', kid: pub.kid, backendRef: id })\n }\n\n /**\n * Sign a caller-supplied payload with a signing-key capability token.\n *\n * The signature is produced backend-side via {@link SigningBackend.signWithKey}\n * — the private key never leaves the backend and never appears in the token,\n * the claims, or this process. The result is a detached-payload Compact JWS\n * (RFC 7515 §7.2.2 + RFC 7797 `b64:false`, `crit:[\"b64\"]`, `alg:EdDSA`) that\n * any standards-compliant JOSE library can verify given the payload and the\n * public key.\n *\n * @param token - A signing-key `CapabilityToken` from {@link VaultKeeper.authorizeSigningKey}.\n * @param request - The payload to sign.\n * @param options - Optional {@link PresenceRequirementOptions}. When\n * `requirePresencePerUse` is set, the signature is refused with a\n * {@link NotCapableError} before the backend is touched unless the active\n * backend forces a fresh per-use human action. When capable, a fresh\n * backend `signWithKey` round-trip is performed for this call — no cached\n * key material can satisfy it (the private key never leaves the backend).\n * @returns The detached compact JWS and vault metadata.\n * @throws {AuthorizationDeniedError} If `token` is invalid or is not a\n * signing-key token (e.g. an ordinary secret token).\n * @throws {SigningNotSupportedError} If the active backend cannot sign.\n * @throws {SigningKeyNotFoundError} If the referenced key no longer exists.\n * @throws {@link NotCapableError} If `options.requirePresencePerUse` is set\n * and the active backend is not presence-per-use capable.\n * @public\n */\n async sign(\n token: CapabilityToken,\n request: SignRequest,\n options?: PresenceRequirementOptions,\n ): Promise<{ result: SignResult; vaultResponse: VaultResponse }> {\n const claims = validateCapabilityToken(token)\n if (!isSigningClaims(claims)) {\n throw new AuthorizationDeniedError(\n 'sign() requires a signing-key capability token from authorizeSigningKey() — ' +\n 'an ordinary secret token cannot be used to sign.',\n )\n }\n const backend = this.#requireSigningBackend()\n await this.#enforcePresenceRequirement(backend, 'sign', options?.requirePresencePerUse)\n const jws = await createDetachedJws(claims.kid, request.payload, (data) =>\n backend.signWithKey(claims.backendRef, data),\n )\n return {\n result: { jws },\n vaultResponse: { keyStatus: 'current' },\n }\n }\n\n /**\n * Verify a detached-payload Compact JWS against a public key — fully offline.\n *\n * This is a static, asynchronous method: no VaultKeeper instance, backend,\n * config, or capability token is required, so it is safe to call in CI or any\n * context holding only public material.\n *\n * Returns `false` for a signature that does not verify — a tampered payload,\n * the wrong key, or a structurally malformed JWS. It throws\n * {@link InvalidKeyMaterialError} only when the public key itself is not\n * parseable (or a private key was supplied) — an operational fault distinct\n * from a bad signature.\n *\n * @param request - The detached payload, the JWS, and the SPKI PEM public key.\n * @returns `true` if the signature is valid, `false` otherwise.\n * @throws {InvalidKeyMaterialError} If `request.publicKey` is not parseable\n * SPKI public key material.\n * @public\n */\n static async verify(request: VerifyRequest): Promise<boolean> {\n return verifyDetachedJws(request)\n }\n\n /**\n * Resolve the active backend and assert it implements the signing contract.\n * @throws {SigningNotSupportedError} If the active backend cannot sign.\n */\n #requireSigningBackend(): SigningBackend {\n const backend = this.#requireBackend()\n if (!isSigningBackend(backend)) {\n throw new SigningNotSupportedError(\n `The active backend ('${backend.type}') does not implement the signing contract. ` +\n `The built-in '${BUILTIN_SIGNING_BACKENDS.join(\"', '\")}' backend does, and a custom ` +\n 'backend may implement SigningBackend.',\n backend.type,\n [...BUILTIN_SIGNING_BACKENDS],\n )\n }\n return backend\n }\n\n /**\n * Shared enforcement for a presence-per-use requirement, called at the top of\n * every backend-touching access path ({@link VaultKeeper.store},\n * {@link VaultKeeper.delete}, {@link VaultKeeper.setup}, {@link VaultKeeper.sign}).\n *\n * @remarks\n * This is the single, non-bypassable point of enforcement — deliberately not\n * duplicated per CLI command. When `require` is not `true` it is a no-op.\n * Otherwise it queries the backend's capabilities **fresh on every call**\n * (never cached across operations, so a prior satisfied call can never\n * satisfy a later one) and throws {@link NotCapableError} — before the caller\n * performs any credential/session/device operation — when the configured\n * instance does not advertise {@link BackendCapabilities.presencePerUse}, **or**\n * advertises it but does not force a fresh action for **this** `operation` (see\n * {@link BackendCapabilities.presenceEnforcedOperations}). The latter makes\n * enforcement operation-aware and fail-closed: e.g. 1Password `per-access`\n * forces presence for reads but not `store`/`delete`, so a flagged write is\n * refused here rather than silently passing through the cached session client.\n *\n * When the backend *is* capable for this operation, this returns and the\n * caller proceeds to the backend's ordinary operation, which by the meaning of\n * the capability forces a distinct fresh human action for this specific call.\n * The presence action itself (and any {@link PresenceDeclinedError}/\n * {@link PresenceTimeoutError}) therefore surfaces from that backend operation,\n * not from here — so two consecutive required-presence operations each drive\n * their own backend call and each demand their own fresh action.\n *\n * @throws {@link NotCapableError} If `require` is `true` and the backend either\n * is not presence-per-use capable or does not force presence for `operation`.\n */\n async #enforcePresenceRequirement(\n backend: SecretBackend,\n operation: PresenceOperation,\n require: boolean | undefined,\n ): Promise<void> {\n if (require !== true) {\n return\n }\n const capabilities = await getBackendCapabilities(backend)\n if (!capabilities.presencePerUse) {\n throw new NotCapableError(\n `This operation required presence-per-use, but the active backend ` +\n `('${backend.type}') cannot guarantee it. ${PRESENCE_PER_USE_QUALIFYING_BACKENDS}`,\n backend.type,\n 'presencePerUse',\n )\n }\n // Operation-aware, fail-closed: a capable instance that only forces presence\n // for some operations (an explicit `presenceEnforcedOperations` list) must\n // refuse a flagged operation it does not cover, rather than passing without a\n // fresh action. An omitted list means \"all keyed operations\" (a touch device).\n const enforced = capabilities.presenceEnforcedOperations\n if (enforced !== undefined && !enforced.includes(operation)) {\n throw new NotCapableError(\n `This '${operation}' operation required presence-per-use, but the active backend ` +\n `('${backend.type}') only enforces a fresh per-use action for ` +\n `[${enforced.join(', ')}] — not '${operation}'. ${PRESENCE_PER_USE_QUALIFYING_BACKENDS}`,\n backend.type,\n 'presencePerUse',\n )\n }\n }\n\n /** Map a caller-facing signing key name to its namespaced backend id. */\n static #signingKeyId(name: string): string {\n return `signing-key:${name}`\n }\n\n /**\n * Rotate the current encryption key.\n *\n * The previous key remains valid for decryption during the grace period\n * configured in `keyRotation.gracePeriodDays`. JWEs presented during the\n * grace period return a `rotatedJwt` in the `VaultResponse` so callers can\n * persist the updated token.\n *\n * @throws {RotationInProgressError} If a rotation is already in progress\n * (i.e. a previous key is still within its grace period).\n */\n async rotateKey(): Promise<void> {\n const gracePeriodMs = this.#config.keyRotation.gracePeriodDays * 24 * 60 * 60 * 1000\n // Throws RotationInProgressError synchronously if a prior rotation's grace\n // period is still active — including one persisted by an earlier process.\n this.#keyManager.rotateKey(gracePeriodMs)\n await this.#persistKeyState()\n }\n\n /**\n * Emergency key revocation — invalidates the previous key immediately.\n *\n * After revocation, any JWE that was encrypted with the revoked key will\n * be permanently unreadable. A new encryption key is generated automatically\n * so that `setup()` can be called immediately after revocation.\n */\n async revokeKey(): Promise<void> {\n this.#keyManager.revokeKey()\n await this.#persistKeyState()\n }\n\n /**\n * Persist the current key state to the config dir when persistence is\n * enabled. A no-op for injected-config/backend instances (in-memory keys).\n */\n async #persistKeyState(): Promise<void> {\n if (!this.#persistKeys) {\n return\n }\n await saveKeyState(this.#configDir, this.#keyManager.snapshot())\n }\n\n /**\n * Add or remove an executable from the development-mode whitelist.\n *\n * When an executable is in the development-mode list, identity verification\n * (TOFU hash checking) is skipped for that executable during `setup()`. This\n * is intended for local development workflows where the binary changes\n * frequently.\n *\n * @param executablePath - Absolute path to the executable to add or remove.\n * @param enabled - Pass `true` to add the executable to the list, `false`\n * to remove it.\n */\n async setDevelopmentMode(executablePath: string, enabled: boolean): Promise<void> {\n if (this.#config.developmentMode === undefined) {\n if (enabled) {\n this.#config.developmentMode = { executables: [executablePath] }\n }\n return\n }\n\n const exes = this.#config.developmentMode.executables\n const idx = exes.indexOf(executablePath)\n\n if (enabled && idx === -1) {\n exes.push(executablePath)\n } else if (!enabled && idx !== -1) {\n exes.splice(idx, 1)\n }\n\n await Promise.resolve()\n }\n\n /**\n * Approve an executable for trust-on-first-use by recording its current\n * SHA-256 hash in the trust manifest.\n *\n * After approval, {@link VaultKeeper.setup} and\n * {@link VaultKeeper.checkExecutableTrust} recognize the executable (matched\n * by its resolved absolute path and content hash) as trusted, so callers can\n * skip an interactive approval prompt.\n *\n * The operation is idempotent: approving the same, unchanged executable more\n * than once leaves a single manifest entry.\n *\n * @param executablePath - Path to the executable to approve. Resolved to an\n * absolute path before hashing and recording.\n * @returns The recorded trust status (always `trusted: true`).\n * @throws {FilesystemError} If the executable does not exist or cannot be read.\n * @public\n */\n async approveExecutable(executablePath: string): Promise<ExecutableTrustStatus> {\n const resolved = path.resolve(executablePath)\n const hash = await hashExecutable(resolved)\n const manifest = await loadManifest(this.#configDir)\n const updated = addTrustedHash(manifest, resolved, hash)\n await saveManifest(this.#configDir, updated)\n return {\n trusted: true,\n hash,\n hashMismatch: false,\n approvedHashes: updated.get(resolved)?.hashes ?? [hash],\n reason: 'Hash recorded in trust manifest',\n }\n }\n\n /**\n * Check whether an executable is trusted according to the trust manifest,\n * without modifying the manifest.\n *\n * This is a read-only probe. Unlike {@link VaultKeeper.setup}, it never\n * records a hash, so it can be used to decide whether an interactive approval\n * prompt is required before proceeding.\n *\n * @param executablePath - Path to the executable to check. Resolved to an\n * absolute path before hashing and lookup.\n * @returns The current trust status. `trusted` is `true` only when the\n * executable's current hash matches an approved manifest entry.\n * @throws {FilesystemError} If the executable does not exist or cannot be read.\n * @public\n */\n async checkExecutableTrust(executablePath: string): Promise<ExecutableTrustStatus> {\n const resolved = path.resolve(executablePath)\n const hash = await hashExecutable(resolved)\n const manifest = await loadManifest(this.#configDir)\n const approvedHashes = manifest.get(resolved)?.hashes ?? []\n\n if (isTrusted(manifest, resolved, hash)) {\n return {\n trusted: true,\n hash,\n hashMismatch: false,\n approvedHashes,\n reason: 'Hash found in trust manifest',\n }\n }\n\n const hashMismatch = approvedHashes.length > 0\n return {\n trusted: false,\n hash,\n hashMismatch,\n approvedHashes,\n reason: hashMismatch\n ? 'Executable hash changed from a previously approved value — re-approval required'\n : 'Executable not yet approved',\n }\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n static #resolveSecrets(token: CapabilityToken | SecretTokenMap): string | Record<string, string> {\n if (token instanceof CapabilityToken) {\n return VaultKeeper.#requireSecretClaims(token).val\n }\n const result: Record<string, string> = {}\n for (const [name, t] of Object.entries(token)) {\n if (!(t instanceof CapabilityToken)) {\n throw new AuthorizationDeniedError(\n `Invalid capability token for secret \"${name}\" — expected a CapabilityToken from authorize()`,\n )\n }\n result[name] = VaultKeeper.#requireSecretClaims(t).val\n }\n return result\n }\n\n /**\n * Resolve a token to its secret claims, rejecting a signing-key token.\n *\n * Defense in depth: a signing-key capability must never be injectable as a\n * secret through `fetch()`/`exec()`.\n */\n static #requireSecretClaims(token: CapabilityToken): VaultClaims {\n const claims = validateCapabilityToken(token)\n if (isSigningClaims(claims)) {\n throw new AuthorizationDeniedError(\n 'This capability token authorizes a signing key, not a secret — ' +\n 'it cannot be injected into fetch() or exec().',\n )\n }\n return claims\n }\n\n /**\n * Validate a caller-supplied resource name. `kind` names the resource in the\n * error so a signing-key caller is not told about a \"secret\".\n *\n * When `enforceReserved` is true (the default, used by name-creating/binding\n * paths — `store`/`setup` and every signing-key operation), the name may not\n * contain `':'`. The `signing-key:<name>` prefix is a reserved internal\n * namespace, so forbidding `':'` at creation time is what actually enforces\n * the documented guarantee that a secret and a signing key can never collide\n * under one name — the CLI's name pattern already forbids `':'`, and this\n * closes the same hole for direct library callers. Read/delete/existence\n * paths pass `false` so a legacy secret whose name contains `':'` (stored\n * before this rule, or seeded directly through a backend) stays reachable for\n * inspection and cleanup.\n */\n static #validateName(name: string, kind: 'secret' | 'signing key', enforceReserved = true): void {\n const noun = kind === 'secret' ? 'Secret' : 'Signing key'\n if (name.trim() === '') {\n throw new VaultError(`${noun} name must not be empty`)\n }\n if (enforceReserved && name.includes(':')) {\n throw new VaultError(\n `${noun} name must not contain ':'. The 'signing-key:' prefix is a reserved internal namespace, so a secret and a signing key can never collide under one name.`,\n )\n }\n }\n\n #resolveBackend(): SecretBackend {\n const enabledBackends = this.#config.backends.filter((b) => b.enabled)\n if (enabledBackends.length === 0) {\n throw new BackendUnavailableError(\n 'No enabled backends configured',\n 'none-enabled',\n this.#config.backends.map((b) => b.type),\n )\n }\n\n const firstEnabled = enabledBackends[0]\n if (firstEnabled === undefined) {\n throw new BackendUnavailableError('No enabled backends configured', 'none-enabled', [])\n }\n\n return BackendRegistry.create(firstEnabled.type, firstEnabled, this.#configDir)\n }\n\n /**\n * Resolve the backend-type hint used both for introspection\n * ({@link activeBackendType}) and for the `bkd` claim minted by\n * {@link setup}. A non-blank `override` wins (trimmed); an empty or\n * whitespace-only override is treated the same as no override, since\n * honoring it would mint a token with a blank `bkd` claim. Otherwise the\n * backend's declared `type` is used (trimmed), and a backend that declares\n * an empty or whitespace-only type — permitted for injected backends —\n * falls back to the stable `'custom'` sentinel. Centralizing this keeps\n * both paths in sync so no route ever mints a token with an empty `bkd`\n * claim (which {@link validateClaims} rejects, making the token unusable).\n */\n static #resolveBackendTypeHint(backend: SecretBackend, override?: string): string {\n const trimmedOverride = override?.trim()\n if (trimmedOverride !== undefined && trimmedOverride !== '') {\n return trimmedOverride\n }\n const declared = backend.type.trim()\n return declared === '' ? 'custom' : declared\n }\n\n #requireBackend(): SecretBackend {\n // Resolve the configured backend lazily on first use so that trust-only\n // operations never require a healthy/registered backend. #resolveBackend()\n // throws BackendUnavailableError if none is enabled or it cannot be built.\n this.#backend ??= this.#resolveBackend()\n return this.#backend\n }\n\n #isDevModeExecutable(executablePath: string): boolean {\n if (this.#config.developmentMode === undefined) {\n return false\n }\n return this.#config.developmentMode.executables.includes(executablePath)\n }\n\n /**\n * Resolve the executable identity to embed in a minted token, enforcing that\n * the caller made an explicit trust decision.\n *\n * Returns the sentinel `'dev'` (no executable binding) when trust is\n * deliberately skipped or the path is on the development-mode allowlist;\n * otherwise runs TOFU *verification only* and returns the verified hash\n * together with a `commit` callback. Verification never writes to the trust\n * manifest by itself — `commit` stages that write, and the caller\n * ({@link VaultKeeper.setup}) must invoke it only after the operation trust\n * was gating has actually succeeded. This is the fail-fast/defer-write split\n * from issue #148: shape validation (missing/conflicting/legacy-sentinel)\n * still throws immediately here, before any backend read, but a\n * first-encounter or Sigstore hash is not durably recorded until `commit`\n * runs.\n *\n * @throws {ExecutableTrustRequiredError} If neither `executablePath` nor\n * `skipTrust: true` is provided, if both are, or if `executablePath` is the\n * retired legacy `'dev'` opt-out sentinel.\n * @throws {IdentityMismatchError} On a TOFU hash conflict. Conflicts never\n * stage a manifest write regardless of whether `commit` is later called.\n */\n async #resolveExecutableIdentity(\n options: TrustChoiceInput | undefined,\n ): Promise<{ exeIdentity: string; commit: () => Promise<void> }> {\n const executablePath = options?.executablePath\n const skipTrust = options?.skipTrust === true\n const noCommit = (): Promise<void> => Promise.resolve()\n\n if (skipTrust && executablePath !== undefined) {\n throw new ExecutableTrustRequiredError(\n 'VaultKeeper.setup() received both options.executablePath and ' +\n 'options.skipTrust: true, which are mutually exclusive. Pass ' +\n 'options.executablePath to verify the calling executable, or ' +\n 'options.skipTrust: true to skip verification (development only) — not both.',\n 'conflicting-choice',\n )\n }\n\n if (skipTrust) {\n // Explicit, greppable development-only opt-out: no executable identity is\n // bound. See the security warning on SetupOptions.skipTrust.\n return { exeIdentity: 'dev', commit: noCommit }\n }\n\n if (executablePath === undefined) {\n throw new ExecutableTrustRequiredError(\n 'VaultKeeper.setup() requires an explicit executable-trust choice and ' +\n 'no longer defaults to skipping verification. Either pass ' +\n \"options.executablePath set to the calling executable's real path \" +\n '(runs trust-on-first-use verification), or set options.skipTrust: ' +\n 'true to deliberately skip verification (development only).',\n 'missing-choice',\n )\n }\n\n // Reject the retired legacy opt-out sentinel. Before explicit-trust,\n // options.executablePath: 'dev' was the documented way to skip verification;\n // it is no longer special and would otherwise be resolved as a real path\n // (<cwd>/dev), hashed, and fail with a confusing \"cannot read executable\"\n // FilesystemError. Point migrating callers at the dedicated opt-out instead.\n if (executablePath === 'dev') {\n throw new ExecutableTrustRequiredError(\n \"VaultKeeper.setup() no longer supports the legacy options.executablePath: 'dev' \" +\n 'sentinel for skipping trust verification. Set options.skipTrust: true to ' +\n 'deliberately skip verification (development only), or pass ' +\n \"options.executablePath set to the calling executable's real path to verify it.\",\n 'legacy-dev-sentinel',\n )\n }\n\n // A real path may still be exempted via the established development-mode\n // allowlist (setDevelopmentMode); otherwise run full TOFU verification.\n if (this.#isDevModeExecutable(executablePath)) {\n return { exeIdentity: 'dev', commit: noCommit }\n }\n\n // Resolve to an absolute path before verification so the manifest is keyed\n // consistently with approveExecutable() and checkExecutableTrust(), both of\n // which resolve. A relative path approved earlier (stored under its absolute\n // key) therefore matches here too.\n //\n // verifyTrustPending only *verifies* — a first-encounter or Sigstore hash\n // is staged on the returned value, not written. Committing it is deferred\n // to the caller (see #148).\n const pending = await verifyTrustPending(path.resolve(executablePath), {\n configDir: this.#configDir,\n })\n if (pending.tofuConflict) {\n // On a conflict the manifest holds at least one prior approved hash;\n // report the most recently approved one as the previous hash. Nothing\n // was staged for this conflict (verifyTrustPending never stages a write\n // on tofuConflict), so there is nothing to avoid committing here.\n const previousHash = pending.approvedHashes.at(-1) ?? pending.identity.hash\n throw new IdentityMismatchError(\n 'Executable hash changed — re-approval required',\n previousHash,\n pending.identity.hash,\n )\n }\n return { exeIdentity: pending.identity.hash, commit: () => commitTrust(pending) }\n }\n\n async #decryptWithKeyResolution(\n jwe: string,\n kid: string | undefined,\n ): Promise<{ claims: VaultClaims; keyStatus: 'current' | 'previous' }> {\n // Try to find key by kid\n if (kid !== undefined) {\n const key = this.#keyManager.findKeyById(kid)\n if (key !== undefined) {\n const claims = await decryptToken(key.key, jwe)\n const isCurrent = key.id === this.#keyManager.getCurrentKey().id\n return {\n claims,\n keyStatus: isCurrent ? 'current' : 'previous',\n }\n }\n // kid not found — key may have been revoked\n throw new KeyRevokedError(`Key ${kid} not found — may have been revoked`)\n }\n\n // No kid — try current key first, then previous\n try {\n const claims = await decryptToken(this.#keyManager.getCurrentKey().key, jwe)\n return { claims, keyStatus: 'current' }\n } catch {\n const previousKey = this.#keyManager.getPreviousKey()\n if (previousKey !== undefined) {\n const claims = await decryptToken(previousKey.key, jwe)\n return { claims, keyStatus: 'previous' }\n }\n throw new VaultError('Failed to decrypt JWE with any available key')\n }\n }\n}\n"]}