@attest-it/core 0.5.0 → 0.6.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/core-alpha.d.ts +1198 -531
- package/dist/core-beta.d.ts +1198 -531
- package/dist/core-public.d.ts +1198 -531
- package/dist/core-unstripped.d.ts +1198 -531
- package/dist/index.cjs +980 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +743 -1
- package/dist/index.d.ts +739 -1
- package/dist/index.js +945 -104
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/fingerprint.ts","../src/attestation.ts","../src/crypto/ed25519.ts","../src/verify.ts","../src/key-provider/filesystem-provider.ts","../src/key-provider/one-password-provider.ts","../src/key-provider/macos-keychain-provider.ts","../src/key-provider/registry.ts","../src/identity/config.ts","../src/authorization.ts","../src/seal/operations.ts","../src/seal/verification.ts","../src/index.ts"],"names":["parseYaml","path","crypto","resolve","hash","z","fs2","path2","os","sign","verify","generateKeyPair","fs3","path3","fs4","fs5","path4","execCommand","path5","os3","spawn","join","readFile","readFileSync","stringifyYaml","dirname","mkdirAsync","writeFile","mkdirSync","writeFileSync","ms","fs7"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Configuration loading and validation for attest-it.\n */\n\nimport { readFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { join, resolve } from 'node:path'\nimport ms from 'ms'\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\n\n/**\n * Zod schema for key provider configuration.\n */\nconst keyProviderOptionsSchema = z\n .object({\n privateKeyPath: z.string().optional(),\n account: z.string().optional(),\n vault: z.string().optional(),\n itemName: z.string().optional(),\n })\n .strict()\n\nconst keyProviderSchema = z\n .object({\n type: z.enum(['filesystem', '1password']).or(z.string()),\n options: keyProviderOptionsSchema.optional(),\n })\n .strict()\n\n/**\n * Zod schema for a team member configuration.\n */\nconst teamMemberSchema = z\n .object({\n name: z.string().min(1, 'Team member name cannot be empty'),\n email: z.string().email().optional(),\n github: z.string().min(1).optional(),\n publicKey: z.string().min(1, 'Public key is required'),\n })\n .strict()\n\n/**\n * Zod schema for fingerprint configuration.\n */\nconst fingerprintConfigSchema = z\n .object({\n paths: z\n .array(z.string().min(1, 'Path cannot be empty'))\n .min(1, 'At least one path is required'),\n exclude: z.array(z.string().min(1, 'Exclude pattern cannot be empty')).optional(),\n })\n .strict()\n\n/**\n * Zod schema for duration strings.\n * Validates and parses duration strings like \"30d\", \"7d\", \"24h\".\n */\nconst durationSchema = z.string().refine(\n (val) => {\n try {\n // Type assertion needed because ms has strict StringValue type\n // We validate the result is a positive number below\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument, @typescript-eslint/consistent-type-assertions\n const parsed = ms(val as any)\n return typeof parsed === 'number' && parsed > 0\n } catch {\n return false\n }\n },\n {\n message: 'Duration must be a valid duration string (e.g., \"30d\", \"7d\", \"24h\")',\n },\n)\n\n/**\n * Zod schema for a gate configuration.\n */\nconst gateSchema = z\n .object({\n name: z.string().min(1, 'Gate name cannot be empty'),\n description: z.string().min(1, 'Gate description cannot be empty'),\n authorizedSigners: z\n .array(z.string().min(1, 'Authorized signer slug cannot be empty'))\n .min(1, 'At least one authorized signer is required'),\n fingerprint: fingerprintConfigSchema,\n maxAge: durationSchema,\n })\n .strict()\n\n/**\n * Zod schema for settings with defaults applied.\n */\nconst settingsSchema = z\n .object({\n maxAgeDays: z.number().int().positive().default(30),\n publicKeyPath: z.string().default('.attest-it/pubkey.pem'),\n attestationsPath: z.string().default('.attest-it/attestations.json'),\n defaultCommand: z.string().optional(),\n keyProvider: keyProviderSchema.optional(),\n // Note: algorithm field was removed - RSA is the only supported algorithm\n })\n .passthrough()\n\n/**\n * Zod schema for a suite configuration.\n * Suites are CLI-layer extensions of gates with command execution capabilities.\n * For backward compatibility, suites can define their own fingerprint via packages/files/ignore.\n */\nconst suiteSchema = z\n .object({\n // Gate fields (if present, this suite references a gate)\n gate: z.string().optional(),\n // Legacy fingerprint definition (for backward compatibility)\n description: z.string().optional(),\n packages: z.array(z.string().min(1, 'Package path cannot be empty')).optional(),\n files: z.array(z.string().min(1, 'File path cannot be empty')).optional(),\n ignore: z.array(z.string().min(1, 'Ignore pattern cannot be empty')).optional(),\n // CLI-specific fields\n command: z.string().optional(),\n timeout: z.string().optional(),\n interactive: z.boolean().optional(),\n // Relationship fields\n invalidates: z.array(z.string().min(1, 'Invalidated suite name cannot be empty')).optional(),\n depends_on: z.array(z.string().min(1, 'Dependency suite name cannot be empty')).optional(),\n })\n .strict()\n .refine(\n (suite) => {\n // Either gate is specified, or packages is specified (for legacy compatibility)\n return suite.gate !== undefined || (suite.packages !== undefined && suite.packages.length > 0)\n },\n {\n message: 'Suite must either reference a gate or define packages for fingerprinting',\n },\n )\n\n/**\n * Zod schema for the full configuration file.\n */\nconst configSchema = z\n .object({\n version: z.literal(1),\n settings: settingsSchema.default({}),\n team: z.record(z.string(), teamMemberSchema).optional(),\n gates: z.record(z.string(), gateSchema).optional(),\n suites: z.record(z.string(), suiteSchema).refine((suites) => Object.keys(suites).length >= 1, {\n message: 'At least one suite must be defined',\n }),\n groups: z\n .record(z.string(), z.array(z.string().min(1, 'Suite name in group cannot be empty')))\n .optional(),\n })\n .strict()\n\n/**\n * Type inference from Zod schema (should match AttestItConfig).\n * This is the same as AttestItConfig but with defaults applied.\n * @public\n */\nexport type Config = z.infer<typeof configSchema>\n\n/**\n * Error thrown when configuration is invalid.\n * @public\n */\nexport class ConfigValidationError extends Error {\n constructor(\n message: string,\n public readonly issues: z.ZodIssue[],\n ) {\n super(message)\n this.name = 'ConfigValidationError'\n }\n}\n\n/**\n * Error thrown when configuration file cannot be found.\n * @public\n */\nexport class ConfigNotFoundError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ConfigNotFoundError'\n }\n}\n\n/**\n * Parse configuration content from a string.\n *\n * @param content - The configuration file content\n * @param format - The format of the content ('yaml' or 'json')\n * @returns Parsed and validated configuration\n * @throws {ConfigValidationError} If validation fails\n */\nfunction parseConfigContent(content: string, format: 'yaml' | 'json'): Config {\n let rawConfig: unknown\n\n try {\n if (format === 'yaml') {\n rawConfig = parseYaml(content)\n } else {\n rawConfig = JSON.parse(content)\n }\n } catch (error) {\n throw new ConfigValidationError(\n `Failed to parse ${format.toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`,\n [],\n )\n }\n\n const result = configSchema.safeParse(rawConfig)\n\n if (!result.success) {\n throw new ConfigValidationError(\n 'Configuration validation failed:\\n' +\n result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n'),\n result.error.issues,\n )\n }\n\n return result.data\n}\n\n/**\n * Determine the format of a config file from its extension.\n *\n * @param filePath - Path to the config file\n * @returns 'yaml' or 'json'\n */\nfunction getConfigFormat(filePath: string): 'yaml' | 'json' {\n const ext = filePath.toLowerCase()\n if (ext.endsWith('.yaml') || ext.endsWith('.yml')) {\n return 'yaml'\n }\n if (ext.endsWith('.json')) {\n return 'json'\n }\n // Default to yaml for extensionless files\n return 'yaml'\n}\n\n/**\n * Find the configuration file in default locations.\n *\n * Searches in this order:\n * 1. .attest-it/config.yaml\n * 2. .attest-it/config.yml\n * 3. .attest-it/config.json\n *\n * @param startDir - Directory to start searching from (defaults to cwd)\n * @returns Absolute path to the config file, or null if not found\n * @public\n */\nexport function findConfigPath(startDir: string = process.cwd()): string | null {\n const configDir = join(startDir, '.attest-it')\n const candidates = ['config.yaml', 'config.yml', 'config.json']\n\n for (const candidate of candidates) {\n const configPath = join(configDir, candidate)\n try {\n readFileSync(configPath, 'utf8')\n return configPath\n } catch {\n // File doesn't exist or can't be read, try next candidate\n continue\n }\n }\n\n return null\n}\n\n/**\n * Load and validate configuration from a file (async).\n *\n * @param configPath - Optional path to config file. If not provided, searches default locations.\n * @returns Validated configuration object\n * @throws {@link ConfigNotFoundError} If config file cannot be found\n * @throws {@link ConfigValidationError} If validation fails\n * @public\n */\nexport async function loadConfig(configPath?: string): Promise<Config> {\n const resolvedPath = configPath ?? findConfigPath()\n\n if (!resolvedPath) {\n throw new ConfigNotFoundError(\n 'Configuration file not found. Expected .attest-it/config.yaml, .attest-it/config.yml, or .attest-it/config.json',\n )\n }\n\n try {\n const content = await readFile(resolvedPath, 'utf8')\n const format = getConfigFormat(resolvedPath)\n return parseConfigContent(content, format)\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error\n }\n throw new ConfigNotFoundError(\n `Failed to read configuration file at ${resolvedPath}: ${String(error)}`,\n )\n }\n}\n\n/**\n * Load and validate configuration from a file (sync).\n *\n * @param configPath - Optional path to config file. If not provided, searches default locations.\n * @returns Validated configuration object\n * @throws {@link ConfigNotFoundError} If config file cannot be found\n * @throws {@link ConfigValidationError} If validation fails\n * @public\n */\nexport function loadConfigSync(configPath?: string): Config {\n const resolvedPath = configPath ?? findConfigPath()\n\n if (!resolvedPath) {\n throw new ConfigNotFoundError(\n 'Configuration file not found. Expected .attest-it/config.yaml, .attest-it/config.yml, or .attest-it/config.json',\n )\n }\n\n try {\n const content = readFileSync(resolvedPath, 'utf8')\n const format = getConfigFormat(resolvedPath)\n return parseConfigContent(content, format)\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error\n }\n throw new ConfigNotFoundError(\n `Failed to read configuration file at ${resolvedPath}: ${String(error)}`,\n )\n }\n}\n\n/**\n * Resolve relative paths in the configuration against the repository root.\n *\n * This converts relative paths in settings.publicKeyPath and settings.attestationsPath\n * to absolute paths relative to the repository root.\n *\n * @param config - The configuration object\n * @param repoRoot - Absolute path to the repository root\n * @returns Configuration with resolved absolute paths\n * @public\n */\nexport function resolveConfigPaths(config: Config, repoRoot: string): Config {\n return {\n ...config,\n settings: {\n ...config.settings,\n publicKeyPath: resolve(repoRoot, config.settings.publicKeyPath),\n attestationsPath: resolve(repoRoot, config.settings.attestationsPath),\n },\n }\n}\n\n/**\n * Convert Zod-validated Config to AttestItConfig by removing undefined values.\n *\n * The Config type (from Zod) has optional fields as `T | undefined`,\n * while AttestItConfig has optional fields as `T?` (can be absent, not undefined).\n *\n * This adapter removes any undefined values to match the AttestItConfig interface\n * that the core functions expect.\n *\n * @param config - The Zod-validated configuration from loadConfig()\n * @returns Configuration compatible with AttestItConfig\n * @public\n */\nexport function toAttestItConfig(config: Config): import('./types.js').AttestItConfig {\n const result: import('./types.js').AttestItConfig = {\n version: config.version,\n settings: {\n maxAgeDays: config.settings.maxAgeDays,\n publicKeyPath: config.settings.publicKeyPath,\n attestationsPath: config.settings.attestationsPath,\n },\n suites: {},\n }\n\n // Add optional settings fields\n if (config.settings.defaultCommand !== undefined) {\n result.settings.defaultCommand = config.settings.defaultCommand\n }\n if (config.settings.keyProvider !== undefined) {\n result.settings.keyProvider = {\n type: config.settings.keyProvider.type,\n ...(config.settings.keyProvider.options !== undefined && {\n options: config.settings.keyProvider.options,\n }),\n }\n }\n\n // Add optional top-level fields\n if (config.team !== undefined) {\n result.team = config.team\n }\n if (config.gates !== undefined) {\n result.gates = config.gates\n }\n if (config.groups !== undefined) {\n result.groups = config.groups\n }\n\n // Map suites\n result.suites = Object.fromEntries(\n Object.entries(config.suites).map(([name, suite]) => {\n const mappedSuite: import('./types.js').SuiteConfig = {}\n\n if (suite.gate !== undefined) mappedSuite.gate = suite.gate\n if (suite.packages !== undefined) mappedSuite.packages = suite.packages\n if (suite.description !== undefined) mappedSuite.description = suite.description\n if (suite.files !== undefined) mappedSuite.files = suite.files\n if (suite.ignore !== undefined) mappedSuite.ignore = suite.ignore\n if (suite.command !== undefined) mappedSuite.command = suite.command\n if (suite.timeout !== undefined) mappedSuite.timeout = suite.timeout\n if (suite.interactive !== undefined) mappedSuite.interactive = suite.interactive\n if (suite.invalidates !== undefined) mappedSuite.invalidates = suite.invalidates\n if (suite.depends_on !== undefined) mappedSuite.depends_on = suite.depends_on\n\n return [name, mappedSuite]\n }),\n )\n\n return result\n}\n","import * as crypto from 'node:crypto'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { glob, globSync } from 'tinyglobby'\n\n/**\n * Threshold for streaming large files instead of reading into memory.\n * Files larger than this will be hashed via streaming to avoid memory issues.\n */\nconst LARGE_FILE_THRESHOLD = 50 * 1024 * 1024 // 50MB\n\n/**\n * Options for computing a package fingerprint.\n * @public\n */\nexport interface FingerprintOptions {\n /** Package directories to include */\n packages: string[]\n /** Glob patterns to exclude from fingerprint */\n ignore?: string[]\n /** Base directory for resolving paths */\n baseDir?: string\n}\n\n/**\n * Result of computing a package fingerprint.\n * @public\n */\nexport interface FingerprintResult {\n /** The fingerprint in \"sha256:...\" format */\n fingerprint: string\n /** List of files included in fingerprint calculation */\n files: string[]\n /** Number of files processed */\n fileCount: number\n}\n\n/**\n * Internal representation of a file hash for fingerprint computation.\n */\ninterface FileHashInput {\n /** The normalized relative path of the file */\n relativePath: string\n /** The computed hash of the file content */\n hash: Buffer\n}\n\n/**\n * Sort files lexicographically (locale-independent).\n */\nfunction sortFiles(files: string[]): string[] {\n return [...files].sort((a, b) => {\n if (a < b) return -1\n if (a > b) return 1\n return 0\n })\n}\n\n/**\n * Normalize path separators to forward slashes.\n */\nfunction normalizePath(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\n/**\n * Compute final fingerprint from file hashes.\n */\nfunction computeFinalFingerprint(fileHashes: FileHashInput[]): string {\n // Sort by relative path\n const sorted = [...fileHashes].sort((a, b) => {\n if (a.relativePath < b.relativePath) return -1\n if (a.relativePath > b.relativePath) return 1\n return 0\n })\n\n // Concatenate all file hashes\n const hashes = sorted.map((input) => input.hash)\n const concatenated = Buffer.concat(hashes)\n\n // Compute final hash\n const finalHash = crypto.createHash('sha256').update(concatenated).digest()\n return `sha256:${finalHash.toString('hex')}`\n}\n\n/**\n * Hash a file's content using streaming for large files (async).\n * For files larger than LARGE_FILE_THRESHOLD, uses streaming to avoid memory issues.\n */\nasync function hashFileAsync(\n realPath: string,\n normalizedPath: string,\n stats: fs.Stats,\n): Promise<Buffer> {\n if (stats.size > LARGE_FILE_THRESHOLD) {\n // Stream large files to avoid memory issues\n return new Promise((resolve, reject) => {\n const hash = crypto.createHash('sha256')\n hash.update(normalizedPath)\n hash.update(':')\n\n const stream = fs.createReadStream(realPath)\n stream.on('data', (chunk: string | Buffer) => {\n hash.update(chunk)\n })\n stream.on('end', () => {\n resolve(hash.digest())\n })\n stream.on('error', reject)\n })\n }\n\n // Read small files into memory (faster than streaming)\n const content = await fs.promises.readFile(realPath)\n const hash = crypto.createHash('sha256')\n hash.update(normalizedPath)\n hash.update(':')\n hash.update(content)\n return hash.digest()\n}\n\n/**\n * Hash a file's content synchronously.\n * Note: Cannot stream synchronously, so large files are read into memory.\n */\nfunction hashFileSync(realPath: string, normalizedPath: string): Buffer {\n const content = fs.readFileSync(realPath)\n const hash = crypto.createHash('sha256')\n hash.update(normalizedPath)\n hash.update(':')\n hash.update(content)\n return hash.digest()\n}\n\n/**\n * Validate fingerprint options and return base directory.\n */\nfunction validateOptions(options: FingerprintOptions): string {\n if (options.packages.length === 0) {\n throw new Error('packages array must not be empty')\n }\n\n const baseDir = options.baseDir ?? process.cwd()\n\n // Verify all package paths exist\n for (const pkg of options.packages) {\n const pkgPath = path.resolve(baseDir, pkg)\n if (!fs.existsSync(pkgPath)) {\n throw new Error(`Package path does not exist: ${pkgPath}`)\n }\n }\n\n return baseDir\n}\n\n/**\n * Compute a deterministic fingerprint for a set of packages (async).\n *\n * Algorithm:\n * 1. List all files in packages (respecting ignore globs)\n * 2. Sort files lexicographically by relative path\n * 3. For each file: compute SHA256(relativePath + \":\" + content)\n * 4. Concatenate all file hashes in sorted order\n * 5. Compute final SHA256 of concatenated hashes\n * 6. Return \"sha256:\" + hex(fingerprint)\n *\n * @param options - Configuration for fingerprint computation\n * @returns Result containing the fingerprint hash and list of files processed\n * @throws Error if packages array is empty or if package paths don't exist\n * @public\n */\nexport async function computeFingerprint(options: FingerprintOptions): Promise<FingerprintResult> {\n const baseDir = validateOptions(options)\n\n // List all files in packages\n const files = await listPackageFiles(options.packages, options.ignore, baseDir)\n\n // Sort files lexicographically\n const sortedFiles = sortFiles(files)\n\n // Track visited files to handle multiple symlinks pointing to the same file\n // Key: realpath, Value: file hash\n const fileHashCache = new Map<string, Buffer>()\n\n // Compute individual file hashes\n const fileHashInputs: FileHashInput[] = []\n for (const file of sortedFiles) {\n const filePath = path.resolve(baseDir, file)\n\n // Handle symlinks\n let realPath = filePath\n let stats = await fs.promises.lstat(filePath)\n\n if (stats.isSymbolicLink()) {\n try {\n realPath = await fs.promises.realpath(filePath)\n } catch {\n // Skip broken symlinks\n continue\n }\n\n // Get stats of the target\n try {\n stats = await fs.promises.stat(realPath)\n } catch {\n // Skip broken symlinks\n continue\n }\n }\n\n // Skip if not a file (e.g., directories)\n if (!stats.isFile()) {\n continue\n }\n\n // Normalize path separators to forward slashes\n const normalizedPath = normalizePath(file)\n\n // Check if we've already hashed this file (via symlinks)\n let hash: Buffer\n const cachedHash = fileHashCache.get(realPath)\n if (cachedHash !== undefined) {\n // Reuse cached hash for files we've already seen (via symlinks)\n hash = cachedHash\n } else {\n // Hash the file content\n hash = await hashFileAsync(realPath, normalizedPath, stats)\n fileHashCache.set(realPath, hash)\n }\n\n fileHashInputs.push({ relativePath: normalizedPath, hash })\n }\n\n // Compute final fingerprint\n const fingerprint = computeFinalFingerprint(fileHashInputs)\n\n return {\n fingerprint,\n files: sortedFiles,\n fileCount: sortedFiles.length,\n }\n}\n\n/**\n * Compute a deterministic fingerprint for a set of packages (sync).\n *\n * @param options - Configuration for fingerprint computation\n * @returns Result containing the fingerprint hash and list of files processed\n * @throws Error if packages array is empty or if package paths don't exist\n * @public\n * @see {@link computeFingerprint} for the async version\n */\nexport function computeFingerprintSync(options: FingerprintOptions): FingerprintResult {\n const baseDir = validateOptions(options)\n\n // List all files in packages (sync version)\n const files = listPackageFilesSync(options.packages, options.ignore, baseDir)\n\n // Sort files lexicographically\n const sortedFiles = sortFiles(files)\n\n // Track visited files to handle multiple symlinks pointing to the same file\n // Key: realpath, Value: file hash\n const fileHashCache = new Map<string, Buffer>()\n\n // Compute individual file hashes\n const fileHashInputs: FileHashInput[] = []\n for (const file of sortedFiles) {\n const filePath = path.resolve(baseDir, file)\n\n // Handle symlinks\n let realPath = filePath\n let stats = fs.lstatSync(filePath)\n\n if (stats.isSymbolicLink()) {\n try {\n realPath = fs.realpathSync(filePath)\n } catch {\n // Skip broken symlinks\n continue\n }\n\n // Get stats of the target\n try {\n stats = fs.statSync(realPath)\n } catch {\n // Skip broken symlinks\n continue\n }\n }\n\n // Skip if not a file (e.g., directories)\n if (!stats.isFile()) {\n continue\n }\n\n // Normalize path separators to forward slashes\n const normalizedPath = normalizePath(file)\n\n // Check if we've already hashed this file (via symlinks)\n let hash: Buffer\n const cachedHash = fileHashCache.get(realPath)\n if (cachedHash !== undefined) {\n // Reuse cached hash for files we've already seen (via symlinks)\n hash = cachedHash\n } else {\n // Hash the file content (sync version cannot stream)\n hash = hashFileSync(realPath, normalizedPath)\n fileHashCache.set(realPath, hash)\n }\n\n fileHashInputs.push({ relativePath: normalizedPath, hash })\n }\n\n // Compute final fingerprint\n const fingerprint = computeFinalFingerprint(fileHashInputs)\n\n return {\n fingerprint,\n files: sortedFiles,\n fileCount: sortedFiles.length,\n }\n}\n\n/**\n * List files in packages, respecting ignore patterns (async).\n *\n * @param packages - Array of package directory paths\n * @param ignore - Optional glob patterns to exclude\n * @param baseDir - Base directory for resolving paths (defaults to cwd)\n * @returns Array of relative file paths\n * @public\n */\nexport async function listPackageFiles(\n packages: string[],\n ignore: string[] = [],\n baseDir: string = process.cwd(),\n): Promise<string[]> {\n const allFiles: string[] = []\n\n for (const pkg of packages) {\n // Build glob patterns for this package\n const patterns = [`${pkg}/**/*`]\n\n // Use tinyglobby to find files\n const files = await glob(patterns, {\n cwd: baseDir,\n ignore,\n onlyFiles: true,\n dot: true, // Include dotfiles\n absolute: false, // Return relative paths\n })\n\n allFiles.push(...files)\n }\n\n return allFiles\n}\n\n/**\n * Synchronous version of listPackageFiles\n */\nfunction listPackageFilesSync(\n packages: string[],\n ignore: string[] = [],\n baseDir: string = process.cwd(),\n): string[] {\n const allFiles: string[] = []\n\n for (const pkg of packages) {\n // Build glob patterns for this package\n const patterns = [`${pkg}/**/*`]\n\n // Use tinyglobby to find files (sync version)\n const files = globSync(patterns, {\n cwd: baseDir,\n ignore,\n onlyFiles: true,\n dot: true, // Include dotfiles\n absolute: false, // Return relative paths\n })\n\n allFiles.push(...files)\n }\n\n return allFiles\n}\n","/**\n * Attestation file I/O module with JSON canonicalization.\n */\n\nimport * as fs from 'node:fs'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport * as canonicalizeNamespace from 'canonicalize'\nimport { z } from 'zod'\nimport type { Attestation, AttestationsFile } from './types.js'\n\n/**\n * Extract the serialize function from the canonicalize CommonJS module.\n *\n * Context: The canonicalize package uses `module.exports = function(...)`, which is\n * a CommonJS pattern. With `esModuleInterop: false` (required for library code to\n * avoid leaking tsconfig options to consumers), TypeScript treats the namespace import\n * as the module object itself, not as an object with a default export.\n *\n * The package's type definitions declare `export default function serialize(...)`,\n * which TypeScript interprets as `{ default: function }` when esModuleInterop is off.\n * However, at runtime with NodeNext module resolution, the actual value is just the\n * function itself.\n *\n * This type assertion is safe because:\n * 1. We verified the runtime export structure of the canonicalize module\n * 2. The type matches the published @types signature\n * 3. This is the standard pattern for importing CommonJS modules in strict ESM\n */\n// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\nconst canonicalize = canonicalizeNamespace as unknown as {\n default: (input: unknown) => string | undefined\n}\nconst serialize = canonicalize.default\n\n// Zod schema for attestation validation\nconst attestationSchema = z.object({\n suite: z.string().min(1),\n fingerprint: z.string().regex(/^sha256:[a-f0-9]{64}$/),\n attestedAt: z.string().datetime(),\n attestedBy: z.string().min(1),\n command: z.string().min(1),\n exitCode: z.literal(0),\n})\n\nconst attestationsFileSchema = z.object({\n schemaVersion: z.literal('1'),\n attestations: z.array(attestationSchema),\n signature: z.string(), // Will be validated by crypto module\n})\n\n/**\n * Type guard to check if an error is a Node.js file system error with code.\n * We need to disable the type assertion rule here because TypeScript doesn't\n * provide a way to narrow an object type after checking for a property without\n * using type assertions or indexed access. This is a safe assertion because we\n * check for the property existence and type before using it.\n */\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n if (error === null || typeof error !== 'object') {\n return false\n }\n if (!('code' in error)) {\n return false\n }\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const errorObj = error as Record<string, unknown>\n return typeof errorObj.code === 'string'\n}\n\n/**\n * Read attestations file from disk (async).\n *\n * @param filePath - Absolute path to the attestations JSON file\n * @returns Parsed attestations file, or null if the file doesn't exist\n * @throws Error on parse or validation errors\n * @public\n */\nexport async function readAttestations(filePath: string): Promise<AttestationsFile | null> {\n try {\n const content = await fs.promises.readFile(filePath, 'utf-8')\n const parsed: unknown = JSON.parse(content)\n // Zod validates and returns the correct type\n return attestationsFileSchema.parse(parsed)\n } catch (error) {\n if (isNodeError(error) && error.code === 'ENOENT') {\n return null\n }\n throw error\n }\n}\n\n/**\n * Read attestations file from disk (sync).\n *\n * @param filePath - Absolute path to the attestations JSON file\n * @returns Parsed attestations file, or null if the file doesn't exist\n * @throws Error on parse or validation errors\n * @public\n */\nexport function readAttestationsSync(filePath: string): AttestationsFile | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8')\n const parsed: unknown = JSON.parse(content)\n // Zod validates and returns the correct type\n return attestationsFileSchema.parse(parsed)\n } catch (error) {\n if (isNodeError(error) && error.code === 'ENOENT') {\n return null\n }\n throw error\n }\n}\n\n/**\n * Write attestations file to disk (async).\n *\n * Creates parent directories if needed. The signature should be computed\n * separately and passed in.\n *\n * @param filePath - Absolute path to write the attestations file\n * @param attestations - Array of attestation entries\n * @param signature - Cryptographic signature of the attestations\n * @throws Error on validation or write errors\n * @public\n */\nexport async function writeAttestations(\n filePath: string,\n attestations: Attestation[],\n signature: string,\n): Promise<void> {\n const fileContent: AttestationsFile = {\n schemaVersion: '1',\n attestations,\n signature,\n }\n\n // Validate before writing\n attestationsFileSchema.parse(fileContent)\n\n // Create parent directories if needed\n const dir = path.dirname(filePath)\n await fs.promises.mkdir(dir, { recursive: true })\n\n // Write with pretty formatting for readability\n const json = JSON.stringify(fileContent, null, 2)\n await fs.promises.writeFile(filePath, json, 'utf-8')\n}\n\n/**\n * Write attestations file to disk (sync).\n *\n * Creates parent directories if needed. The signature should be computed\n * separately and passed in.\n *\n * @param filePath - Absolute path to write the attestations file\n * @param attestations - Array of attestation entries\n * @param signature - Cryptographic signature of the attestations\n * @throws Error on validation or write errors\n * @public\n */\nexport function writeAttestationsSync(\n filePath: string,\n attestations: Attestation[],\n signature: string,\n): void {\n const fileContent: AttestationsFile = {\n schemaVersion: '1',\n attestations,\n signature,\n }\n\n // Validate before writing\n attestationsFileSchema.parse(fileContent)\n\n // Create parent directories if needed\n const dir = path.dirname(filePath)\n fs.mkdirSync(dir, { recursive: true })\n\n // Write with pretty formatting for readability\n const json = JSON.stringify(fileContent, null, 2)\n fs.writeFileSync(filePath, json, 'utf-8')\n}\n\n/**\n * Find an attestation for a specific suite.\n *\n * @param attestations - Attestations file containing all attestations\n * @param suite - Name of the suite to find\n * @returns The attestation if found, undefined otherwise\n * @public\n */\nexport function findAttestation(\n attestations: AttestationsFile,\n suite: string,\n): Attestation | undefined {\n return attestations.attestations.find((a) => a.suite === suite)\n}\n\n/**\n * Add or update an attestation for a suite.\n *\n * This is an immutable operation that returns a new array.\n *\n * @param attestations - Current array of attestations\n * @param newAttestation - Attestation to add or update\n * @returns New attestations array with the upserted attestation\n * @throws Error if the new attestation fails validation\n * @public\n */\nexport function upsertAttestation(\n attestations: Attestation[],\n newAttestation: Attestation,\n): Attestation[] {\n // Validate the new attestation\n attestationSchema.parse(newAttestation)\n\n const existingIndex = attestations.findIndex((a) => a.suite === newAttestation.suite)\n\n if (existingIndex === -1) {\n // Add new attestation\n return [...attestations, newAttestation]\n } else {\n // Update existing attestation\n const updated = [...attestations]\n // eslint-disable-next-line security/detect-object-injection -- False positive: existingIndex is a safe number from findIndex\n updated[existingIndex] = newAttestation\n return updated\n }\n}\n\n/**\n * Remove attestations for a suite.\n *\n * This is an immutable operation that returns a new array.\n *\n * @param attestations - Current array of attestations\n * @param suite - Name of the suite to remove\n * @returns New attestations array without the specified suite\n * @public\n */\nexport function removeAttestation(attestations: Attestation[], suite: string): Attestation[] {\n return attestations.filter((a) => a.suite !== suite)\n}\n\n/**\n * Compute canonical JSON representation for signing.\n *\n * Implements RFC 8785 JSON Canonicalization Scheme. The canonicalize package provides:\n * 1. Keys sorted lexicographically (Unicode code point order)\n * 2. No whitespace between tokens\n * 3. No trailing commas\n * 4. Strings escaped using \\uXXXX for control characters\n * 5. Numbers: no leading zeros, no +, use lowercase 'e' for exponent\n * 6. UTF-8 encoding\n *\n * @param attestations - Array of attestations to canonicalize\n * @returns Canonical JSON string representation\n * @throws Error if canonicalization fails\n * @public\n */\nexport function canonicalizeAttestations(attestations: Attestation[]): string {\n const canonical = serialize(attestations)\n if (canonical === undefined) {\n throw new Error('Failed to canonicalize attestations')\n }\n return canonical\n}\n\n/**\n * Create a new attestation entry.\n *\n * @param params - Parameters for creating the attestation\n * @param params.suite - Name of the test suite\n * @param params.fingerprint - Fingerprint of the packages in sha256 format\n * @param params.command - Command that was executed\n * @param params.attestedBy - Optional username (defaults to current OS user)\n * @returns Validated attestation object\n * @throws Error if attestation validation fails\n * @public\n */\nexport function createAttestation(params: {\n suite: string\n fingerprint: string\n command: string\n attestedBy?: string\n}): Attestation {\n const attestation: Attestation = {\n suite: params.suite,\n fingerprint: params.fingerprint,\n attestedAt: new Date().toISOString(),\n attestedBy: params.attestedBy ?? os.userInfo().username,\n command: params.command,\n exitCode: 0,\n }\n\n // Validate before returning\n attestationSchema.parse(attestation)\n\n return attestation\n}\n\n/**\n * Options for writing signed attestations.\n * @public\n */\nexport interface WriteSignedAttestationsOptions {\n /** Path to write the attestations file */\n filePath: string\n /** Array of attestations to write */\n attestations: Attestation[]\n /** Path to the private key for signing (legacy) */\n privateKeyPath?: string\n /** Key provider for signing */\n keyProvider?: import('./key-provider/types.js').KeyProvider\n /** Key reference for the provider */\n keyRef?: string\n}\n\n/**\n * Options for reading and verifying signed attestations.\n * @public\n */\nexport interface ReadSignedAttestationsOptions {\n /** Path to read the attestations file from */\n filePath: string\n /** Path to the public key for verification */\n publicKeyPath: string\n}\n\n/**\n * Write attestations with a cryptographic signature.\n *\n * This function canonicalizes the attestations, signs them with the private key,\n * and writes the attestations file with the signature.\n *\n * @param options - Options for writing signed attestations\n * @throws Error if signing or writing fails\n * @public\n */\nexport async function writeSignedAttestations(\n options: WriteSignedAttestationsOptions,\n): Promise<void> {\n // Import sign function here to avoid circular dependency\n const { sign } = await import('./crypto.js')\n\n const { privateKeyPath, keyProvider, keyRef } = options\n\n // Validate that we have either legacy path or provider + ref\n if (!privateKeyPath && (!keyProvider || !keyRef)) {\n throw new Error(\n 'Either privateKeyPath or both keyProvider and keyRef must be provided for signing',\n )\n }\n\n const canonical = canonicalizeAttestations(options.attestations)\n\n // Build sign options, only including defined properties\n const signOptions: Parameters<typeof sign>[0] = {\n data: canonical,\n }\n\n if (privateKeyPath !== undefined) {\n signOptions.privateKeyPath = privateKeyPath\n }\n if (keyProvider !== undefined) {\n signOptions.keyProvider = keyProvider\n }\n if (keyRef !== undefined) {\n signOptions.keyRef = keyRef\n }\n\n const signature = await sign(signOptions)\n await writeAttestations(options.filePath, options.attestations, signature)\n}\n\n/**\n * Read attestations and verify the signature.\n *\n * This function reads the attestations file, canonicalizes the attestations,\n * and verifies the signature using the public key. It throws an error if the\n * file doesn't exist or if signature verification fails.\n *\n * @param options - Options for reading and verifying attestations\n * @returns The attestations file if signature is valid\n * @throws Error if attestations file not found\n * @throws SignatureInvalidError if signature verification fails\n * @public\n */\nexport async function readAndVerifyAttestations(\n options: ReadSignedAttestationsOptions,\n): Promise<AttestationsFile> {\n // Import verify function here to avoid circular dependency\n const { verify } = await import('./crypto.js')\n\n const file = await readAttestations(options.filePath)\n if (!file) {\n throw new Error(`Attestations file not found: ${options.filePath}`)\n }\n\n const canonical = canonicalizeAttestations(file.attestations)\n const isValid = await verify({\n publicKeyPath: options.publicKeyPath,\n data: canonical,\n signature: file.signature,\n })\n\n if (!isValid) {\n throw new SignatureInvalidError(options.filePath)\n }\n\n return file\n}\n\n/**\n * Error thrown when signature verification fails.\n * @public\n */\nexport class SignatureInvalidError extends Error {\n /**\n * Create a new SignatureInvalidError.\n * @param filePath - Path to the file that failed verification\n */\n constructor(filePath: string) {\n super(`Signature verification failed for: ${filePath}`)\n this.name = 'SignatureInvalidError'\n }\n}\n","/**\n * Ed25519 cryptographic operations using Node.js native crypto module.\n *\n * @remarks\n * This module provides Ed25519 digital signature operations using Node.js\n * native crypto support (available in Node 18+). Ed25519 offers better security\n * and performance than RSA-2048 with much smaller key and signature sizes.\n *\n * @packageDocumentation\n */\n\nimport * as crypto from 'node:crypto'\n\n/**\n * An Ed25519 keypair with base64-encoded public key and PEM-encoded private key.\n * @public\n */\nexport interface KeyPair {\n /** Base64-encoded public key (raw 32 bytes, ~44 characters) */\n publicKey: string\n /** PEM-encoded private key */\n privateKey: string\n}\n\n/**\n * Type guard to check if a value is a Buffer.\n * @param value - Value to check\n * @returns true if value is a Buffer\n * @internal\n */\nfunction isBuffer(value: unknown): value is Buffer {\n return Buffer.isBuffer(value)\n}\n\n/**\n * Generate a new Ed25519 keypair.\n *\n * @returns A keypair with base64-encoded public key and PEM-encoded private key\n * @throws Error if key generation fails\n * @public\n */\nexport function generateKeyPair(): KeyPair {\n try {\n // Generate Ed25519 keypair using Node.js native crypto\n // When format is 'pem', the keys are returned as strings\n const keyPair = crypto.generateKeyPairSync('ed25519', {\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n },\n })\n\n const { publicKey, privateKey } = keyPair\n if (typeof publicKey !== 'string' || typeof privateKey !== 'string') {\n throw new Error('Expected keypair to have string keys')\n }\n\n // Extract raw public key bytes and encode as base64\n const publicKeyObj = crypto.createPublicKey(publicKey)\n const publicKeyExport = publicKeyObj.export({\n type: 'spki',\n format: 'der',\n })\n\n if (!isBuffer(publicKeyExport)) {\n throw new Error('Expected public key export to be a Buffer')\n }\n\n // Ed25519 SPKI format: 12-byte header + 32-byte key\n // We extract just the 32-byte raw key for compact storage\n const rawPublicKey = publicKeyExport.subarray(12)\n const publicKeyBase64 = rawPublicKey.toString('base64')\n\n return {\n publicKey: publicKeyBase64,\n privateKey,\n }\n } catch (err) {\n throw new Error(\n `Failed to generate Ed25519 keypair: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Sign data with an Ed25519 private key.\n *\n * @param data - Data to sign (Buffer or UTF-8 string)\n * @param privateKeyPem - PEM-encoded private key\n * @returns Base64-encoded signature\n * @throws Error if signing fails\n * @public\n */\nexport function sign(data: Buffer | string, privateKeyPem: string): string {\n try {\n // Convert string data to Buffer\n const dataBuffer = typeof data === 'string' ? Buffer.from(data, 'utf8') : data\n\n // Create private key object\n const privateKeyObj = crypto.createPrivateKey(privateKeyPem)\n\n // Sign the data (null algorithm parameter for Ed25519)\n const signatureResult = crypto.sign(null, dataBuffer, privateKeyObj)\n\n if (!isBuffer(signatureResult)) {\n throw new Error('Expected signature to be a Buffer')\n }\n\n return signatureResult.toString('base64')\n } catch (err) {\n throw new Error(\n `Failed to sign data with Ed25519: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Verify an Ed25519 signature.\n *\n * @param data - Original data that was signed\n * @param signature - Base64-encoded signature to verify\n * @param publicKeyBase64 - Base64-encoded public key (raw 32 bytes)\n * @returns true if signature is valid, false otherwise\n * @throws Error if verification fails (not just invalid signature)\n * @public\n */\nexport function verify(data: Buffer | string, signature: string, publicKeyBase64: string): boolean {\n try {\n // Convert string data to Buffer\n const dataBuffer = typeof data === 'string' ? Buffer.from(data, 'utf8') : data\n\n // Decode signature from base64\n const signatureBuffer = Buffer.from(signature, 'base64')\n\n // Reconstruct SPKI format from raw public key\n // Ed25519 SPKI: 12-byte header + 32-byte key\n const rawPublicKey = Buffer.from(publicKeyBase64, 'base64')\n\n if (rawPublicKey.length !== 32) {\n throw new Error(\n `Invalid Ed25519 public key length: expected 32 bytes, got ${rawPublicKey.length.toString()}`,\n )\n }\n\n // SPKI header for Ed25519 (algorithm OID)\n const spkiHeader = Buffer.from([\n 0x30,\n 0x2a, // SEQUENCE, 42 bytes\n 0x30,\n 0x05, // SEQUENCE, 5 bytes\n 0x06,\n 0x03,\n 0x2b,\n 0x65,\n 0x70, // OID 1.3.101.112 (Ed25519)\n 0x03,\n 0x21,\n 0x00, // BIT STRING, 33 bytes (32 key + 1 padding)\n ])\n\n const spkiBuffer = Buffer.concat([spkiHeader, rawPublicKey])\n\n // Create public key object from SPKI\n const publicKeyObj = crypto.createPublicKey({\n key: spkiBuffer,\n format: 'der',\n type: 'spki',\n })\n\n // Verify the signature (null algorithm parameter for Ed25519)\n return crypto.verify(null, dataBuffer, publicKeyObj, signatureBuffer)\n } catch (err) {\n // If it's a verification failure (wrong signature), return false\n // If it's any other error, throw it\n if (err instanceof Error && err.message.includes('verification failed')) {\n return false\n }\n throw new Error(\n `Failed to verify Ed25519 signature: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Extract the public key from an Ed25519 private key.\n *\n * @param privateKeyPem - PEM-encoded private key\n * @returns Base64-encoded public key (raw 32 bytes)\n * @throws Error if extraction fails\n * @public\n */\nexport function getPublicKeyFromPrivate(privateKeyPem: string): string {\n try {\n // Create private key object\n const privateKeyObj = crypto.createPrivateKey(privateKeyPem)\n\n // Export the corresponding public key\n const publicKeyObj = crypto.createPublicKey(privateKeyObj)\n const publicKeyExport = publicKeyObj.export({\n type: 'spki',\n format: 'der',\n })\n\n if (!isBuffer(publicKeyExport)) {\n throw new Error('Expected public key export to be a Buffer')\n }\n\n // Extract raw 32-byte public key from SPKI format\n const rawPublicKey = publicKeyExport.subarray(12)\n return rawPublicKey.toString('base64')\n } catch (err) {\n throw new Error(\n `Failed to extract public key from Ed25519 private key: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n","/**\n * Verification logic for attestations.\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type {\n AttestItConfig,\n Attestation,\n AttestationsFile,\n SuiteVerificationResult,\n} from './types.js'\nimport { computeFingerprint } from './fingerprint.js'\nimport { readAndVerifyAttestations, SignatureInvalidError } from './attestation.js'\n\n/**\n * Options for verifying attestations.\n * @public\n */\nexport interface VerifyOptions {\n /** Configuration object */\n config: AttestItConfig\n /** Repository root directory (defaults to process.cwd()) */\n repoRoot?: string\n}\n\n/**\n * Result of verifying all attestations.\n * @public\n */\nexport interface VerifyResult {\n /** Overall success - true if all attestations are valid */\n success: boolean\n /** Whether the attestations file signature is valid */\n signatureValid: boolean\n /** Verification results for each suite */\n suites: SuiteVerificationResult[]\n /** Error messages encountered during verification */\n errors: string[]\n}\n\n/**\n * Verify all attestations against current code state.\n *\n * Verification algorithm:\n * 1. Load and verify attestations file signature\n * 2. For each suite in config:\n * a. Compute current fingerprint\n * b. Find matching attestation\n * c. Compare fingerprints\n * d. Check age\n * 3. Check invalidation chains\n * 4. Return aggregated results\n *\n * @param options - Verification options\n * @returns Verification result with status for each suite\n * @public\n */\nexport async function verifyAttestations(options: VerifyOptions): Promise<VerifyResult> {\n const { config, repoRoot = process.cwd() } = options\n const errors: string[] = []\n const suiteResults: SuiteVerificationResult[] = []\n let signatureValid = true\n let attestationsFile: AttestationsFile | null = null\n\n // Resolve paths\n const attestationsPath = resolvePath(config.settings.attestationsPath, repoRoot)\n const publicKeyPath = resolvePath(config.settings.publicKeyPath, repoRoot)\n\n // Step 1: Load and verify attestations\n try {\n if (!fs.existsSync(attestationsPath)) {\n // No attestations file - all suites need attestation\n attestationsFile = null\n } else if (!fs.existsSync(publicKeyPath)) {\n errors.push(`Public key not found: ${publicKeyPath}`)\n signatureValid = false\n } else {\n attestationsFile = await readAndVerifyAttestations({\n filePath: attestationsPath,\n publicKeyPath,\n })\n }\n } catch (err) {\n if (err instanceof SignatureInvalidError) {\n signatureValid = false\n errors.push(err.message)\n } else if (err instanceof Error) {\n errors.push(err.message)\n }\n }\n\n const attestations = attestationsFile?.attestations ?? []\n\n // Step 2: Check each suite\n for (const [suiteName, suiteConfig] of Object.entries(config.suites)) {\n const result = await verifySuite({\n suiteName,\n suiteConfig,\n attestations,\n maxAgeDays: config.settings.maxAgeDays,\n repoRoot,\n })\n suiteResults.push(result)\n }\n\n // Step 3: Check invalidation chains\n checkInvalidationChains(config, suiteResults)\n\n // Step 4: Aggregate results\n const allValid =\n signatureValid && suiteResults.every((r) => r.status === 'VALID') && errors.length === 0\n\n return {\n success: allValid,\n signatureValid,\n suites: suiteResults,\n errors,\n }\n}\n\n/**\n * Options for verifying a single suite.\n * @internal\n */\ninterface VerifySuiteOptions {\n /** Name of the suite */\n suiteName: string\n /** Suite configuration */\n suiteConfig: { packages?: string[]; ignore?: string[] }\n /** All attestations from the attestations file */\n attestations: Attestation[]\n /** Maximum age in days before attestation expires */\n maxAgeDays: number\n /** Repository root directory */\n repoRoot: string\n}\n\n/**\n * Verify a single suite's attestation.\n * @internal\n */\nasync function verifySuite(options: VerifySuiteOptions): Promise<SuiteVerificationResult> {\n const { suiteName, suiteConfig, attestations, maxAgeDays, repoRoot } = options\n\n // Validate that packages is defined (required for legacy verification)\n // Note: For gate-based verification, use the seal system functions instead\n if (!suiteConfig.packages || suiteConfig.packages.length === 0) {\n return {\n suite: suiteName,\n status: 'NEEDS_ATTESTATION',\n fingerprint: '',\n message: 'Suite configuration missing packages field',\n }\n }\n\n // Compute current fingerprint\n const fingerprintOptions = {\n packages: suiteConfig.packages.map((p) => resolvePath(p, repoRoot)),\n baseDir: repoRoot,\n ...(suiteConfig.ignore && { ignore: suiteConfig.ignore }),\n }\n const fingerprintResult = await computeFingerprint(fingerprintOptions)\n\n // Find attestation for this suite\n const attestation = attestations.find((a) => a.suite === suiteName)\n\n // No attestation found\n if (!attestation) {\n return {\n suite: suiteName,\n status: 'NEEDS_ATTESTATION',\n fingerprint: fingerprintResult.fingerprint,\n message: 'No attestation found for this suite',\n }\n }\n\n // Check fingerprint\n if (attestation.fingerprint !== fingerprintResult.fingerprint) {\n return {\n suite: suiteName,\n status: 'FINGERPRINT_CHANGED',\n fingerprint: fingerprintResult.fingerprint,\n attestation,\n message: `Fingerprint changed from ${attestation.fingerprint.slice(0, 20)}... to ${fingerprintResult.fingerprint.slice(0, 20)}...`,\n }\n }\n\n // Check age\n const attestedAt = new Date(attestation.attestedAt)\n const ageMs = Date.now() - attestedAt.getTime()\n const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24))\n\n if (ageDays > maxAgeDays) {\n return {\n suite: suiteName,\n status: 'EXPIRED',\n fingerprint: fingerprintResult.fingerprint,\n attestation,\n age: ageDays,\n message: `Attestation expired (${String(ageDays)} days old, max ${String(maxAgeDays)} days)`,\n }\n }\n\n // All checks passed\n return {\n suite: suiteName,\n status: 'VALID',\n fingerprint: fingerprintResult.fingerprint,\n attestation,\n age: ageDays,\n }\n}\n\n/**\n * Check invalidation chains.\n *\n * If suite A invalidates suite B, and A's attestation is newer than B's,\n * then B should be marked as INVALIDATED_BY_PARENT.\n *\n * @param config - Full configuration\n * @param results - Array of suite verification results to mutate\n * @internal\n */\nfunction checkInvalidationChains(config: AttestItConfig, results: SuiteVerificationResult[]): void {\n for (const [parentName, parentConfig] of Object.entries(config.suites)) {\n const invalidates = parentConfig.invalidates ?? []\n const parentResult = results.find((r) => r.suite === parentName)\n\n if (!parentResult?.attestation) continue\n\n const parentTime = new Date(parentResult.attestation.attestedAt).getTime()\n\n for (const childName of invalidates) {\n const childResult = results.find((r) => r.suite === childName)\n if (!childResult?.attestation) continue\n\n const childTime = new Date(childResult.attestation.attestedAt).getTime()\n\n // If parent was attested AFTER child, child is invalidated\n if (parentTime > childTime && childResult.status === 'VALID') {\n childResult.status = 'INVALIDATED_BY_PARENT'\n childResult.message = `Invalidated by ${parentName} (attested later)`\n }\n }\n }\n}\n\n/**\n * Resolve a path relative to a base directory.\n * @param relativePath - Path that may be relative or absolute\n * @param baseDir - Base directory for resolving relative paths\n * @returns Absolute path\n * @internal\n */\nfunction resolvePath(relativePath: string, baseDir: string): string {\n if (path.isAbsolute(relativePath)) {\n return relativePath\n }\n return path.join(baseDir, relativePath)\n}\n","/**\n * Filesystem-based key provider implementation.\n *\n * @remarks\n * This provider stores private keys on the local filesystem, maintaining\n * backward compatibility with the existing attest-it key storage behavior.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs/promises'\nimport { generateKeyPair as cryptoGenerateKeyPair, getDefaultPrivateKeyPath } from '../crypto.js'\nimport type {\n KeyProvider,\n KeyProviderConfig,\n KeyRetrievalResult,\n KeyGenerationResult,\n KeygenProviderOptions,\n} from './types.js'\n\n/**\n * Options for creating a FilesystemKeyProvider.\n * @public\n */\nexport interface FilesystemKeyProviderOptions {\n /** Path to the private key file (defaults to OS-specific config dir) */\n privateKeyPath?: string\n}\n\n/**\n * Key provider that stores private keys on the filesystem.\n *\n * @remarks\n * This is the default provider and maintains backward compatibility with\n * existing attest-it installations. Private keys are stored at:\n * - macOS/Linux: ~/.config/attest-it/private.pem\n * - Windows: %APPDATA%\\attest-it\\private.pem\n *\n * @public\n */\nexport class FilesystemKeyProvider implements KeyProvider {\n readonly type = 'filesystem'\n readonly displayName = 'Filesystem'\n\n private readonly privateKeyPath: string\n\n /**\n * Create a new FilesystemKeyProvider.\n * @param options - Provider options\n */\n constructor(options: FilesystemKeyProviderOptions = {}) {\n this.privateKeyPath = options.privateKeyPath ?? getDefaultPrivateKeyPath()\n }\n\n /**\n * Check if this provider is available.\n * Filesystem provider is always available.\n */\n async isAvailable(): Promise<boolean> {\n // Filesystem provider is always available\n return Promise.resolve(true)\n }\n\n /**\n * Check if a key exists at the given path.\n * @param keyRef - Path to the private key file\n */\n async keyExists(keyRef: string): Promise<boolean> {\n try {\n await fs.access(keyRef)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the private key path for signing.\n * Returns the path directly with a no-op cleanup function.\n * @param keyRef - Path to the private key file\n */\n async getPrivateKey(keyRef: string): Promise<KeyRetrievalResult> {\n // Verify the key exists\n if (!(await this.keyExists(keyRef))) {\n throw new Error(`Private key not found: ${keyRef}`)\n }\n\n return {\n keyPath: keyRef,\n // No-op cleanup for filesystem provider\n cleanup: async () => {\n // Nothing to clean up - key stays on filesystem\n },\n }\n }\n\n /**\n * Generate a new keypair and store on filesystem.\n * @param options - Key generation options\n */\n async generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult> {\n const { publicKeyPath, force = false } = options\n\n // Delegate to existing crypto module function\n const result = await cryptoGenerateKeyPair({\n privatePath: this.privateKeyPath,\n publicPath: publicKeyPath,\n force,\n })\n\n return {\n privateKeyRef: result.privatePath,\n publicKeyPath: result.publicPath,\n storageDescription: `Filesystem: ${result.privatePath}`,\n }\n }\n\n /**\n * Get the configuration for this provider.\n */\n getConfig(): KeyProviderConfig {\n return {\n type: this.type,\n options: {\n privateKeyPath: this.privateKeyPath,\n },\n }\n }\n}\n","/**\n * 1Password-based key provider implementation.\n *\n * @remarks\n * This provider stores private keys in 1Password and retrieves them via the\n * `op` CLI tool. Keys are downloaded to a temporary file for signing and\n * securely deleted after use.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { generateKeyPair as cryptoGenerateKeyPair, setKeyPermissions } from '../crypto.js'\nimport type {\n KeyProvider,\n KeyProviderConfig,\n KeyRetrievalResult,\n KeyGenerationResult,\n KeygenProviderOptions,\n} from './types.js'\n\n/**\n * Options for creating a OnePasswordKeyProvider.\n * @public\n */\nexport interface OnePasswordKeyProviderOptions {\n /** 1Password account email (optional if only one account) */\n account?: string\n /** Vault name or ID where the key is stored */\n vault: string\n /** Item name in 1Password */\n itemName: string\n}\n\n/**\n * Information about a 1Password account.\n * @public\n */\nexport interface OnePasswordAccount {\n /** Account UUID */\n account_uuid: string\n /** User email address */\n email: string\n /** Account URL */\n url: string\n /** User UUID */\n user_uuid: string\n}\n\n/**\n * Information about a 1Password vault.\n * @public\n */\nexport interface OnePasswordVault {\n /** Vault UUID */\n id: string\n /** Vault name */\n name: string\n}\n\n/**\n * Key provider that stores private keys in 1Password.\n *\n * @remarks\n * This provider requires the `op` CLI tool to be installed and authenticated.\n * Private keys are stored as documents in 1Password and downloaded to\n * temporary files for signing operations.\n *\n * @public\n */\nexport class OnePasswordKeyProvider implements KeyProvider {\n readonly type = '1password'\n readonly displayName = '1Password'\n\n private readonly account?: string\n private readonly vault: string\n private readonly itemName: string\n\n /**\n * Create a new OnePasswordKeyProvider.\n * @param options - Provider options\n */\n constructor(options: OnePasswordKeyProviderOptions) {\n // Only assign account if it's defined (to satisfy exactOptionalPropertyTypes)\n if (options.account !== undefined) {\n this.account = options.account\n }\n this.vault = options.vault\n this.itemName = options.itemName\n }\n\n /**\n * Check if the 1Password CLI is installed.\n * @returns True if `op` command is available\n */\n static async isInstalled(): Promise<boolean> {\n try {\n await execCommand('op', ['--version'])\n return true\n } catch {\n return false\n }\n }\n\n /**\n * List all 1Password accounts.\n * @returns Array of account information\n */\n static async listAccounts(): Promise<OnePasswordAccount[]> {\n try {\n const output = await execCommand('op', ['account', 'list', '--format=json'])\n const parsed: unknown = JSON.parse(output)\n if (!Array.isArray(parsed)) {\n return []\n }\n // Type assertion needed: We validate it's an array, but can't validate structure\n // at runtime without a full validation library. The op CLI output format is trusted.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return parsed as OnePasswordAccount[]\n } catch (error) {\n // Log in development for debugging, but don't fail\n if (process.env.NODE_ENV !== 'production') {\n console.error('Failed to list 1Password accounts:', error)\n }\n return []\n }\n }\n\n /**\n * List vaults in a specific account.\n * @param account - Account email (optional if only one account)\n * @returns Array of vault information\n */\n static async listVaults(account?: string): Promise<OnePasswordVault[]> {\n try {\n const args = ['vault', 'list', '--format=json']\n if (account) {\n args.push('--account', account)\n }\n const output = await execCommand('op', args)\n const parsed: unknown = JSON.parse(output)\n if (!Array.isArray(parsed)) {\n return []\n }\n // Type assertion needed: We validate it's an array, but can't validate structure\n // at runtime without a full validation library. The op CLI output format is trusted.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return parsed as OnePasswordVault[]\n } catch (error) {\n // Log in development for debugging, but don't fail\n if (process.env.NODE_ENV !== 'production') {\n console.error('Failed to list 1Password vaults:', error)\n }\n return []\n }\n }\n\n /**\n * Check if this provider is available.\n * Requires `op` CLI to be installed and authenticated.\n */\n async isAvailable(): Promise<boolean> {\n return OnePasswordKeyProvider.isInstalled()\n }\n\n /**\n * Check if a key exists in 1Password.\n * @param keyRef - Item name in 1Password\n */\n async keyExists(keyRef: string): Promise<boolean> {\n try {\n const args = ['item', 'get', keyRef, '--vault', this.vault, '--format=json']\n if (this.account) {\n args.push('--account', this.account)\n }\n await execCommand('op', args)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the private key from 1Password for signing.\n * Downloads to a temporary file and returns a cleanup function.\n * @param keyRef - Item name in 1Password\n * @throws Error if the key does not exist in 1Password\n */\n async getPrivateKey(keyRef: string): Promise<KeyRetrievalResult> {\n // Check if key exists first for better error messages\n if (!(await this.keyExists(keyRef))) {\n throw new Error(\n `Key not found in 1Password: \"${keyRef}\" (vault: ${this.vault})` +\n (this.account ? ` (account: ${this.account})` : ''),\n )\n }\n\n // Create a temporary file\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-'))\n const tempKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Download the key from 1Password\n const args = ['document', 'get', keyRef, '--vault', this.vault, '--out-file', tempKeyPath]\n if (this.account) {\n args.push('--account', this.account)\n }\n\n await execCommand('op', args)\n\n // Set proper permissions\n await setKeyPermissions(tempKeyPath)\n\n return {\n keyPath: tempKeyPath,\n cleanup: async () => {\n // Securely delete the temporary file and directory\n try {\n await fs.unlink(tempKeyPath)\n await fs.rmdir(tempDir)\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key file at ${tempKeyPath}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n },\n }\n } catch (error) {\n // Clean up temp directory on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Generate a new keypair and store private key in 1Password.\n * Public key is written to filesystem for repository commit.\n * @param options - Key generation options\n */\n async generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult> {\n const { publicKeyPath, force = false } = options\n\n // Create a temporary directory for key generation\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-keygen-'))\n const tempPrivateKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Generate the keypair to temporary location\n await cryptoGenerateKeyPair({\n privatePath: tempPrivateKeyPath,\n publicPath: publicKeyPath,\n force,\n })\n\n // Upload the private key to 1Password as a document\n const args = [\n 'document',\n 'create',\n tempPrivateKeyPath,\n '--title',\n this.itemName,\n '--vault',\n this.vault,\n ]\n if (this.account) {\n args.push('--account', this.account)\n }\n\n await execCommand('op', args)\n\n // Clean up temporary private key\n await fs.unlink(tempPrivateKeyPath)\n await fs.rmdir(tempDir)\n\n return {\n privateKeyRef: this.itemName,\n publicKeyPath,\n storageDescription: `1Password: ${this.vault}/${this.itemName}`,\n }\n } catch (error) {\n // Clean up on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Get the configuration for this provider.\n */\n getConfig(): KeyProviderConfig {\n return {\n type: this.type,\n options: {\n ...(this.account && { account: this.account }),\n vault: this.vault,\n itemName: this.itemName,\n },\n }\n }\n}\n\n/**\n * Execute a command and return stdout.\n * @internal\n */\nasync function execCommand(command: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] })\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 if (code === 0) {\n resolve(stdout.trim())\n } else {\n reject(new Error(`Command failed with exit code ${String(code)}: ${stderr}`))\n }\n })\n\n proc.on('error', (error) => {\n reject(error)\n })\n })\n}\n","/**\n * macOS Keychain-based key provider implementation.\n *\n * @remarks\n * This provider stores private keys in the macOS Keychain and retrieves them via the\n * `security` CLI tool. Keys are stored as base64-encoded strings and downloaded to\n * temporary files for signing operations, then securely deleted after use.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { generateKeyPair as cryptoGenerateKeyPair, setKeyPermissions } from '../crypto.js'\nimport type {\n KeyProvider,\n KeyProviderConfig,\n KeyRetrievalResult,\n KeyGenerationResult,\n KeygenProviderOptions,\n} from './types.js'\n\n/**\n * Options for creating a MacOSKeychainKeyProvider.\n * @public\n */\nexport interface MacOSKeychainKeyProviderOptions {\n /** Item name in keychain (e.g., \"attest-it-private-key\") */\n itemName: string\n /** Path to the keychain file (optional, uses default keychain if not specified) */\n keychain?: string\n}\n\n/**\n * Information about a macOS keychain.\n * @public\n */\nexport interface MacOSKeychain {\n /** Full path to the keychain file */\n path: string\n /** Display name (filename without extension) */\n name: string\n}\n\n/**\n * Key provider that stores private keys in macOS Keychain.\n *\n * @remarks\n * This provider requires macOS and uses the `security` CLI tool.\n * Private keys are stored as base64-encoded strings in the keychain and decoded\n * to temporary files for signing operations.\n *\n * @public\n */\nexport class MacOSKeychainKeyProvider implements KeyProvider {\n readonly type = 'macos-keychain'\n readonly displayName = 'macOS Keychain'\n\n private readonly itemName: string\n private readonly keychain?: string\n private static readonly ACCOUNT = 'attest-it'\n\n /**\n * Create a new MacOSKeychainKeyProvider.\n * @param options - Provider options\n */\n constructor(options: MacOSKeychainKeyProviderOptions) {\n this.itemName = options.itemName\n if (options.keychain !== undefined) {\n this.keychain = options.keychain\n }\n }\n\n /**\n * Check if this provider is available.\n * Only available on macOS platforms.\n */\n static isAvailable(): boolean {\n return process.platform === 'darwin'\n }\n\n /**\n * List available keychains on the system.\n * @returns Array of keychain information\n */\n static async listKeychains(): Promise<MacOSKeychain[]> {\n if (!MacOSKeychainKeyProvider.isAvailable()) {\n return []\n }\n\n try {\n const output = await execCommand('security', ['list-keychains'])\n // Parse output - each line is a quoted path like:\n // \" \"/Users/name/Library/Keychains/login.keychain-db\"\"\n const keychains: MacOSKeychain[] = []\n const lines = output.split('\\n')\n for (const line of lines) {\n const match = /\"(.+)\"/.exec(line.trim())\n if (match?.[1]) {\n const fullPath = match[1]\n // Extract display name from path (filename without extension)\n const filename = fullPath.split('/').pop() ?? fullPath\n const name = filename.replace(/\\.keychain(-db)?$/, '')\n keychains.push({ path: fullPath, name })\n }\n }\n return keychains\n } catch {\n return []\n }\n }\n\n /**\n * Check if this provider is available on the current system.\n */\n isAvailable(): Promise<boolean> {\n return Promise.resolve(MacOSKeychainKeyProvider.isAvailable())\n }\n\n /**\n * Check if a key exists in the keychain.\n * @param keyRef - Item name in keychain\n */\n async keyExists(keyRef: string): Promise<boolean> {\n try {\n const args = ['find-generic-password', '-a', MacOSKeychainKeyProvider.ACCOUNT, '-s', keyRef]\n if (this.keychain) {\n args.push(this.keychain)\n }\n await execCommand('security', args)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the private key from keychain for signing.\n * Downloads to a temporary file and returns a cleanup function.\n * @param keyRef - Item name in keychain\n * @throws Error if the key does not exist in keychain\n */\n async getPrivateKey(keyRef: string): Promise<KeyRetrievalResult> {\n // Check if key exists first for better error messages\n if (!(await this.keyExists(keyRef))) {\n throw new Error(\n `Key not found in macOS Keychain: \"${keyRef}\" (account: ${MacOSKeychainKeyProvider.ACCOUNT})`,\n )\n }\n\n // Create a temporary file\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-'))\n const tempKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Retrieve the base64-encoded key from keychain\n const findArgs = [\n 'find-generic-password',\n '-a',\n MacOSKeychainKeyProvider.ACCOUNT,\n '-s',\n keyRef,\n '-w',\n ]\n if (this.keychain) {\n findArgs.push(this.keychain)\n }\n const base64Key = await execCommand('security', findArgs)\n\n // Decode from base64 and write to temp file\n const keyContent = Buffer.from(base64Key, 'base64').toString('utf8')\n await fs.writeFile(tempKeyPath, keyContent, { mode: 0o600 })\n\n // Set proper permissions\n await setKeyPermissions(tempKeyPath)\n\n return {\n keyPath: tempKeyPath,\n cleanup: async () => {\n // Securely delete the temporary file and directory\n try {\n await fs.unlink(tempKeyPath)\n await fs.rmdir(tempDir)\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key file at ${tempKeyPath}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n },\n }\n } catch (error) {\n // Clean up temp directory on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Generate a new keypair and store private key in keychain.\n * Public key is written to filesystem for repository commit.\n * @param options - Key generation options\n */\n async generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult> {\n const { publicKeyPath, force = false } = options\n\n // Create a temporary directory for key generation\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-keygen-'))\n const tempPrivateKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Generate the keypair to temporary location\n await cryptoGenerateKeyPair({\n privatePath: tempPrivateKeyPath,\n publicPath: publicKeyPath,\n force,\n })\n\n // Read the private key and encode as base64\n const privateKeyContent = await fs.readFile(tempPrivateKeyPath, 'utf8')\n const base64Key = Buffer.from(privateKeyContent, 'utf8').toString('base64')\n\n // Store in keychain\n // The -T \"\" flag allows all applications to access the key\n // The -U flag updates if the item already exists\n const addArgs = [\n 'add-generic-password',\n '-a',\n MacOSKeychainKeyProvider.ACCOUNT,\n '-s',\n this.itemName,\n '-w',\n base64Key,\n '-T',\n '',\n '-U',\n ]\n if (this.keychain) {\n addArgs.push(this.keychain)\n }\n await execCommand('security', addArgs)\n\n // Clean up temporary private key\n await fs.unlink(tempPrivateKeyPath)\n await fs.rmdir(tempDir)\n\n return {\n privateKeyRef: this.itemName,\n publicKeyPath,\n storageDescription: `macOS Keychain: ${this.itemName}`,\n }\n } catch (error) {\n // Clean up on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Get the configuration for this provider.\n */\n getConfig(): KeyProviderConfig {\n return {\n type: this.type,\n options: {\n itemName: this.itemName,\n },\n }\n }\n}\n\n/**\n * Execute a command and return stdout.\n * @internal\n */\nasync function execCommand(command: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] })\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 if (code === 0) {\n resolve(stdout.trim())\n } else {\n reject(new Error(`Command failed with exit code ${String(code)}: ${stderr}`))\n }\n })\n\n proc.on('error', (error) => {\n reject(error)\n })\n })\n}\n","/**\n * Registry for key provider implementations.\n *\n * @remarks\n * The registry maintains a mapping of provider types to factory functions,\n * allowing dynamic creation of key providers based on configuration.\n *\n * @packageDocumentation\n */\n\nimport type { KeyProvider, KeyProviderConfig } from './types.js'\nimport { FilesystemKeyProvider } from './filesystem-provider.js'\nimport { OnePasswordKeyProvider } from './one-password-provider.js'\nimport { MacOSKeychainKeyProvider } from './macos-keychain-provider.js'\n\n/**\n * Type for a key provider factory function.\n * @public\n */\nexport type KeyProviderFactory = (config: KeyProviderConfig) => KeyProvider\n\n/**\n * Registry for key provider implementations.\n *\n * @remarks\n * The registry allows registration of custom key providers and provides\n * a factory method to create provider instances from configuration.\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 KeyProviderRegistry {\n private static providers = new Map<string, KeyProviderFactory>()\n\n /**\n * Register a key provider factory.\n * @param type - Provider type identifier\n * @param factory - Factory function to create provider instances\n */\n static register(type: string, factory: KeyProviderFactory): void {\n this.providers.set(type, factory)\n }\n\n /**\n * Create a key provider from configuration.\n * @param config - Provider configuration\n * @returns A key provider instance\n * @throws Error if the provider type is not registered\n */\n static create(config: KeyProviderConfig): KeyProvider {\n const factory = this.providers.get(config.type)\n if (!factory) {\n throw new Error(\n `Unknown key provider type: ${config.type}. ` +\n `Available types: ${Array.from(this.providers.keys()).join(', ')}`,\n )\n }\n return factory(config)\n }\n\n /**\n * Get all registered provider types.\n * @returns Array of provider type identifiers\n */\n static getProviderTypes(): string[] {\n return Array.from(this.providers.keys())\n }\n}\n\n// Register the filesystem provider by default\nKeyProviderRegistry.register('filesystem', (config) => {\n const privateKeyPath =\n typeof config.options.privateKeyPath === 'string' ? config.options.privateKeyPath : undefined\n\n // Only pass privateKeyPath if it's defined (to satisfy exactOptionalPropertyTypes)\n if (privateKeyPath !== undefined) {\n return new FilesystemKeyProvider({ privateKeyPath })\n }\n return new FilesystemKeyProvider()\n})\n\n// Register the 1Password provider\nKeyProviderRegistry.register('1password', (config) => {\n const { options } = config\n const account = typeof options.account === 'string' ? options.account : undefined\n const vault = typeof options.vault === 'string' ? options.vault : ''\n const itemName = typeof options.itemName === 'string' ? options.itemName : ''\n\n if (!vault || !itemName) {\n throw new Error('1Password provider requires vault and itemName options')\n }\n\n // Only pass account if it's defined (to satisfy exactOptionalPropertyTypes)\n if (account !== undefined) {\n return new OnePasswordKeyProvider({ account, vault, itemName })\n }\n return new OnePasswordKeyProvider({ vault, itemName })\n})\n\n// Register the macOS Keychain provider\nKeyProviderRegistry.register('macos-keychain', (config) => {\n const { options } = config\n const itemName = typeof options.itemName === 'string' ? options.itemName : ''\n\n if (!itemName) {\n throw new Error('macOS Keychain provider requires itemName option')\n }\n\n return new MacOSKeychainKeyProvider({ itemName })\n})\n","/**\n * Configuration loading for local identity system.\n * @packageDocumentation\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { mkdir as mkdirAsync, readFile, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml'\nimport { z } from 'zod'\nimport type { Identity, LocalConfig, PrivateKeyRef } from './types.js'\n\n/**\n * Module-level override for the attest-it home directory.\n * When set, this overrides the default ~/.config/attest-it location.\n * @internal\n */\nlet homeDirOverride: string | null = null\n\n/**\n * Set a custom home directory for attest-it configuration.\n * This is useful for testing or running with isolated state.\n *\n * @param dir - The directory to use, or null to reset to default\n * @public\n */\nexport function setAttestItHomeDir(dir: string | null): void {\n homeDirOverride = dir\n}\n\n/**\n * Get the current attest-it home directory override.\n *\n * @returns The override directory, or null if using default\n * @public\n */\nexport function getAttestItHomeDir(): string | null {\n return homeDirOverride\n}\n\n/**\n * Zod schema for private key references.\n */\nconst privateKeyRefSchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('file'),\n path: z.string().min(1, 'File path cannot be empty'),\n }),\n z.object({\n type: z.literal('keychain'),\n service: z.string().min(1, 'Service name cannot be empty'),\n account: z.string().min(1, 'Account name cannot be empty'),\n keychain: z.string().optional(),\n }),\n z.object({\n type: z.literal('1password'),\n account: z.string().optional(),\n vault: z.string().min(1, 'Vault name cannot be empty'),\n item: z.string().min(1, 'Item name cannot be empty'),\n field: z.string().optional(),\n }),\n])\n\n/**\n * Zod schema for a single identity.\n */\nconst identitySchema = z\n .object({\n name: z.string().min(1, 'Identity name cannot be empty'),\n email: z.string().optional(),\n github: z.string().optional(),\n publicKey: z.string().min(1, 'Public key cannot be empty'),\n privateKey: privateKeyRefSchema,\n })\n .strict()\n\n/**\n * Zod schema for the local config file.\n */\nconst localConfigSchema = z\n .object({\n activeIdentity: z.string().min(1, 'Active identity name cannot be empty'),\n identities: z\n .record(z.string(), identitySchema)\n .refine((identities) => Object.keys(identities).length >= 1, {\n message: 'At least one identity must be defined',\n }),\n })\n .strict()\n\n/**\n * Error thrown when local config validation fails.\n * @public\n */\nexport class LocalConfigValidationError extends Error {\n constructor(\n message: string,\n public readonly issues: z.ZodIssue[],\n ) {\n super(message)\n this.name = 'LocalConfigValidationError'\n }\n}\n\n/**\n * Get the path to the local config file.\n *\n * If a home directory override is set via setAttestItHomeDir(),\n * returns {homeDir}/config.yaml. Otherwise returns ~/.config/attest-it/config.yaml.\n *\n * @returns Path to the local config file\n * @public\n */\nexport function getLocalConfigPath(): string {\n if (homeDirOverride) {\n return join(homeDirOverride, 'config.yaml')\n }\n const home = homedir()\n return join(home, '.config', 'attest-it', 'config.yaml')\n}\n\n/**\n * Get the attest-it configuration directory.\n *\n * If a home directory override is set via setAttestItHomeDir(),\n * returns that directory. Otherwise returns ~/.config/attest-it.\n *\n * @returns Path to the configuration directory\n * @public\n */\nexport function getAttestItConfigDir(): string {\n if (homeDirOverride) {\n return homeDirOverride\n }\n return join(homedir(), '.config', 'attest-it')\n}\n\n/**\n * Parse and validate local config content.\n *\n * @param content - YAML content to parse\n * @returns Validated LocalConfig object\n * @throws {LocalConfigValidationError} If validation fails\n */\nfunction parseLocalConfigContent(content: string): LocalConfig {\n let rawConfig: unknown\n\n try {\n rawConfig = parseYaml(content)\n } catch (error) {\n throw new LocalConfigValidationError(\n `Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`,\n [],\n )\n }\n\n const result = localConfigSchema.safeParse(rawConfig)\n\n if (!result.success) {\n throw new LocalConfigValidationError(\n 'Local configuration validation failed:\\n' +\n result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n'),\n result.error.issues,\n )\n }\n\n // Transform Zod output to match LocalConfig interface by removing undefined values\n const identities: Record<string, Identity> = Object.fromEntries(\n Object.entries(result.data.identities).map(([key, identity]) => {\n // Transform private key ref to remove undefined optional fields\n let privateKey: PrivateKeyRef\n if (identity.privateKey.type === '1password') {\n privateKey = {\n type: '1password',\n vault: identity.privateKey.vault,\n item: identity.privateKey.item,\n ...(identity.privateKey.account !== undefined && {\n account: identity.privateKey.account,\n }),\n ...(identity.privateKey.field !== undefined && { field: identity.privateKey.field }),\n }\n } else if (identity.privateKey.type === 'keychain') {\n privateKey = {\n type: 'keychain',\n service: identity.privateKey.service,\n account: identity.privateKey.account,\n ...(identity.privateKey.keychain !== undefined && {\n keychain: identity.privateKey.keychain,\n }),\n }\n } else {\n privateKey = identity.privateKey\n }\n\n return [\n key,\n {\n name: identity.name,\n publicKey: identity.publicKey,\n privateKey,\n ...(identity.email !== undefined && { email: identity.email }),\n ...(identity.github !== undefined && { github: identity.github }),\n },\n ]\n }),\n )\n\n return {\n activeIdentity: result.data.activeIdentity,\n identities,\n }\n}\n\n/**\n * Load and validate local config from file (async).\n *\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @returns Validated LocalConfig object, or null if file does not exist\n * @throws {LocalConfigValidationError} If validation fails\n * @public\n */\nexport async function loadLocalConfig(configPath?: string): Promise<LocalConfig | null> {\n const resolvedPath = configPath ?? getLocalConfigPath()\n\n try {\n const content = await readFile(resolvedPath, 'utf8')\n return parseLocalConfigContent(content)\n } catch (error) {\n if (error instanceof LocalConfigValidationError) {\n throw error\n }\n // Check if it's a file not found error\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n (error.code === 'ENOENT' || error.code === 'ENOTDIR')\n ) {\n return null\n }\n // Re-throw other errors\n throw error\n }\n}\n\n/**\n * Load and validate local config from file (sync).\n *\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @returns Validated LocalConfig object, or null if file does not exist\n * @throws {LocalConfigValidationError} If validation fails\n * @public\n */\nexport function loadLocalConfigSync(configPath?: string): LocalConfig | null {\n const resolvedPath = configPath ?? getLocalConfigPath()\n\n try {\n const content = readFileSync(resolvedPath, 'utf8')\n return parseLocalConfigContent(content)\n } catch (error) {\n if (error instanceof LocalConfigValidationError) {\n throw error\n }\n // Check if it's a file not found error\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n (error.code === 'ENOENT' || error.code === 'ENOTDIR')\n ) {\n return null\n }\n // Re-throw other errors\n throw error\n }\n}\n\n/**\n * Save local config to file (async).\n *\n * @param config - LocalConfig object to save\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @throws {Error} If write fails\n * @public\n */\nexport async function saveLocalConfig(config: LocalConfig, configPath?: string): Promise<void> {\n const resolvedPath = configPath ?? getLocalConfigPath()\n const content = stringifyYaml(config)\n\n // Ensure parent directory exists\n const dir = dirname(resolvedPath)\n await mkdirAsync(dir, { recursive: true })\n\n await writeFile(resolvedPath, content, 'utf8')\n}\n\n/**\n * Save local config to file (sync).\n *\n * @param config - LocalConfig object to save\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @throws {Error} If write fails\n * @public\n */\nexport function saveLocalConfigSync(config: LocalConfig, configPath?: string): void {\n const resolvedPath = configPath ?? getLocalConfigPath()\n const content = stringifyYaml(config)\n\n // Ensure parent directory exists\n const dir = dirname(resolvedPath)\n mkdirSync(dir, { recursive: true })\n\n writeFileSync(resolvedPath, content, 'utf8')\n}\n\n/**\n * Get the active identity from a config.\n *\n * @param config - LocalConfig object\n * @returns The active Identity, or undefined if not found\n * @public\n */\nexport function getActiveIdentity(config: LocalConfig): Identity | undefined {\n return config.identities[config.activeIdentity]\n}\n","/**\n * Authorization logic for attest-it v2.0.\n * @packageDocumentation\n */\n\nimport ms from 'ms'\n\nimport type { AttestItConfig, GateConfig, TeamMember } from './types.js'\n\n/**\n * Check if a public key belongs to an authorized signer for a gate.\n *\n * @param config - The attest-it configuration\n * @param gateId - The gate identifier (slug)\n * @param publicKey - Base64-encoded Ed25519 public key to check\n * @returns true if the public key belongs to an authorized signer for the gate\n * @public\n */\nexport function isAuthorizedSigner(\n config: AttestItConfig,\n gateId: string,\n publicKey: string,\n): boolean {\n // eslint-disable-next-line security/detect-object-injection\n const gate = config.gates?.[gateId]\n if (!gate) {\n return false\n }\n\n const teamMember = findTeamMemberByPublicKey(config, publicKey)\n if (!teamMember) {\n return false\n }\n\n // Find the slug for this team member\n const teamMemberSlug = findTeamMemberSlug(config, teamMember)\n if (!teamMemberSlug) {\n return false\n }\n\n return gate.authorizedSigners.includes(teamMemberSlug)\n}\n\n/**\n * Get all team members authorized to sign for a gate.\n *\n * @param config - The attest-it configuration\n * @param gateId - The gate identifier (slug)\n * @returns Array of authorized team members, or empty array if gate not found\n * @public\n */\nexport function getAuthorizedSignersForGate(config: AttestItConfig, gateId: string): TeamMember[] {\n // eslint-disable-next-line security/detect-object-injection\n const gate = config.gates?.[gateId]\n if (!gate || !config.team) {\n return []\n }\n\n const authorizedMembers: TeamMember[] = []\n for (const signerSlug of gate.authorizedSigners) {\n // eslint-disable-next-line security/detect-object-injection\n const member = config.team[signerSlug]\n if (member) {\n authorizedMembers.push(member)\n }\n }\n\n return authorizedMembers\n}\n\n/**\n * Find a team member by their public key.\n *\n * @param config - The attest-it configuration\n * @param publicKey - Base64-encoded Ed25519 public key\n * @returns The team member with matching public key, or undefined if not found\n * @public\n */\nexport function findTeamMemberByPublicKey(\n config: AttestItConfig,\n publicKey: string,\n): TeamMember | undefined {\n if (!config.team) {\n return undefined\n }\n\n for (const member of Object.values(config.team)) {\n if (member.publicKey === publicKey) {\n return member\n }\n }\n\n return undefined\n}\n\n/**\n * Find the slug for a team member.\n *\n * @param config - The attest-it configuration\n * @param teamMember - The team member to find the slug for\n * @returns The team member slug, or undefined if not found\n */\nfunction findTeamMemberSlug(config: AttestItConfig, teamMember: TeamMember): string | undefined {\n if (!config.team) {\n return undefined\n }\n\n for (const [slug, member] of Object.entries(config.team)) {\n if (member === teamMember || member.publicKey === teamMember.publicKey) {\n return slug\n }\n }\n\n return undefined\n}\n\n/**\n * Get the gate configuration for a given gate ID.\n *\n * @param config - The attest-it configuration\n * @param gateId - The gate identifier (slug)\n * @returns The gate configuration, or undefined if not found\n * @public\n */\nexport function getGate(config: AttestItConfig, gateId: string): GateConfig | undefined {\n // eslint-disable-next-line security/detect-object-injection\n return config.gates?.[gateId]\n}\n\n/**\n * Regular expression pattern for valid duration strings.\n * Matches formats like \"30d\", \"7d\", \"24h\", \"1w\", \"2y\", \"100ms\", etc.\n * Negative durations are not supported.\n * @internal\n */\nconst DURATION_PATTERN = /^\\d+(\\.\\d+)?\\s*(ms|s|m|h|d|w|y)$/i\n\n/**\n * Type guard to check if a string is a valid duration format.\n *\n * @param value - String to check\n * @returns true if the string matches the duration pattern\n * @internal\n */\nfunction isValidDurationFormat(value: string): boolean {\n return DURATION_PATTERN.test(value.trim())\n}\n\n/**\n * Parse a duration string to milliseconds.\n * Uses the ms library to parse strings like \"30d\", \"7d\", \"24h\".\n *\n * @param duration - Duration string (e.g., \"30d\", \"7d\", \"24h\")\n * @returns Duration in milliseconds\n * @throws {Error} If duration string is invalid\n * @public\n */\nexport function parseDuration(duration: string): number {\n // Validate format before calling ms to avoid type assertion issues\n if (!isValidDurationFormat(duration)) {\n throw new Error(`Invalid duration string: ${duration}`)\n }\n\n // The ms function accepts the StringValue type which is a union of specific string patterns\n // After validating the format, we can safely call ms\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- safe after format validation\n const result = ms(duration as Parameters<typeof ms>[0])\n if (typeof result !== 'number' || result <= 0) {\n throw new Error(`Invalid duration string: ${duration}`)\n }\n return result\n}\n","/**\n * Seal operations for creating, verifying, and managing seals.\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { z } from 'zod'\n\nimport * as ed25519 from '../crypto/ed25519.js'\nimport type { AttestItConfig } from '../types.js'\nimport type { Seal, SealsFile } from './types.js'\n\n/**\n * Zod schema for a single seal.\n * @internal\n */\nconst sealSchema = z.object({\n gateId: z.string().min(1, 'Gate ID cannot be empty'),\n // Fingerprint format: sha256:<hex> where hex is at least 1 character\n // Full fingerprints are 64 hex chars, but tests may use shorter values\n fingerprint: z\n .string()\n .regex(/^sha256:[a-f0-9]+$/i, 'Invalid fingerprint format (expected sha256:<hex>)'),\n timestamp: z.string().datetime({ message: 'Invalid ISO 8601 timestamp' }),\n sealedBy: z.string().min(1, 'Signer slug cannot be empty'),\n signature: z.string().min(1, 'Signature cannot be empty'),\n})\n\n/**\n * Zod schema for the seals file.\n * @internal\n */\nconst sealsFileSchema = z.object({\n version: z.literal(1, { errorMap: () => ({ message: 'Unsupported seals file version' }) }),\n seals: z.record(z.string(), sealSchema),\n})\n\n/**\n * Options for creating a seal.\n * @public\n */\nexport interface CreateSealOptions {\n /** Gate identifier (slug) */\n gateId: string\n /** SHA-256 fingerprint of the gate's content */\n fingerprint: string\n /** Team member slug creating the seal */\n sealedBy: string\n /** PEM-encoded Ed25519 private key for signing */\n privateKey: string\n}\n\n/**\n * Result of seal signature verification.\n * @public\n */\nexport interface SignatureVerificationResult {\n /** Whether the seal signature is valid */\n valid: boolean\n /** Error message if verification failed */\n error?: string\n}\n\n/**\n * Create a seal by signing the canonical string: gateId:fingerprint:timestamp\n *\n * @param options - Seal creation options\n * @returns The created seal\n * @throws Error if signing fails\n * @public\n */\nexport function createSeal(options: CreateSealOptions): Seal {\n const { gateId, fingerprint, sealedBy, privateKey } = options\n\n // Create ISO 8601 timestamp\n const timestamp = new Date().toISOString()\n\n // Create canonical string to sign\n const canonicalString = `${gateId}:${fingerprint}:${timestamp}`\n\n // Sign the canonical string\n const signature = ed25519.sign(canonicalString, privateKey)\n\n return {\n gateId,\n fingerprint,\n timestamp,\n sealedBy,\n signature,\n }\n}\n\n/**\n * Verify a seal's signature against the team member's public key.\n *\n * @param seal - The seal to verify\n * @param config - The attest-it configuration containing team members\n * @returns Verification result with success status and optional error message\n * @public\n */\nexport function verifySeal(seal: Seal, config: AttestItConfig): SignatureVerificationResult {\n const { gateId, fingerprint, timestamp, sealedBy, signature } = seal\n\n // Look up team member by slug\n if (!config.team) {\n return {\n valid: false,\n error: `No team configuration found`,\n }\n }\n\n // eslint-disable-next-line security/detect-object-injection\n const teamMember = config.team[sealedBy]\n if (!teamMember) {\n return {\n valid: false,\n error: `Team member '${sealedBy}' not found in configuration`,\n }\n }\n\n // Reconstruct canonical string\n const canonicalString = `${gateId}:${fingerprint}:${timestamp}`\n\n // Verify signature\n try {\n const isValid = ed25519.verify(canonicalString, signature, teamMember.publicKey)\n if (!isValid) {\n return {\n valid: false,\n error: 'Signature verification failed',\n }\n }\n\n return { valid: true }\n } catch (error) {\n return {\n valid: false,\n error: `Signature verification error: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n}\n\n/**\n * Parse and validate seals file content.\n *\n * @param content - JSON content to parse\n * @returns Validated SealsFile\n * @throws Error if validation fails\n * @internal\n */\nfunction parseSealsContent(content: string): SealsFile {\n let rawData: unknown\n try {\n rawData = JSON.parse(content)\n } catch (error) {\n throw new Error(`Invalid JSON: ${error instanceof Error ? error.message : String(error)}`)\n }\n\n const result = sealsFileSchema.safeParse(rawData)\n if (!result.success) {\n const issues = result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n')\n throw new Error(`Invalid seals file:\\n${issues}`)\n }\n\n return result.data\n}\n\n/**\n * Read seals from the seals.json file (async).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @returns The seals file contents, or an empty seals file if the file doesn't exist\n * @throws Error if file exists but cannot be read or parsed\n * @public\n */\nexport async function readSeals(dir: string): Promise<SealsFile> {\n const sealsPath = path.join(dir, '.attest-it', 'seals.json')\n\n try {\n const content = await fs.promises.readFile(sealsPath, 'utf8')\n return parseSealsContent(content)\n } catch (error) {\n // If file doesn't exist, return empty seals file\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n return {\n version: 1,\n seals: {},\n }\n }\n\n // Re-throw other errors (permission denied, parse errors, etc.)\n throw new Error(\n `Failed to read seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n\n/**\n * Read seals from the seals.json file (sync).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @returns The seals file contents, or an empty seals file if the file doesn't exist\n * @throws Error if file exists but cannot be read or parsed\n * @public\n */\nexport function readSealsSync(dir: string): SealsFile {\n const sealsPath = path.join(dir, '.attest-it', 'seals.json')\n\n try {\n const content = fs.readFileSync(sealsPath, 'utf8')\n return parseSealsContent(content)\n } catch (error) {\n // If file doesn't exist, return empty seals file\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n return {\n version: 1,\n seals: {},\n }\n }\n\n // Re-throw other errors (permission denied, parse errors, etc.)\n throw new Error(\n `Failed to read seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n\n/**\n * Write seals to the seals.json file (async).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @param sealsFile - The seals file to write\n * @throws Error if file cannot be written\n * @public\n */\nexport async function writeSeals(dir: string, sealsFile: SealsFile): Promise<void> {\n const attestItDir = path.join(dir, '.attest-it')\n const sealsPath = path.join(attestItDir, 'seals.json')\n\n try {\n // Ensure .attest-it directory exists\n await fs.promises.mkdir(attestItDir, { recursive: true })\n\n // Write seals file with pretty formatting\n const content = JSON.stringify(sealsFile, null, 2) + '\\n'\n await fs.promises.writeFile(sealsPath, content, 'utf8')\n } catch (error) {\n throw new Error(\n `Failed to write seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n\n/**\n * Write seals to the seals.json file (sync).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @param sealsFile - The seals file to write\n * @throws Error if file cannot be written\n * @public\n */\nexport function writeSealsSync(dir: string, sealsFile: SealsFile): void {\n const attestItDir = path.join(dir, '.attest-it')\n const sealsPath = path.join(attestItDir, 'seals.json')\n\n try {\n // Ensure .attest-it directory exists\n fs.mkdirSync(attestItDir, { recursive: true })\n\n // Write seals file with pretty formatting\n const content = JSON.stringify(sealsFile, null, 2) + '\\n'\n fs.writeFileSync(sealsPath, content, 'utf8')\n } catch (error) {\n throw new Error(\n `Failed to write seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n","/**\n * Seal verification logic and states.\n * @packageDocumentation\n */\n\nimport { parseDuration, getGate, isAuthorizedSigner } from '../authorization.js'\nimport type { AttestItConfig } from '../types.js'\nimport type { Seal, SealsFile } from './types.js'\nimport { verifySeal } from './operations.js'\n\n/**\n * Verification state for a gate's seal.\n * @public\n */\nexport type VerificationState =\n | 'VALID' // Seal exists, signature valid, not stale, fingerprint matches\n | 'MISSING' // No seal for this gate\n | 'STALE' // Seal exists but exceeds maxAge\n | 'FINGERPRINT_MISMATCH' // Seal fingerprint doesn't match current fingerprint\n | 'INVALID_SIGNATURE' // Signature doesn't verify\n | 'UNKNOWN_SIGNER' // sealedBy not in team or not authorized for this gate\n\n/**\n * Result of verifying a single gate's seal.\n * @public\n */\nexport interface SealVerificationResult {\n /** Gate identifier */\n gateId: string\n /** Verification state */\n state: VerificationState\n /** The seal, if one exists */\n seal?: Seal\n /** Human-readable message explaining the state */\n message?: string\n}\n\n/**\n * Verify a single gate's seal.\n *\n * @param config - The attest-it configuration\n * @param gateId - Gate identifier to verify\n * @param seals - The seals file containing all seals\n * @param currentFingerprint - Current computed fingerprint for the gate\n * @returns Verification result for the gate\n * @public\n */\nexport function verifyGateSeal(\n config: AttestItConfig,\n gateId: string,\n seals: SealsFile,\n currentFingerprint: string,\n): SealVerificationResult {\n // Get the gate configuration\n const gate = getGate(config, gateId)\n if (!gate) {\n return {\n gateId,\n state: 'MISSING',\n message: `Gate '${gateId}' not found in configuration`,\n }\n }\n\n // Check if a seal exists for this gate\n // eslint-disable-next-line security/detect-object-injection\n const seal = seals.seals[gateId]\n if (!seal) {\n return {\n gateId,\n state: 'MISSING',\n message: `No seal found for gate '${gateId}'`,\n }\n }\n\n // Check if fingerprint matches\n if (seal.fingerprint !== currentFingerprint) {\n return {\n gateId,\n state: 'FINGERPRINT_MISMATCH',\n seal,\n message: `Fingerprint changed since seal was created`,\n }\n }\n\n // Check if signer is in team and authorized\n if (!config.team) {\n return {\n gateId,\n state: 'UNKNOWN_SIGNER',\n seal,\n message: `No team configuration found`,\n }\n }\n\n const teamMember = config.team[seal.sealedBy]\n if (!teamMember) {\n return {\n gateId,\n state: 'UNKNOWN_SIGNER',\n seal,\n message: `Signer '${seal.sealedBy}' not found in team`,\n }\n }\n\n // Check if signer is authorized for this gate\n const authorized = isAuthorizedSigner(config, gateId, teamMember.publicKey)\n if (!authorized) {\n return {\n gateId,\n state: 'UNKNOWN_SIGNER',\n seal,\n message: `Signer '${seal.sealedBy}' is not authorized for gate '${gateId}'`,\n }\n }\n\n // Verify signature\n const verificationResult = verifySeal(seal, config)\n if (!verificationResult.valid) {\n return {\n gateId,\n state: 'INVALID_SIGNATURE',\n seal,\n message: verificationResult.error ?? 'Signature verification failed',\n }\n }\n\n // Check if seal is stale (exceeds maxAge)\n try {\n const maxAgeMs = parseDuration(gate.maxAge)\n const sealTimestamp = new Date(seal.timestamp).getTime()\n const now = Date.now()\n const ageMs = now - sealTimestamp\n\n if (ageMs > maxAgeMs) {\n const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24))\n const maxAgeDays = Math.floor(maxAgeMs / (1000 * 60 * 60 * 24))\n return {\n gateId,\n state: 'STALE',\n seal,\n message: `Seal is ${ageDays.toString()} days old, exceeds maxAge of ${maxAgeDays.toString()} days`,\n }\n }\n } catch (error) {\n // If we can't parse maxAge, fail closed - treat as stale to enforce freshness\n // This prevents bypassing staleness checks with invalid maxAge values\n return {\n gateId,\n state: 'STALE',\n seal,\n message: `Cannot verify freshness: invalid maxAge format: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n\n // All checks passed\n return {\n gateId,\n state: 'VALID',\n seal,\n }\n}\n\n/**\n * Verify all gates' seals.\n *\n * @param config - The attest-it configuration\n * @param seals - The seals file containing all seals\n * @param fingerprints - Map of gate IDs to their current fingerprints\n * @returns Array of verification results for all gates\n * @public\n */\nexport function verifyAllSeals(\n config: AttestItConfig,\n seals: SealsFile,\n fingerprints: Record<string, string>,\n): SealVerificationResult[] {\n if (!config.gates) {\n return []\n }\n\n const results: SealVerificationResult[] = []\n\n for (const gateId of Object.keys(config.gates)) {\n // eslint-disable-next-line security/detect-object-injection\n const fingerprint = fingerprints[gateId]\n if (!fingerprint) {\n results.push({\n gateId,\n state: 'MISSING',\n message: `No fingerprint computed for gate '${gateId}'`,\n })\n continue\n }\n\n const result = verifyGateSeal(config, gateId, seals, fingerprint)\n results.push(result)\n }\n\n return results\n}\n","/**\n * @attest-it/core\n *\n * Core functionality for the attest-it testing framework.\n * @packageDocumentation\n */\n\n/**\n * Package version\n * @public\n */\nexport const version = '0.0.0'\n\n// Types\nexport type {\n AttestItSettings,\n KeyProviderSettings,\n TeamMember,\n FingerprintConfig,\n GateConfig,\n SuiteConfig,\n AttestItConfig,\n Attestation,\n AttestationsFile,\n VerificationStatus,\n SuiteVerificationResult,\n} from './types.js'\n\n// Config\nexport {\n loadConfig,\n loadConfigSync,\n findConfigPath,\n resolveConfigPaths,\n toAttestItConfig,\n ConfigValidationError,\n ConfigNotFoundError,\n type Config,\n} from './config.js'\n\n// Fingerprinting\nexport { computeFingerprint, computeFingerprintSync, listPackageFiles } from './fingerprint.js'\nexport type { FingerprintOptions, FingerprintResult } from './fingerprint.js'\n\n// Attestations\nexport {\n readAttestations,\n readAttestationsSync,\n writeAttestations,\n writeAttestationsSync,\n findAttestation,\n upsertAttestation,\n removeAttestation,\n canonicalizeAttestations,\n createAttestation,\n writeSignedAttestations,\n readAndVerifyAttestations,\n SignatureInvalidError,\n} from './attestation.js'\nexport type {\n WriteSignedAttestationsOptions,\n ReadSignedAttestationsOptions,\n} from './attestation.js'\n\n// Cryptography\nexport {\n checkOpenSSL,\n getDefaultPrivateKeyPath,\n getDefaultPublicKeyPath,\n generateKeyPair,\n sign,\n verify,\n setKeyPermissions,\n} from './crypto.js'\nexport type {\n KeyPaths,\n KeygenOptions,\n SignOptions,\n VerifyOptions as CryptoVerifyOptions,\n} from './crypto.js'\n\n// Ed25519 Cryptography\nexport {\n generateKeyPair as generateEd25519KeyPair,\n sign as signEd25519,\n verify as verifyEd25519,\n getPublicKeyFromPrivate,\n} from './crypto/ed25519.js'\nexport type { KeyPair as Ed25519KeyPair } from './crypto/ed25519.js'\n\n// Verification\nexport { verifyAttestations } from './verify.js'\nexport type { VerifyOptions, VerifyResult } from './verify.js'\n\n// Key Providers\nexport {\n FilesystemKeyProvider,\n OnePasswordKeyProvider,\n MacOSKeychainKeyProvider,\n KeyProviderRegistry,\n type KeyProvider,\n type KeyProviderConfig,\n type KeyRetrievalResult,\n type KeyGenerationResult,\n type KeygenProviderOptions,\n type FilesystemKeyProviderOptions,\n type OnePasswordKeyProviderOptions,\n type OnePasswordAccount,\n type OnePasswordVault,\n type MacOSKeychainKeyProviderOptions,\n type MacOSKeychain,\n type KeyProviderFactory,\n} from './key-provider/index.js'\n\n// Identity System\nexport {\n getLocalConfigPath,\n getAttestItConfigDir,\n setAttestItHomeDir,\n getAttestItHomeDir,\n loadLocalConfig,\n loadLocalConfigSync,\n saveLocalConfig,\n saveLocalConfigSync,\n getActiveIdentity,\n LocalConfigValidationError,\n type PrivateKeyRef,\n type Identity,\n type LocalConfig,\n} from './identity/index.js'\n\n// Authorization\nexport {\n isAuthorizedSigner,\n getAuthorizedSignersForGate,\n findTeamMemberByPublicKey,\n getGate,\n parseDuration,\n} from './authorization.js'\n\n// Seal System\nexport {\n createSeal,\n verifySeal,\n readSeals,\n readSealsSync,\n writeSeals,\n writeSealsSync,\n verifyGateSeal,\n verifyAllSeals,\n type Seal,\n type SealsFile,\n type CreateSealOptions,\n type SignatureVerificationResult,\n type VerificationState,\n type SealVerificationResult,\n} from './seal/index.js'\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/config/shared-schemas.ts","../src/config/policy-schema.ts","../src/config/operational-schema.ts","../src/config/merge.ts","../src/config/validation.ts","../src/fingerprint.ts","../src/attestation.ts","../src/crypto/ed25519.ts","../src/verify.ts","../src/key-provider/filesystem-provider.ts","../src/key-provider/one-password-provider.ts","../src/key-provider/macos-keychain-provider.ts","../src/identity/config.ts","../src/key-provider/yubikey-provider.ts","../src/key-provider/registry.ts","../src/identity/preferences.ts","../src/authorization.ts","../src/seal/operations.ts","../src/seal/verification.ts","../src/index.ts"],"names":["parseYaml","teamMemberSchema","z","fingerprintConfigSchema","durationSchema","ms","gateSchema","keyProviderOptionsSchema","keyProviderSchema","suiteSchema","path","crypto","resolve","hash","fs2","path2","os","sign","verify","generateKeyPair","crypto2","fs3","path3","fs4","fs5","path4","execCommand","fs6","path5","os3","spawn","join","readFile","readFileSync","stringifyYaml","dirname","mkdirAsync","writeFile","mkdirSync","writeFileSync","version","os4","path7","fs8"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Configuration loading and validation for attest-it.\n */\n\nimport { readFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { join, resolve } from 'node:path'\nimport ms from 'ms'\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\n\n/**\n * Zod schema for key provider configuration.\n */\nconst keyProviderOptionsSchema = z\n .object({\n privateKeyPath: z.string().optional(),\n account: z.string().optional(),\n vault: z.string().optional(),\n itemName: z.string().optional(),\n })\n .strict()\n\nconst keyProviderSchema = z\n .object({\n type: z.enum(['filesystem', '1password']).or(z.string()),\n options: keyProviderOptionsSchema.optional(),\n })\n .strict()\n\n/**\n * Zod schema for a team member configuration.\n */\nconst teamMemberSchema = z\n .object({\n name: z.string().min(1, 'Team member name cannot be empty'),\n email: z.string().email().optional(),\n github: z.string().min(1).optional(),\n publicKey: z.string().min(1, 'Public key is required'),\n })\n .strict()\n\n/**\n * Zod schema for fingerprint configuration.\n */\nconst fingerprintConfigSchema = z\n .object({\n paths: z\n .array(z.string().min(1, 'Path cannot be empty'))\n .min(1, 'At least one path is required'),\n exclude: z.array(z.string().min(1, 'Exclude pattern cannot be empty')).optional(),\n })\n .strict()\n\n/**\n * Zod schema for duration strings.\n * Validates and parses duration strings like \"30d\", \"7d\", \"24h\".\n */\nconst durationSchema = z.string().refine(\n (val) => {\n try {\n // Type assertion needed because ms has strict StringValue type\n // We validate the result is a positive number below\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument, @typescript-eslint/consistent-type-assertions\n const parsed = ms(val as any)\n return typeof parsed === 'number' && parsed > 0\n } catch {\n return false\n }\n },\n {\n message: 'Duration must be a valid duration string (e.g., \"30d\", \"7d\", \"24h\")',\n },\n)\n\n/**\n * Zod schema for a gate configuration.\n */\nconst gateSchema = z\n .object({\n name: z.string().min(1, 'Gate name cannot be empty'),\n description: z.string().min(1, 'Gate description cannot be empty'),\n authorizedSigners: z\n .array(z.string().min(1, 'Authorized signer slug cannot be empty'))\n .min(1, 'At least one authorized signer is required'),\n fingerprint: fingerprintConfigSchema,\n maxAge: durationSchema,\n })\n .strict()\n\n/**\n * Zod schema for settings with defaults applied.\n */\nconst settingsSchema = z\n .object({\n maxAgeDays: z.number().int().positive().default(30),\n publicKeyPath: z.string().default('.attest-it/pubkey.pem'),\n attestationsPath: z.string().default('.attest-it/attestations.json'),\n defaultCommand: z.string().optional(),\n keyProvider: keyProviderSchema.optional(),\n // Note: algorithm field was removed - RSA is the only supported algorithm\n })\n .passthrough()\n\n/**\n * Zod schema for a suite configuration.\n * Suites are CLI-layer extensions of gates with command execution capabilities.\n * For backward compatibility, suites can define their own fingerprint via packages/files/ignore.\n */\nconst suiteSchema = z\n .object({\n // Gate fields (if present, this suite references a gate)\n gate: z.string().optional(),\n // Legacy fingerprint definition (for backward compatibility)\n description: z.string().optional(),\n packages: z.array(z.string().min(1, 'Package path cannot be empty')).optional(),\n files: z.array(z.string().min(1, 'File path cannot be empty')).optional(),\n ignore: z.array(z.string().min(1, 'Ignore pattern cannot be empty')).optional(),\n // CLI-specific fields\n command: z.string().optional(),\n timeout: z.string().optional(),\n interactive: z.boolean().optional(),\n // Relationship fields\n invalidates: z.array(z.string().min(1, 'Invalidated suite name cannot be empty')).optional(),\n depends_on: z.array(z.string().min(1, 'Dependency suite name cannot be empty')).optional(),\n })\n .strict()\n .refine(\n (suite) => {\n // Either gate is specified, or packages is specified (for legacy compatibility)\n return suite.gate !== undefined || (suite.packages !== undefined && suite.packages.length > 0)\n },\n {\n message: 'Suite must either reference a gate or define packages for fingerprinting',\n },\n )\n\n/**\n * Zod schema for the full configuration file.\n */\nconst configSchema = z\n .object({\n version: z.literal(1),\n settings: settingsSchema.default({}),\n team: z.record(z.string(), teamMemberSchema).optional(),\n gates: z.record(z.string(), gateSchema).optional(),\n suites: z.record(z.string(), suiteSchema).refine((suites) => Object.keys(suites).length >= 1, {\n message: 'At least one suite must be defined',\n }),\n groups: z\n .record(z.string(), z.array(z.string().min(1, 'Suite name in group cannot be empty')))\n .optional(),\n })\n .strict()\n\n/**\n * Type inference from Zod schema (should match AttestItConfig).\n * This is the same as AttestItConfig but with defaults applied.\n * @public\n */\nexport type Config = z.infer<typeof configSchema>\n\n/**\n * Error thrown when configuration is invalid.\n * @public\n */\nexport class ConfigValidationError extends Error {\n constructor(\n message: string,\n public readonly issues: z.ZodIssue[],\n ) {\n super(message)\n this.name = 'ConfigValidationError'\n }\n}\n\n/**\n * Error thrown when configuration file cannot be found.\n * @public\n */\nexport class ConfigNotFoundError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ConfigNotFoundError'\n }\n}\n\n/**\n * Parse configuration content from a string.\n *\n * @param content - The configuration file content\n * @param format - The format of the content ('yaml' or 'json')\n * @returns Parsed and validated configuration\n * @throws {ConfigValidationError} If validation fails\n */\nfunction parseConfigContent(content: string, format: 'yaml' | 'json'): Config {\n let rawConfig: unknown\n\n try {\n if (format === 'yaml') {\n rawConfig = parseYaml(content)\n } else {\n rawConfig = JSON.parse(content)\n }\n } catch (error) {\n throw new ConfigValidationError(\n `Failed to parse ${format.toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`,\n [],\n )\n }\n\n const result = configSchema.safeParse(rawConfig)\n\n if (!result.success) {\n throw new ConfigValidationError(\n 'Configuration validation failed:\\n' +\n result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n'),\n result.error.issues,\n )\n }\n\n return result.data\n}\n\n/**\n * Determine the format of a config file from its extension.\n *\n * @param filePath - Path to the config file\n * @returns 'yaml' or 'json'\n */\nfunction getConfigFormat(filePath: string): 'yaml' | 'json' {\n const ext = filePath.toLowerCase()\n if (ext.endsWith('.yaml') || ext.endsWith('.yml')) {\n return 'yaml'\n }\n if (ext.endsWith('.json')) {\n return 'json'\n }\n // Default to yaml for extensionless files\n return 'yaml'\n}\n\n/**\n * Find the configuration file in default locations.\n *\n * Searches in this order:\n * 1. .attest-it/config.yaml\n * 2. .attest-it/config.yml\n * 3. .attest-it/config.json\n *\n * @param startDir - Directory to start searching from (defaults to cwd)\n * @returns Absolute path to the config file, or null if not found\n * @public\n */\nexport function findConfigPath(startDir: string = process.cwd()): string | null {\n const configDir = join(startDir, '.attest-it')\n const candidates = ['config.yaml', 'config.yml', 'config.json']\n\n for (const candidate of candidates) {\n const configPath = join(configDir, candidate)\n try {\n readFileSync(configPath, 'utf8')\n return configPath\n } catch {\n // File doesn't exist or can't be read, try next candidate\n continue\n }\n }\n\n return null\n}\n\n/**\n * Load and validate configuration from a file (async).\n *\n * @param configPath - Optional path to config file. If not provided, searches default locations.\n * @returns Validated configuration object\n * @throws {@link ConfigNotFoundError} If config file cannot be found\n * @throws {@link ConfigValidationError} If validation fails\n * @public\n */\nexport async function loadConfig(configPath?: string): Promise<Config> {\n const resolvedPath = configPath ?? findConfigPath()\n\n if (!resolvedPath) {\n throw new ConfigNotFoundError(\n 'Configuration file not found. Expected .attest-it/config.yaml, .attest-it/config.yml, or .attest-it/config.json',\n )\n }\n\n try {\n const content = await readFile(resolvedPath, 'utf8')\n const format = getConfigFormat(resolvedPath)\n return parseConfigContent(content, format)\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error\n }\n throw new ConfigNotFoundError(\n `Failed to read configuration file at ${resolvedPath}: ${String(error)}`,\n )\n }\n}\n\n/**\n * Load and validate configuration from a file (sync).\n *\n * @param configPath - Optional path to config file. If not provided, searches default locations.\n * @returns Validated configuration object\n * @throws {@link ConfigNotFoundError} If config file cannot be found\n * @throws {@link ConfigValidationError} If validation fails\n * @public\n */\nexport function loadConfigSync(configPath?: string): Config {\n const resolvedPath = configPath ?? findConfigPath()\n\n if (!resolvedPath) {\n throw new ConfigNotFoundError(\n 'Configuration file not found. Expected .attest-it/config.yaml, .attest-it/config.yml, or .attest-it/config.json',\n )\n }\n\n try {\n const content = readFileSync(resolvedPath, 'utf8')\n const format = getConfigFormat(resolvedPath)\n return parseConfigContent(content, format)\n } catch (error) {\n if (error instanceof ConfigValidationError) {\n throw error\n }\n throw new ConfigNotFoundError(\n `Failed to read configuration file at ${resolvedPath}: ${String(error)}`,\n )\n }\n}\n\n/**\n * Resolve relative paths in the configuration against the repository root.\n *\n * This converts relative paths in settings.publicKeyPath and settings.attestationsPath\n * to absolute paths relative to the repository root.\n *\n * @param config - The configuration object\n * @param repoRoot - Absolute path to the repository root\n * @returns Configuration with resolved absolute paths\n * @public\n */\nexport function resolveConfigPaths(config: Config, repoRoot: string): Config {\n return {\n ...config,\n settings: {\n ...config.settings,\n publicKeyPath: resolve(repoRoot, config.settings.publicKeyPath),\n attestationsPath: resolve(repoRoot, config.settings.attestationsPath),\n },\n }\n}\n\n/**\n * Convert Zod-validated Config to AttestItConfig by removing undefined values.\n *\n * The Config type (from Zod) has optional fields as `T | undefined`,\n * while AttestItConfig has optional fields as `T?` (can be absent, not undefined).\n *\n * This adapter removes any undefined values to match the AttestItConfig interface\n * that the core functions expect.\n *\n * @param config - The Zod-validated configuration from loadConfig()\n * @returns Configuration compatible with AttestItConfig\n * @public\n */\nexport function toAttestItConfig(config: Config): import('./types.js').AttestItConfig {\n const result: import('./types.js').AttestItConfig = {\n version: config.version,\n settings: {\n maxAgeDays: config.settings.maxAgeDays,\n publicKeyPath: config.settings.publicKeyPath,\n attestationsPath: config.settings.attestationsPath,\n },\n suites: {},\n }\n\n // Add optional settings fields\n if (config.settings.defaultCommand !== undefined) {\n result.settings.defaultCommand = config.settings.defaultCommand\n }\n if (config.settings.keyProvider !== undefined) {\n result.settings.keyProvider = {\n type: config.settings.keyProvider.type,\n ...(config.settings.keyProvider.options !== undefined && {\n options: config.settings.keyProvider.options,\n }),\n }\n }\n\n // Add optional top-level fields\n if (config.team !== undefined) {\n result.team = config.team\n }\n if (config.gates !== undefined) {\n result.gates = config.gates\n }\n if (config.groups !== undefined) {\n result.groups = config.groups\n }\n\n // Map suites\n result.suites = Object.fromEntries(\n Object.entries(config.suites).map(([name, suite]) => {\n const mappedSuite: import('./types.js').SuiteConfig = {}\n\n if (suite.gate !== undefined) mappedSuite.gate = suite.gate\n if (suite.packages !== undefined) mappedSuite.packages = suite.packages\n if (suite.description !== undefined) mappedSuite.description = suite.description\n if (suite.files !== undefined) mappedSuite.files = suite.files\n if (suite.ignore !== undefined) mappedSuite.ignore = suite.ignore\n if (suite.command !== undefined) mappedSuite.command = suite.command\n if (suite.timeout !== undefined) mappedSuite.timeout = suite.timeout\n if (suite.interactive !== undefined) mappedSuite.interactive = suite.interactive\n if (suite.invalidates !== undefined) mappedSuite.invalidates = suite.invalidates\n if (suite.depends_on !== undefined) mappedSuite.depends_on = suite.depends_on\n\n return [name, mappedSuite]\n }),\n )\n\n return result\n}\n","/**\n * Shared Zod schemas used by both policy and operational configuration.\n *\n * ============================================================================\n * IMPORTANT: DOCUMENTATION SYNC REQUIRED\n * ============================================================================\n * When modifying any schema in this file, you MUST also update:\n *\n * 1. README.md - Update the \"Configuration\" section's quick example\n * 2. docs/configuration.md - Update the comprehensive configuration reference\n * 3. Run `pnpm --filter @attest-it/core generate:schemas` to regenerate JSON schemas\n *\n * The configuration format is a key part of the user experience. Any schema\n * changes should be reflected in user-facing documentation.\n * ============================================================================\n */\n\nimport ms from 'ms'\nimport { z } from 'zod'\n\n/**\n * Zod schema for a team member configuration.\n * @public\n */\nexport const teamMemberSchema = z\n .object({\n name: z.string().min(1, 'Team member name cannot be empty'),\n email: z.string().email().optional(),\n github: z.string().min(1).optional(),\n publicKey: z.string().min(1, 'Public key is required'),\n })\n .strict()\n\n/**\n * Zod schema for fingerprint configuration.\n * @public\n */\nexport const fingerprintConfigSchema = z\n .object({\n paths: z\n .array(z.string().min(1, 'Path cannot be empty'))\n .min(1, 'At least one path is required'),\n exclude: z.array(z.string().min(1, 'Exclude pattern cannot be empty')).optional(),\n })\n .strict()\n\n/**\n * Zod schema for duration strings.\n * Validates and parses duration strings like \"30d\", \"7d\", \"24h\".\n * @public\n */\nexport const durationSchema = z.string().refine(\n (val) => {\n try {\n // Type assertion needed because ms has strict StringValue type\n // We validate the result is a positive number below\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument, @typescript-eslint/consistent-type-assertions\n const parsed = ms(val as any)\n return typeof parsed === 'number' && parsed > 0\n } catch {\n return false\n }\n },\n {\n message: 'Duration must be a valid duration string (e.g., \"30d\", \"7d\", \"24h\")',\n },\n)\n\n/**\n * Zod schema for a gate configuration.\n * @public\n */\nexport const gateSchema = z\n .object({\n name: z.string().min(1, 'Gate name cannot be empty'),\n description: z.string().min(1, 'Gate description cannot be empty'),\n authorizedSigners: z\n .array(z.string().min(1, 'Authorized signer slug cannot be empty'))\n .min(1, 'At least one authorized signer is required'),\n fingerprint: fingerprintConfigSchema,\n maxAge: durationSchema,\n })\n .strict()\n\n/**\n * Zod schema for key provider configuration options.\n * @public\n */\nexport const keyProviderOptionsSchema = z\n .object({\n privateKeyPath: z.string().optional(),\n account: z.string().optional(),\n vault: z.string().optional(),\n itemName: z.string().optional(),\n })\n .passthrough()\n\n/**\n * Zod schema for key provider configuration.\n * @public\n */\nexport const keyProviderSchema = z\n .object({\n type: z.enum(['filesystem', '1password']).or(z.string()),\n options: keyProviderOptionsSchema.optional(),\n })\n .strict()\n","/**\n * Policy configuration schema and validation for attest-it.\n *\n * Policy files contain trust and security-critical configuration that should\n * be loaded from the default branch to prevent tampering by PR authors.\n *\n * ============================================================================\n * IMPORTANT: DOCUMENTATION SYNC REQUIRED\n * ============================================================================\n * When modifying any schema in this file, you MUST also update:\n *\n * 1. README.md - Update the \"Configuration\" section's quick example\n * 2. docs/configuration.md - Update the comprehensive configuration reference\n * 3. schemas/policy.schema.json - Run `pnpm --filter @attest-it/core generate:schemas`\n *\n * The configuration format is a key part of the user experience. Any schema\n * changes should be reflected in user-facing documentation.\n * ============================================================================\n */\n\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\nimport {\n durationSchema,\n fingerprintConfigSchema,\n gateSchema,\n teamMemberSchema,\n} from './shared-schemas.js'\n\n/**\n * Zod schema for policy settings (security-critical fields only).\n */\nconst policySettingsSchema = z\n .object({\n maxAgeDays: z.number().int().positive().default(30),\n publicKeyPath: z.string().default('.attest-it/pubkey.pem'),\n attestationsPath: z.string().default('.attest-it/attestations.json'),\n })\n .strict()\n\n/**\n * Zod schema for the policy configuration file.\n *\n * Policy files define:\n * - Security settings (key paths, attestation storage, max age)\n * - Team members and their public keys\n * - Gates with authorization rules\n *\n * @public\n */\nexport const policySchema = z\n .object({\n version: z.literal(1),\n settings: policySettingsSchema.default({}),\n team: z.record(z.string(), teamMemberSchema).optional(),\n gates: z.record(z.string(), gateSchema).optional(),\n })\n .strict()\n\n/**\n * Policy configuration type inferred from the Zod schema.\n * @public\n */\nexport type PolicyConfig = z.infer<typeof policySchema>\n\n/**\n * Error thrown when policy configuration is invalid.\n * @public\n */\nexport class PolicyValidationError extends Error {\n constructor(\n message: string,\n public readonly issues: z.ZodIssue[],\n ) {\n super(message)\n this.name = 'PolicyValidationError'\n }\n}\n\n/**\n * Parse policy configuration content from a string.\n *\n * @param content - The policy file content\n * @param format - The format of the content ('yaml' or 'json')\n * @returns Parsed and validated policy configuration\n * @throws {@link PolicyValidationError} If validation fails\n * @public\n */\nexport function parsePolicyContent(content: string, format: 'yaml' | 'json'): PolicyConfig {\n let rawConfig: unknown\n\n try {\n if (format === 'yaml') {\n rawConfig = parseYaml(content)\n } else {\n rawConfig = JSON.parse(content)\n }\n } catch (error) {\n throw new PolicyValidationError(\n `Failed to parse ${format.toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`,\n [],\n )\n }\n\n const result = policySchema.safeParse(rawConfig)\n\n if (!result.success) {\n throw new PolicyValidationError(\n 'Policy validation failed:\\n' +\n result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n'),\n result.error.issues,\n )\n }\n\n return result.data\n}\n\n// Re-export shared schemas for convenience\nexport { durationSchema, fingerprintConfigSchema, gateSchema, teamMemberSchema }\n","/**\n * Operational configuration schema and validation for attest-it.\n *\n * Operational files contain non-security-critical configuration that can\n * be loaded from PR branches (e.g., suite definitions, command execution settings).\n *\n * ============================================================================\n * IMPORTANT: DOCUMENTATION SYNC REQUIRED\n * ============================================================================\n * When modifying any schema in this file, you MUST also update:\n *\n * 1. README.md - Update the \"Configuration\" section's quick example\n * 2. docs/configuration.md - Update the comprehensive configuration reference\n * 3. schemas/config.schema.json - Run `pnpm --filter @attest-it/core generate:schemas`\n *\n * The configuration format is a key part of the user experience. Any schema\n * changes should be reflected in user-facing documentation.\n * ============================================================================\n */\n\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\nimport { keyProviderSchema } from './shared-schemas.js'\n\n/**\n * Zod schema for operational settings (non-security-critical fields only).\n */\nconst operationalSettingsSchema = z\n .object({\n defaultCommand: z.string().optional(),\n keyProvider: keyProviderSchema.optional(),\n })\n .strict()\n\n/**\n * Zod schema for a suite configuration.\n * Suites are CLI-layer extensions of gates with command execution capabilities.\n * For backward compatibility, suites can define their own fingerprint via packages/files/ignore.\n */\nconst suiteSchema = z\n .object({\n // Gate fields (if present, this suite references a gate)\n gate: z.string().optional(),\n // Legacy fingerprint definition (for backward compatibility)\n description: z.string().optional(),\n packages: z.array(z.string().min(1, 'Package path cannot be empty')).optional(),\n files: z.array(z.string().min(1, 'File path cannot be empty')).optional(),\n ignore: z.array(z.string().min(1, 'Ignore pattern cannot be empty')).optional(),\n // CLI-specific fields\n command: z.string().optional(),\n timeout: z.string().optional(),\n interactive: z.boolean().optional(),\n // Relationship fields\n invalidates: z.array(z.string().min(1, 'Invalidated suite name cannot be empty')).optional(),\n depends_on: z.array(z.string().min(1, 'Dependency suite name cannot be empty')).optional(),\n })\n .strict()\n .refine(\n (suite) => {\n // Either gate is specified, or packages is specified (for legacy compatibility)\n return suite.gate !== undefined || (suite.packages !== undefined && suite.packages.length > 0)\n },\n {\n message: 'Suite must either reference a gate or define packages for fingerprinting',\n },\n )\n\n/**\n * Zod schema for the operational configuration file.\n *\n * Operational files define:\n * - Command execution settings (default command, key provider)\n * - Suite definitions with command execution details\n * - Suite groups for organizational purposes\n *\n * @public\n */\nexport const operationalSchema = z\n .object({\n version: z.literal(1),\n settings: operationalSettingsSchema.default({}),\n suites: z.record(z.string(), suiteSchema).refine((suites) => Object.keys(suites).length >= 1, {\n message: 'At least one suite must be defined',\n }),\n groups: z\n .record(z.string(), z.array(z.string().min(1, 'Suite name in group cannot be empty')))\n .optional(),\n })\n .strict()\n\n/**\n * Operational configuration type inferred from the Zod schema.\n * @public\n */\nexport type OperationalConfig = z.infer<typeof operationalSchema>\n\n/**\n * Error thrown when operational configuration is invalid.\n * @public\n */\nexport class OperationalValidationError extends Error {\n constructor(\n message: string,\n public readonly issues: z.ZodIssue[],\n ) {\n super(message)\n this.name = 'OperationalValidationError'\n }\n}\n\n/**\n * Parse operational configuration content from a string.\n *\n * @param content - The operational config file content\n * @param format - The format of the content ('yaml' or 'json')\n * @returns Parsed and validated operational configuration\n * @throws {@link OperationalValidationError} If validation fails\n * @public\n */\nexport function parseOperationalContent(\n content: string,\n format: 'yaml' | 'json',\n): OperationalConfig {\n let rawConfig: unknown\n\n try {\n if (format === 'yaml') {\n rawConfig = parseYaml(content)\n } else {\n rawConfig = JSON.parse(content)\n }\n } catch (error) {\n throw new OperationalValidationError(\n `Failed to parse ${format.toUpperCase()}: ${error instanceof Error ? error.message : String(error)}`,\n [],\n )\n }\n\n const result = operationalSchema.safeParse(rawConfig)\n\n if (!result.success) {\n throw new OperationalValidationError(\n 'Operational configuration validation failed:\\n' +\n result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n'),\n result.error.issues,\n )\n }\n\n return result.data\n}\n\n// Re-export suite schema for convenience\nexport { suiteSchema }\n","/**\n * Merge policy and operational configurations into a unified AttestItConfig.\n *\n * This module handles the combination of security-critical policy configuration\n * (loaded from the default branch) with operational configuration (can be loaded\n * from PR branches) to create the complete configuration used for attestation\n * verification.\n *\n * @packageDocumentation\n */\n\nimport type {\n AttestItConfig,\n GateConfig,\n KeyProviderSettings,\n SuiteConfig,\n TeamMember,\n} from '../types.js'\nimport type { OperationalConfig } from './operational-schema.js'\nimport type { PolicyConfig } from './policy-schema.js'\n\n/**\n * Converts a Zod-inferred suite config to the AttestItConfig suite type.\n * Filters out undefined values to match exactOptionalPropertyTypes requirements.\n */\nfunction toSuiteConfig(suite: OperationalConfig['suites'][string]): SuiteConfig {\n const result: SuiteConfig = {}\n\n if (suite.gate !== undefined) result.gate = suite.gate\n if (suite.description !== undefined) result.description = suite.description\n if (suite.packages !== undefined) result.packages = suite.packages\n if (suite.files !== undefined) result.files = suite.files\n if (suite.ignore !== undefined) result.ignore = suite.ignore\n if (suite.command !== undefined) result.command = suite.command\n if (suite.timeout !== undefined) result.timeout = suite.timeout\n if (suite.interactive !== undefined) result.interactive = suite.interactive\n if (suite.invalidates !== undefined) result.invalidates = suite.invalidates\n if (suite.depends_on !== undefined) result.depends_on = suite.depends_on\n\n return result\n}\n\n/**\n * Converts a Zod-inferred team member to the AttestItConfig team member type.\n * Filters out undefined values to match exactOptionalPropertyTypes requirements.\n */\nfunction toTeamMember(member: NonNullable<PolicyConfig['team']>[string]): TeamMember {\n const result: TeamMember = {\n name: member.name,\n publicKey: member.publicKey,\n }\n\n if (member.email !== undefined) result.email = member.email\n if (member.github !== undefined) result.github = member.github\n\n return result\n}\n\n/**\n * Converts a Zod-inferred gate config to the AttestItConfig gate type.\n * Filters out undefined values to match exactOptionalPropertyTypes requirements.\n */\nfunction toGateConfig(gate: NonNullable<PolicyConfig['gates']>[string]): GateConfig {\n const fingerprint: GateConfig['fingerprint'] = {\n paths: gate.fingerprint.paths,\n }\n\n if (gate.fingerprint.exclude !== undefined) {\n fingerprint.exclude = gate.fingerprint.exclude\n }\n\n return {\n name: gate.name,\n description: gate.description,\n authorizedSigners: gate.authorizedSigners,\n fingerprint,\n maxAge: gate.maxAge,\n }\n}\n\n/**\n * Converts a Zod-inferred key provider to the AttestItConfig key provider type.\n * Filters out undefined values to match exactOptionalPropertyTypes requirements.\n */\nfunction toKeyProvider(\n provider: NonNullable<OperationalConfig['settings']['keyProvider']>,\n): KeyProviderSettings {\n const result: KeyProviderSettings = {\n type: provider.type,\n }\n\n if (provider.options !== undefined) {\n const options: NonNullable<KeyProviderSettings['options']> = {}\n let hasOptions = false\n\n if (provider.options.privateKeyPath !== undefined) {\n options.privateKeyPath = provider.options.privateKeyPath\n hasOptions = true\n }\n if (provider.options.account !== undefined) {\n options.account = provider.options.account\n hasOptions = true\n }\n if (provider.options.vault !== undefined) {\n options.vault = provider.options.vault\n hasOptions = true\n }\n if (provider.options.itemName !== undefined) {\n options.itemName = provider.options.itemName\n hasOptions = true\n }\n\n if (hasOptions) {\n result.options = options\n }\n }\n\n return result\n}\n\n/**\n * Merges policy and operational configurations into a single AttestItConfig.\n *\n * The merge strategy prioritizes security-critical fields from the policy\n * configuration while combining operational fields from both sources:\n *\n * - **Policy settings** (maxAgeDays, publicKeyPath, attestationsPath) are used as-is\n * - **Operational settings** (defaultCommand, keyProvider) are added from operational config\n * - **Team and gates** come exclusively from policy config\n * - **Suites and groups** come exclusively from operational config\n *\n * @param policy - The policy configuration containing security-critical settings\n * @param operational - The operational configuration containing suites and execution settings\n * @returns A complete AttestItConfig ready for use in attestation operations\n *\n * @example\n * ```typescript\n * const policy = parsePolicyContent(policyYaml, 'yaml')\n * const operational = parseOperationalContent(operationalYaml, 'yaml')\n * const config = mergeConfigs(policy, operational)\n * ```\n *\n * @public\n */\nexport function mergeConfigs(policy: PolicyConfig, operational: OperationalConfig): AttestItConfig {\n const settings: AttestItConfig['settings'] = {\n // Security settings from policy (these are trust-critical)\n maxAgeDays: policy.settings.maxAgeDays,\n publicKeyPath: policy.settings.publicKeyPath,\n attestationsPath: policy.settings.attestationsPath,\n }\n\n // Add operational settings only if defined\n if (operational.settings.defaultCommand !== undefined) {\n settings.defaultCommand = operational.settings.defaultCommand\n }\n if (operational.settings.keyProvider !== undefined) {\n settings.keyProvider = toKeyProvider(operational.settings.keyProvider)\n }\n\n // Convert suites\n const suites: Record<string, SuiteConfig> = {}\n for (const [name, suite] of Object.entries(operational.suites)) {\n // eslint-disable-next-line security/detect-object-injection\n suites[name] = toSuiteConfig(suite)\n }\n\n const config: AttestItConfig = {\n version: 1,\n settings,\n suites,\n }\n\n // Add team from policy if defined\n if (policy.team !== undefined) {\n const team: Record<string, TeamMember> = {}\n for (const [slug, member] of Object.entries(policy.team)) {\n // eslint-disable-next-line security/detect-object-injection\n team[slug] = toTeamMember(member)\n }\n config.team = team\n }\n\n // Add gates from policy if defined\n if (policy.gates !== undefined) {\n const gates: Record<string, GateConfig> = {}\n for (const [slug, gate] of Object.entries(policy.gates)) {\n // eslint-disable-next-line security/detect-object-injection\n gates[slug] = toGateConfig(gate)\n }\n config.gates = gates\n }\n\n // Add groups from operational config if defined\n if (operational.groups !== undefined) {\n config.groups = operational.groups\n }\n\n return config\n}\n","/**\n * Cross-configuration validation for split policy and operational configs.\n *\n * This module validates relationships between policy and operational configurations,\n * ensuring that suite-gate references are valid and that all authorized signers\n * are defined in the team.\n *\n * @packageDocumentation\n */\n\nimport type { OperationalConfig } from './operational-schema.js'\nimport type { PolicyConfig } from './policy-schema.js'\n\n/**\n * Validation error types for cross-configuration validation.\n * @public\n */\nexport type ValidationErrorType = 'UNKNOWN_GATE' | 'MISSING_TEAM_MEMBER'\n\n/**\n * Represents a validation error found during cross-configuration validation.\n * @public\n */\nexport interface ValidationError {\n /** The type of validation error */\n type: ValidationErrorType\n /** The suite name where the error was found (if applicable) */\n suite?: string\n /** The gate name involved in the error (if applicable) */\n gate?: string\n /** The signer slug that is missing (if applicable) */\n signer?: string\n /** Human-readable error message explaining the issue */\n message: string\n}\n\n/**\n * Validates that all suite-gate references and authorized signers are valid.\n *\n * This function performs cross-configuration validation to ensure:\n * 1. Every suite that references a gate refers to an existing gate in the policy\n * 2. Every authorized signer in each referenced gate is defined in the policy team\n *\n * These validations are critical because:\n * - Operational config (suites) can come from PR branches\n * - Policy config (gates, team) comes from the default branch\n * - We must ensure PR authors cannot reference non-existent gates or signers\n *\n * @param policy - The policy configuration containing gates and team definitions\n * @param operational - The operational configuration containing suite definitions\n * @returns An array of validation errors (empty if validation passes)\n *\n * @example\n * ```typescript\n * const errors = validateSuiteGateReferences(policy, operational)\n * if (errors.length > 0) {\n * console.error('Validation failed:')\n * for (const error of errors) {\n * console.error(` - ${error.message}`)\n * }\n * throw new Error('Configuration validation failed')\n * }\n * ```\n *\n * @public\n */\nexport function validateSuiteGateReferences(\n policy: PolicyConfig,\n operational: OperationalConfig,\n): ValidationError[] {\n const errors: ValidationError[] = []\n const gates = policy.gates ?? {}\n const team = policy.team ?? {}\n\n // Validate each suite that references a gate\n for (const [suiteName, suiteConfig] of Object.entries(operational.suites)) {\n const gateName = suiteConfig.gate\n\n // Skip suites that don't reference a gate (legacy fingerprint-based suites)\n if (gateName === undefined) {\n continue\n }\n\n // Check if the referenced gate exists in the policy\n // eslint-disable-next-line security/detect-object-injection\n const gate = gates[gateName]\n if (gate === undefined) {\n errors.push({\n type: 'UNKNOWN_GATE',\n suite: suiteName,\n gate: gateName,\n message: `Suite \"${suiteName}\" references unknown gate \"${gateName}\". The gate must be defined in policy.yaml.`,\n })\n continue\n }\n\n // Validate that all authorized signers exist in the team\n for (const signerSlug of gate.authorizedSigners) {\n // eslint-disable-next-line security/detect-object-injection\n if (team[signerSlug] === undefined) {\n errors.push({\n type: 'MISSING_TEAM_MEMBER',\n suite: suiteName,\n gate: gateName,\n signer: signerSlug,\n message: `Gate \"${gateName}\" (referenced by suite \"${suiteName}\") authorizes signer \"${signerSlug}\", but this team member is not defined in policy.yaml.`,\n })\n }\n }\n }\n\n return errors\n}\n","import * as crypto from 'node:crypto'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { glob, globSync } from 'tinyglobby'\n\n/**\n * Threshold for streaming large files instead of reading into memory.\n * Files larger than this will be hashed via streaming to avoid memory issues.\n */\nconst LARGE_FILE_THRESHOLD = 50 * 1024 * 1024 // 50MB\n\n/**\n * Options for computing a package fingerprint.\n * @public\n */\nexport interface FingerprintOptions {\n /** Package directories to include */\n packages: string[]\n /** Glob patterns to exclude from fingerprint */\n ignore?: string[]\n /** Base directory for resolving paths */\n baseDir?: string\n}\n\n/**\n * Result of computing a package fingerprint.\n * @public\n */\nexport interface FingerprintResult {\n /** The fingerprint in \"sha256:...\" format */\n fingerprint: string\n /** List of files included in fingerprint calculation */\n files: string[]\n /** Number of files processed */\n fileCount: number\n}\n\n/**\n * Internal representation of a file hash for fingerprint computation.\n */\ninterface FileHashInput {\n /** The normalized relative path of the file */\n relativePath: string\n /** The computed hash of the file content */\n hash: Buffer\n}\n\n/**\n * Sort files lexicographically (locale-independent).\n */\nfunction sortFiles(files: string[]): string[] {\n return [...files].sort((a, b) => {\n if (a < b) return -1\n if (a > b) return 1\n return 0\n })\n}\n\n/**\n * Normalize path separators to forward slashes.\n */\nfunction normalizePath(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\n/**\n * Compute final fingerprint from file hashes.\n */\nfunction computeFinalFingerprint(fileHashes: FileHashInput[]): string {\n // Sort by relative path\n const sorted = [...fileHashes].sort((a, b) => {\n if (a.relativePath < b.relativePath) return -1\n if (a.relativePath > b.relativePath) return 1\n return 0\n })\n\n // Concatenate all file hashes\n const hashes = sorted.map((input) => input.hash)\n const concatenated = Buffer.concat(hashes)\n\n // Compute final hash\n const finalHash = crypto.createHash('sha256').update(concatenated).digest()\n return `sha256:${finalHash.toString('hex')}`\n}\n\n/**\n * Hash a file's content using streaming for large files (async).\n * For files larger than LARGE_FILE_THRESHOLD, uses streaming to avoid memory issues.\n */\nasync function hashFileAsync(\n realPath: string,\n normalizedPath: string,\n stats: fs.Stats,\n): Promise<Buffer> {\n if (stats.size > LARGE_FILE_THRESHOLD) {\n // Stream large files to avoid memory issues\n return new Promise((resolve, reject) => {\n const hash = crypto.createHash('sha256')\n hash.update(normalizedPath)\n hash.update(':')\n\n const stream = fs.createReadStream(realPath)\n stream.on('data', (chunk: string | Buffer) => {\n hash.update(chunk)\n })\n stream.on('end', () => {\n resolve(hash.digest())\n })\n stream.on('error', reject)\n })\n }\n\n // Read small files into memory (faster than streaming)\n const content = await fs.promises.readFile(realPath)\n const hash = crypto.createHash('sha256')\n hash.update(normalizedPath)\n hash.update(':')\n hash.update(content)\n return hash.digest()\n}\n\n/**\n * Hash a file's content synchronously.\n * Note: Cannot stream synchronously, so large files are read into memory.\n */\nfunction hashFileSync(realPath: string, normalizedPath: string): Buffer {\n const content = fs.readFileSync(realPath)\n const hash = crypto.createHash('sha256')\n hash.update(normalizedPath)\n hash.update(':')\n hash.update(content)\n return hash.digest()\n}\n\n/**\n * Validate fingerprint options and return base directory.\n */\nfunction validateOptions(options: FingerprintOptions): string {\n if (options.packages.length === 0) {\n throw new Error('packages array must not be empty')\n }\n\n const baseDir = options.baseDir ?? process.cwd()\n\n // Verify all package paths exist\n for (const pkg of options.packages) {\n const pkgPath = path.resolve(baseDir, pkg)\n if (!fs.existsSync(pkgPath)) {\n throw new Error(`Package path does not exist: ${pkgPath}`)\n }\n }\n\n return baseDir\n}\n\n/**\n * Compute a deterministic fingerprint for a set of packages (async).\n *\n * Algorithm:\n * 1. List all files in packages (respecting ignore globs)\n * 2. Sort files lexicographically by relative path\n * 3. For each file: compute SHA256(relativePath + \":\" + content)\n * 4. Concatenate all file hashes in sorted order\n * 5. Compute final SHA256 of concatenated hashes\n * 6. Return \"sha256:\" + hex(fingerprint)\n *\n * @param options - Configuration for fingerprint computation\n * @returns Result containing the fingerprint hash and list of files processed\n * @throws Error if packages array is empty or if package paths don't exist\n * @public\n */\nexport async function computeFingerprint(options: FingerprintOptions): Promise<FingerprintResult> {\n const baseDir = validateOptions(options)\n\n // List all files in packages\n const files = await listPackageFiles(options.packages, options.ignore, baseDir)\n\n // Sort files lexicographically\n const sortedFiles = sortFiles(files)\n\n // Track visited files to handle multiple symlinks pointing to the same file\n // Key: realpath, Value: file hash\n const fileHashCache = new Map<string, Buffer>()\n\n // Compute individual file hashes\n const fileHashInputs: FileHashInput[] = []\n for (const file of sortedFiles) {\n const filePath = path.resolve(baseDir, file)\n\n // Handle symlinks\n let realPath = filePath\n let stats = await fs.promises.lstat(filePath)\n\n if (stats.isSymbolicLink()) {\n try {\n realPath = await fs.promises.realpath(filePath)\n } catch {\n // Skip broken symlinks\n continue\n }\n\n // Get stats of the target\n try {\n stats = await fs.promises.stat(realPath)\n } catch {\n // Skip broken symlinks\n continue\n }\n }\n\n // Skip if not a file (e.g., directories)\n if (!stats.isFile()) {\n continue\n }\n\n // Normalize path separators to forward slashes\n const normalizedPath = normalizePath(file)\n\n // Check if we've already hashed this file (via symlinks)\n let hash: Buffer\n const cachedHash = fileHashCache.get(realPath)\n if (cachedHash !== undefined) {\n // Reuse cached hash for files we've already seen (via symlinks)\n hash = cachedHash\n } else {\n // Hash the file content\n hash = await hashFileAsync(realPath, normalizedPath, stats)\n fileHashCache.set(realPath, hash)\n }\n\n fileHashInputs.push({ relativePath: normalizedPath, hash })\n }\n\n // Compute final fingerprint\n const fingerprint = computeFinalFingerprint(fileHashInputs)\n\n return {\n fingerprint,\n files: sortedFiles,\n fileCount: sortedFiles.length,\n }\n}\n\n/**\n * Compute a deterministic fingerprint for a set of packages (sync).\n *\n * @param options - Configuration for fingerprint computation\n * @returns Result containing the fingerprint hash and list of files processed\n * @throws Error if packages array is empty or if package paths don't exist\n * @public\n * @see {@link computeFingerprint} for the async version\n */\nexport function computeFingerprintSync(options: FingerprintOptions): FingerprintResult {\n const baseDir = validateOptions(options)\n\n // List all files in packages (sync version)\n const files = listPackageFilesSync(options.packages, options.ignore, baseDir)\n\n // Sort files lexicographically\n const sortedFiles = sortFiles(files)\n\n // Track visited files to handle multiple symlinks pointing to the same file\n // Key: realpath, Value: file hash\n const fileHashCache = new Map<string, Buffer>()\n\n // Compute individual file hashes\n const fileHashInputs: FileHashInput[] = []\n for (const file of sortedFiles) {\n const filePath = path.resolve(baseDir, file)\n\n // Handle symlinks\n let realPath = filePath\n let stats = fs.lstatSync(filePath)\n\n if (stats.isSymbolicLink()) {\n try {\n realPath = fs.realpathSync(filePath)\n } catch {\n // Skip broken symlinks\n continue\n }\n\n // Get stats of the target\n try {\n stats = fs.statSync(realPath)\n } catch {\n // Skip broken symlinks\n continue\n }\n }\n\n // Skip if not a file (e.g., directories)\n if (!stats.isFile()) {\n continue\n }\n\n // Normalize path separators to forward slashes\n const normalizedPath = normalizePath(file)\n\n // Check if we've already hashed this file (via symlinks)\n let hash: Buffer\n const cachedHash = fileHashCache.get(realPath)\n if (cachedHash !== undefined) {\n // Reuse cached hash for files we've already seen (via symlinks)\n hash = cachedHash\n } else {\n // Hash the file content (sync version cannot stream)\n hash = hashFileSync(realPath, normalizedPath)\n fileHashCache.set(realPath, hash)\n }\n\n fileHashInputs.push({ relativePath: normalizedPath, hash })\n }\n\n // Compute final fingerprint\n const fingerprint = computeFinalFingerprint(fileHashInputs)\n\n return {\n fingerprint,\n files: sortedFiles,\n fileCount: sortedFiles.length,\n }\n}\n\n/**\n * List files in packages, respecting ignore patterns (async).\n *\n * @param packages - Array of package directory paths\n * @param ignore - Optional glob patterns to exclude\n * @param baseDir - Base directory for resolving paths (defaults to cwd)\n * @returns Array of relative file paths\n * @public\n */\nexport async function listPackageFiles(\n packages: string[],\n ignore: string[] = [],\n baseDir: string = process.cwd(),\n): Promise<string[]> {\n const allFiles: string[] = []\n\n for (const pkg of packages) {\n // Build glob patterns for this package\n const patterns = [`${pkg}/**/*`]\n\n // Use tinyglobby to find files\n const files = await glob(patterns, {\n cwd: baseDir,\n ignore,\n onlyFiles: true,\n dot: true, // Include dotfiles\n absolute: false, // Return relative paths\n })\n\n allFiles.push(...files)\n }\n\n return allFiles\n}\n\n/**\n * Synchronous version of listPackageFiles\n */\nfunction listPackageFilesSync(\n packages: string[],\n ignore: string[] = [],\n baseDir: string = process.cwd(),\n): string[] {\n const allFiles: string[] = []\n\n for (const pkg of packages) {\n // Build glob patterns for this package\n const patterns = [`${pkg}/**/*`]\n\n // Use tinyglobby to find files (sync version)\n const files = globSync(patterns, {\n cwd: baseDir,\n ignore,\n onlyFiles: true,\n dot: true, // Include dotfiles\n absolute: false, // Return relative paths\n })\n\n allFiles.push(...files)\n }\n\n return allFiles\n}\n","/**\n * Attestation file I/O module with JSON canonicalization.\n */\n\nimport * as fs from 'node:fs'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport * as canonicalizeNamespace from 'canonicalize'\nimport { z } from 'zod'\nimport type { Attestation, AttestationsFile } from './types.js'\n\n/**\n * Extract the serialize function from the canonicalize CommonJS module.\n *\n * Context: The canonicalize package uses `module.exports = function(...)`, which is\n * a CommonJS pattern. With `esModuleInterop: false` (required for library code to\n * avoid leaking tsconfig options to consumers), TypeScript treats the namespace import\n * as the module object itself, not as an object with a default export.\n *\n * The package's type definitions declare `export default function serialize(...)`,\n * which TypeScript interprets as `{ default: function }` when esModuleInterop is off.\n * However, at runtime with NodeNext module resolution, the actual value is just the\n * function itself.\n *\n * This type assertion is safe because:\n * 1. We verified the runtime export structure of the canonicalize module\n * 2. The type matches the published @types signature\n * 3. This is the standard pattern for importing CommonJS modules in strict ESM\n */\n// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\nconst canonicalize = canonicalizeNamespace as unknown as {\n default: (input: unknown) => string | undefined\n}\nconst serialize = canonicalize.default\n\n// Zod schema for attestation validation\nconst attestationSchema = z.object({\n suite: z.string().min(1),\n fingerprint: z.string().regex(/^sha256:[a-f0-9]{64}$/),\n attestedAt: z.string().datetime(),\n attestedBy: z.string().min(1),\n command: z.string().min(1),\n exitCode: z.literal(0),\n})\n\nconst attestationsFileSchema = z.object({\n schemaVersion: z.literal('1'),\n attestations: z.array(attestationSchema),\n signature: z.string(), // Will be validated by crypto module\n})\n\n/**\n * Type guard to check if an error is a Node.js file system error with code.\n * We need to disable the type assertion rule here because TypeScript doesn't\n * provide a way to narrow an object type after checking for a property without\n * using type assertions or indexed access. This is a safe assertion because we\n * check for the property existence and type before using it.\n */\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n if (error === null || typeof error !== 'object') {\n return false\n }\n if (!('code' in error)) {\n return false\n }\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const errorObj = error as Record<string, unknown>\n return typeof errorObj.code === 'string'\n}\n\n/**\n * Read attestations file from disk (async).\n *\n * @param filePath - Absolute path to the attestations JSON file\n * @returns Parsed attestations file, or null if the file doesn't exist\n * @throws Error on parse or validation errors\n * @public\n */\nexport async function readAttestations(filePath: string): Promise<AttestationsFile | null> {\n try {\n const content = await fs.promises.readFile(filePath, 'utf-8')\n const parsed: unknown = JSON.parse(content)\n // Zod validates and returns the correct type\n return attestationsFileSchema.parse(parsed)\n } catch (error) {\n if (isNodeError(error) && error.code === 'ENOENT') {\n return null\n }\n throw error\n }\n}\n\n/**\n * Read attestations file from disk (sync).\n *\n * @param filePath - Absolute path to the attestations JSON file\n * @returns Parsed attestations file, or null if the file doesn't exist\n * @throws Error on parse or validation errors\n * @public\n */\nexport function readAttestationsSync(filePath: string): AttestationsFile | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8')\n const parsed: unknown = JSON.parse(content)\n // Zod validates and returns the correct type\n return attestationsFileSchema.parse(parsed)\n } catch (error) {\n if (isNodeError(error) && error.code === 'ENOENT') {\n return null\n }\n throw error\n }\n}\n\n/**\n * Write attestations file to disk (async).\n *\n * Creates parent directories if needed. The signature should be computed\n * separately and passed in.\n *\n * @param filePath - Absolute path to write the attestations file\n * @param attestations - Array of attestation entries\n * @param signature - Cryptographic signature of the attestations\n * @throws Error on validation or write errors\n * @public\n */\nexport async function writeAttestations(\n filePath: string,\n attestations: Attestation[],\n signature: string,\n): Promise<void> {\n const fileContent: AttestationsFile = {\n schemaVersion: '1',\n attestations,\n signature,\n }\n\n // Validate before writing\n attestationsFileSchema.parse(fileContent)\n\n // Create parent directories if needed\n const dir = path.dirname(filePath)\n await fs.promises.mkdir(dir, { recursive: true })\n\n // Write with pretty formatting for readability\n const json = JSON.stringify(fileContent, null, 2)\n await fs.promises.writeFile(filePath, json, 'utf-8')\n}\n\n/**\n * Write attestations file to disk (sync).\n *\n * Creates parent directories if needed. The signature should be computed\n * separately and passed in.\n *\n * @param filePath - Absolute path to write the attestations file\n * @param attestations - Array of attestation entries\n * @param signature - Cryptographic signature of the attestations\n * @throws Error on validation or write errors\n * @public\n */\nexport function writeAttestationsSync(\n filePath: string,\n attestations: Attestation[],\n signature: string,\n): void {\n const fileContent: AttestationsFile = {\n schemaVersion: '1',\n attestations,\n signature,\n }\n\n // Validate before writing\n attestationsFileSchema.parse(fileContent)\n\n // Create parent directories if needed\n const dir = path.dirname(filePath)\n fs.mkdirSync(dir, { recursive: true })\n\n // Write with pretty formatting for readability\n const json = JSON.stringify(fileContent, null, 2)\n fs.writeFileSync(filePath, json, 'utf-8')\n}\n\n/**\n * Find an attestation for a specific suite.\n *\n * @param attestations - Attestations file containing all attestations\n * @param suite - Name of the suite to find\n * @returns The attestation if found, undefined otherwise\n * @public\n */\nexport function findAttestation(\n attestations: AttestationsFile,\n suite: string,\n): Attestation | undefined {\n return attestations.attestations.find((a) => a.suite === suite)\n}\n\n/**\n * Add or update an attestation for a suite.\n *\n * This is an immutable operation that returns a new array.\n *\n * @param attestations - Current array of attestations\n * @param newAttestation - Attestation to add or update\n * @returns New attestations array with the upserted attestation\n * @throws Error if the new attestation fails validation\n * @public\n */\nexport function upsertAttestation(\n attestations: Attestation[],\n newAttestation: Attestation,\n): Attestation[] {\n // Validate the new attestation\n attestationSchema.parse(newAttestation)\n\n const existingIndex = attestations.findIndex((a) => a.suite === newAttestation.suite)\n\n if (existingIndex === -1) {\n // Add new attestation\n return [...attestations, newAttestation]\n } else {\n // Update existing attestation\n const updated = [...attestations]\n // eslint-disable-next-line security/detect-object-injection -- False positive: existingIndex is a safe number from findIndex\n updated[existingIndex] = newAttestation\n return updated\n }\n}\n\n/**\n * Remove attestations for a suite.\n *\n * This is an immutable operation that returns a new array.\n *\n * @param attestations - Current array of attestations\n * @param suite - Name of the suite to remove\n * @returns New attestations array without the specified suite\n * @public\n */\nexport function removeAttestation(attestations: Attestation[], suite: string): Attestation[] {\n return attestations.filter((a) => a.suite !== suite)\n}\n\n/**\n * Compute canonical JSON representation for signing.\n *\n * Implements RFC 8785 JSON Canonicalization Scheme. The canonicalize package provides:\n * 1. Keys sorted lexicographically (Unicode code point order)\n * 2. No whitespace between tokens\n * 3. No trailing commas\n * 4. Strings escaped using \\uXXXX for control characters\n * 5. Numbers: no leading zeros, no +, use lowercase 'e' for exponent\n * 6. UTF-8 encoding\n *\n * @param attestations - Array of attestations to canonicalize\n * @returns Canonical JSON string representation\n * @throws Error if canonicalization fails\n * @public\n */\nexport function canonicalizeAttestations(attestations: Attestation[]): string {\n const canonical = serialize(attestations)\n if (canonical === undefined) {\n throw new Error('Failed to canonicalize attestations')\n }\n return canonical\n}\n\n/**\n * Create a new attestation entry.\n *\n * @param params - Parameters for creating the attestation\n * @param params.suite - Name of the test suite\n * @param params.fingerprint - Fingerprint of the packages in sha256 format\n * @param params.command - Command that was executed\n * @param params.attestedBy - Optional username (defaults to current OS user)\n * @returns Validated attestation object\n * @throws Error if attestation validation fails\n * @public\n */\nexport function createAttestation(params: {\n suite: string\n fingerprint: string\n command: string\n attestedBy?: string\n}): Attestation {\n const attestation: Attestation = {\n suite: params.suite,\n fingerprint: params.fingerprint,\n attestedAt: new Date().toISOString(),\n attestedBy: params.attestedBy ?? os.userInfo().username,\n command: params.command,\n exitCode: 0,\n }\n\n // Validate before returning\n attestationSchema.parse(attestation)\n\n return attestation\n}\n\n/**\n * Options for writing signed attestations.\n * @public\n */\nexport interface WriteSignedAttestationsOptions {\n /** Path to write the attestations file */\n filePath: string\n /** Array of attestations to write */\n attestations: Attestation[]\n /** Path to the private key for signing (legacy) */\n privateKeyPath?: string\n /** Key provider for signing */\n keyProvider?: import('./key-provider/types.js').KeyProvider\n /** Key reference for the provider */\n keyRef?: string\n}\n\n/**\n * Options for reading and verifying signed attestations.\n * @public\n */\nexport interface ReadSignedAttestationsOptions {\n /** Path to read the attestations file from */\n filePath: string\n /** Path to the public key for verification */\n publicKeyPath: string\n}\n\n/**\n * Write attestations with a cryptographic signature.\n *\n * This function canonicalizes the attestations, signs them with the private key,\n * and writes the attestations file with the signature.\n *\n * @param options - Options for writing signed attestations\n * @throws Error if signing or writing fails\n * @public\n */\nexport async function writeSignedAttestations(\n options: WriteSignedAttestationsOptions,\n): Promise<void> {\n // Import sign function here to avoid circular dependency\n const { sign } = await import('./crypto.js')\n\n const { privateKeyPath, keyProvider, keyRef } = options\n\n // Validate that we have either legacy path or provider + ref\n if (!privateKeyPath && (!keyProvider || !keyRef)) {\n throw new Error(\n 'Either privateKeyPath or both keyProvider and keyRef must be provided for signing',\n )\n }\n\n const canonical = canonicalizeAttestations(options.attestations)\n\n // Build sign options, only including defined properties\n const signOptions: Parameters<typeof sign>[0] = {\n data: canonical,\n }\n\n if (privateKeyPath !== undefined) {\n signOptions.privateKeyPath = privateKeyPath\n }\n if (keyProvider !== undefined) {\n signOptions.keyProvider = keyProvider\n }\n if (keyRef !== undefined) {\n signOptions.keyRef = keyRef\n }\n\n const signature = await sign(signOptions)\n await writeAttestations(options.filePath, options.attestations, signature)\n}\n\n/**\n * Read attestations and verify the signature.\n *\n * This function reads the attestations file, canonicalizes the attestations,\n * and verifies the signature using the public key. It throws an error if the\n * file doesn't exist or if signature verification fails.\n *\n * @param options - Options for reading and verifying attestations\n * @returns The attestations file if signature is valid\n * @throws Error if attestations file not found\n * @throws SignatureInvalidError if signature verification fails\n * @public\n */\nexport async function readAndVerifyAttestations(\n options: ReadSignedAttestationsOptions,\n): Promise<AttestationsFile> {\n // Import verify function here to avoid circular dependency\n const { verify } = await import('./crypto.js')\n\n const file = await readAttestations(options.filePath)\n if (!file) {\n throw new Error(`Attestations file not found: ${options.filePath}`)\n }\n\n const canonical = canonicalizeAttestations(file.attestations)\n const isValid = await verify({\n publicKeyPath: options.publicKeyPath,\n data: canonical,\n signature: file.signature,\n })\n\n if (!isValid) {\n throw new SignatureInvalidError(options.filePath)\n }\n\n return file\n}\n\n/**\n * Error thrown when signature verification fails.\n * @public\n */\nexport class SignatureInvalidError extends Error {\n /**\n * Create a new SignatureInvalidError.\n * @param filePath - Path to the file that failed verification\n */\n constructor(filePath: string) {\n super(`Signature verification failed for: ${filePath}`)\n this.name = 'SignatureInvalidError'\n }\n}\n","/**\n * Ed25519 cryptographic operations using Node.js native crypto module.\n *\n * @remarks\n * This module provides Ed25519 digital signature operations using Node.js\n * native crypto support (available in Node 18+). Ed25519 offers better security\n * and performance than RSA-2048 with much smaller key and signature sizes.\n *\n * @packageDocumentation\n */\n\nimport * as crypto from 'node:crypto'\n\n/**\n * An Ed25519 keypair with base64-encoded public key and PEM-encoded private key.\n * @public\n */\nexport interface KeyPair {\n /** Base64-encoded public key (raw 32 bytes, ~44 characters) */\n publicKey: string\n /** PEM-encoded private key */\n privateKey: string\n}\n\n/**\n * Type guard to check if a value is a Buffer.\n * @param value - Value to check\n * @returns true if value is a Buffer\n * @internal\n */\nfunction isBuffer(value: unknown): value is Buffer {\n return Buffer.isBuffer(value)\n}\n\n/**\n * Generate a new Ed25519 keypair.\n *\n * @returns A keypair with base64-encoded public key and PEM-encoded private key\n * @throws Error if key generation fails\n * @public\n */\nexport function generateKeyPair(): KeyPair {\n try {\n // Generate Ed25519 keypair using Node.js native crypto\n // When format is 'pem', the keys are returned as strings\n const keyPair = crypto.generateKeyPairSync('ed25519', {\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n },\n })\n\n const { publicKey, privateKey } = keyPair\n if (typeof publicKey !== 'string' || typeof privateKey !== 'string') {\n throw new Error('Expected keypair to have string keys')\n }\n\n // Extract raw public key bytes and encode as base64\n const publicKeyObj = crypto.createPublicKey(publicKey)\n const publicKeyExport = publicKeyObj.export({\n type: 'spki',\n format: 'der',\n })\n\n if (!isBuffer(publicKeyExport)) {\n throw new Error('Expected public key export to be a Buffer')\n }\n\n // Ed25519 SPKI format: 12-byte header + 32-byte key\n // We extract just the 32-byte raw key for compact storage\n const rawPublicKey = publicKeyExport.subarray(12)\n const publicKeyBase64 = rawPublicKey.toString('base64')\n\n return {\n publicKey: publicKeyBase64,\n privateKey,\n }\n } catch (err) {\n throw new Error(\n `Failed to generate Ed25519 keypair: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Sign data with an Ed25519 private key.\n *\n * @param data - Data to sign (Buffer or UTF-8 string)\n * @param privateKeyPem - PEM-encoded private key\n * @returns Base64-encoded signature\n * @throws Error if signing fails\n * @public\n */\nexport function sign(data: Buffer | string, privateKeyPem: string): string {\n try {\n // Convert string data to Buffer\n const dataBuffer = typeof data === 'string' ? Buffer.from(data, 'utf8') : data\n\n // Create private key object\n const privateKeyObj = crypto.createPrivateKey(privateKeyPem)\n\n // Sign the data (null algorithm parameter for Ed25519)\n const signatureResult = crypto.sign(null, dataBuffer, privateKeyObj)\n\n if (!isBuffer(signatureResult)) {\n throw new Error('Expected signature to be a Buffer')\n }\n\n return signatureResult.toString('base64')\n } catch (err) {\n throw new Error(\n `Failed to sign data with Ed25519: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Verify an Ed25519 signature.\n *\n * @param data - Original data that was signed\n * @param signature - Base64-encoded signature to verify\n * @param publicKeyBase64 - Base64-encoded public key (raw 32 bytes)\n * @returns true if signature is valid, false otherwise\n * @throws Error if verification fails (not just invalid signature)\n * @public\n */\nexport function verify(data: Buffer | string, signature: string, publicKeyBase64: string): boolean {\n try {\n // Convert string data to Buffer\n const dataBuffer = typeof data === 'string' ? Buffer.from(data, 'utf8') : data\n\n // Decode signature from base64\n const signatureBuffer = Buffer.from(signature, 'base64')\n\n // Reconstruct SPKI format from raw public key\n // Ed25519 SPKI: 12-byte header + 32-byte key\n const rawPublicKey = Buffer.from(publicKeyBase64, 'base64')\n\n if (rawPublicKey.length !== 32) {\n throw new Error(\n `Invalid Ed25519 public key length: expected 32 bytes, got ${rawPublicKey.length.toString()}`,\n )\n }\n\n // SPKI header for Ed25519 (algorithm OID)\n const spkiHeader = Buffer.from([\n 0x30,\n 0x2a, // SEQUENCE, 42 bytes\n 0x30,\n 0x05, // SEQUENCE, 5 bytes\n 0x06,\n 0x03,\n 0x2b,\n 0x65,\n 0x70, // OID 1.3.101.112 (Ed25519)\n 0x03,\n 0x21,\n 0x00, // BIT STRING, 33 bytes (32 key + 1 padding)\n ])\n\n const spkiBuffer = Buffer.concat([spkiHeader, rawPublicKey])\n\n // Create public key object from SPKI\n const publicKeyObj = crypto.createPublicKey({\n key: spkiBuffer,\n format: 'der',\n type: 'spki',\n })\n\n // Verify the signature (null algorithm parameter for Ed25519)\n return crypto.verify(null, dataBuffer, publicKeyObj, signatureBuffer)\n } catch (err) {\n // If it's a verification failure (wrong signature), return false\n // If it's any other error, throw it\n if (err instanceof Error && err.message.includes('verification failed')) {\n return false\n }\n throw new Error(\n `Failed to verify Ed25519 signature: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n/**\n * Extract the public key from an Ed25519 private key.\n *\n * @param privateKeyPem - PEM-encoded private key\n * @returns Base64-encoded public key (raw 32 bytes)\n * @throws Error if extraction fails\n * @public\n */\nexport function getPublicKeyFromPrivate(privateKeyPem: string): string {\n try {\n // Create private key object\n const privateKeyObj = crypto.createPrivateKey(privateKeyPem)\n\n // Export the corresponding public key\n const publicKeyObj = crypto.createPublicKey(privateKeyObj)\n const publicKeyExport = publicKeyObj.export({\n type: 'spki',\n format: 'der',\n })\n\n if (!isBuffer(publicKeyExport)) {\n throw new Error('Expected public key export to be a Buffer')\n }\n\n // Extract raw 32-byte public key from SPKI format\n const rawPublicKey = publicKeyExport.subarray(12)\n return rawPublicKey.toString('base64')\n } catch (err) {\n throw new Error(\n `Failed to extract public key from Ed25519 private key: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n","/**\n * Verification logic for attestations.\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type {\n AttestItConfig,\n Attestation,\n AttestationsFile,\n SuiteVerificationResult,\n} from './types.js'\nimport { computeFingerprint } from './fingerprint.js'\nimport { readAndVerifyAttestations, SignatureInvalidError } from './attestation.js'\n\n/**\n * Options for verifying attestations.\n * @public\n */\nexport interface VerifyOptions {\n /** Configuration object */\n config: AttestItConfig\n /** Repository root directory (defaults to process.cwd()) */\n repoRoot?: string\n}\n\n/**\n * Result of verifying all attestations.\n * @public\n */\nexport interface VerifyResult {\n /** Overall success - true if all attestations are valid */\n success: boolean\n /** Whether the attestations file signature is valid */\n signatureValid: boolean\n /** Verification results for each suite */\n suites: SuiteVerificationResult[]\n /** Error messages encountered during verification */\n errors: string[]\n}\n\n/**\n * Verify all attestations against current code state.\n *\n * Verification algorithm:\n * 1. Load and verify attestations file signature\n * 2. For each suite in config:\n * a. Compute current fingerprint\n * b. Find matching attestation\n * c. Compare fingerprints\n * d. Check age\n * 3. Check invalidation chains\n * 4. Return aggregated results\n *\n * @param options - Verification options\n * @returns Verification result with status for each suite\n * @public\n */\nexport async function verifyAttestations(options: VerifyOptions): Promise<VerifyResult> {\n const { config, repoRoot = process.cwd() } = options\n const errors: string[] = []\n const suiteResults: SuiteVerificationResult[] = []\n let signatureValid = true\n let attestationsFile: AttestationsFile | null = null\n\n // Resolve paths\n const attestationsPath = resolvePath(config.settings.attestationsPath, repoRoot)\n const publicKeyPath = resolvePath(config.settings.publicKeyPath, repoRoot)\n\n // Step 1: Load and verify attestations\n try {\n if (!fs.existsSync(attestationsPath)) {\n // No attestations file - all suites need attestation\n attestationsFile = null\n } else if (!fs.existsSync(publicKeyPath)) {\n errors.push(`Public key not found: ${publicKeyPath}`)\n signatureValid = false\n } else {\n attestationsFile = await readAndVerifyAttestations({\n filePath: attestationsPath,\n publicKeyPath,\n })\n }\n } catch (err) {\n if (err instanceof SignatureInvalidError) {\n signatureValid = false\n errors.push(err.message)\n } else if (err instanceof Error) {\n errors.push(err.message)\n }\n }\n\n const attestations = attestationsFile?.attestations ?? []\n\n // Step 2: Check each suite\n for (const [suiteName, suiteConfig] of Object.entries(config.suites)) {\n const result = await verifySuite({\n suiteName,\n suiteConfig,\n attestations,\n maxAgeDays: config.settings.maxAgeDays,\n repoRoot,\n })\n suiteResults.push(result)\n }\n\n // Step 3: Check invalidation chains\n checkInvalidationChains(config, suiteResults)\n\n // Step 4: Aggregate results\n const allValid =\n signatureValid && suiteResults.every((r) => r.status === 'VALID') && errors.length === 0\n\n return {\n success: allValid,\n signatureValid,\n suites: suiteResults,\n errors,\n }\n}\n\n/**\n * Options for verifying a single suite.\n * @internal\n */\ninterface VerifySuiteOptions {\n /** Name of the suite */\n suiteName: string\n /** Suite configuration */\n suiteConfig: { packages?: string[]; ignore?: string[] }\n /** All attestations from the attestations file */\n attestations: Attestation[]\n /** Maximum age in days before attestation expires */\n maxAgeDays: number\n /** Repository root directory */\n repoRoot: string\n}\n\n/**\n * Verify a single suite's attestation.\n * @internal\n */\nasync function verifySuite(options: VerifySuiteOptions): Promise<SuiteVerificationResult> {\n const { suiteName, suiteConfig, attestations, maxAgeDays, repoRoot } = options\n\n // Validate that packages is defined (required for legacy verification)\n // Note: For gate-based verification, use the seal system functions instead\n if (!suiteConfig.packages || suiteConfig.packages.length === 0) {\n return {\n suite: suiteName,\n status: 'NEEDS_ATTESTATION',\n fingerprint: '',\n message: 'Suite configuration missing packages field',\n }\n }\n\n // Compute current fingerprint\n const fingerprintOptions = {\n packages: suiteConfig.packages.map((p) => resolvePath(p, repoRoot)),\n baseDir: repoRoot,\n ...(suiteConfig.ignore && { ignore: suiteConfig.ignore }),\n }\n const fingerprintResult = await computeFingerprint(fingerprintOptions)\n\n // Find attestation for this suite\n const attestation = attestations.find((a) => a.suite === suiteName)\n\n // No attestation found\n if (!attestation) {\n return {\n suite: suiteName,\n status: 'NEEDS_ATTESTATION',\n fingerprint: fingerprintResult.fingerprint,\n message: 'No attestation found for this suite',\n }\n }\n\n // Check fingerprint\n if (attestation.fingerprint !== fingerprintResult.fingerprint) {\n return {\n suite: suiteName,\n status: 'FINGERPRINT_CHANGED',\n fingerprint: fingerprintResult.fingerprint,\n attestation,\n message: `Fingerprint changed from ${attestation.fingerprint.slice(0, 20)}... to ${fingerprintResult.fingerprint.slice(0, 20)}...`,\n }\n }\n\n // Check age\n const attestedAt = new Date(attestation.attestedAt)\n const ageMs = Date.now() - attestedAt.getTime()\n const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24))\n\n if (ageDays > maxAgeDays) {\n return {\n suite: suiteName,\n status: 'EXPIRED',\n fingerprint: fingerprintResult.fingerprint,\n attestation,\n age: ageDays,\n message: `Attestation expired (${String(ageDays)} days old, max ${String(maxAgeDays)} days)`,\n }\n }\n\n // All checks passed\n return {\n suite: suiteName,\n status: 'VALID',\n fingerprint: fingerprintResult.fingerprint,\n attestation,\n age: ageDays,\n }\n}\n\n/**\n * Check invalidation chains.\n *\n * If suite A invalidates suite B, and A's attestation is newer than B's,\n * then B should be marked as INVALIDATED_BY_PARENT.\n *\n * @param config - Full configuration\n * @param results - Array of suite verification results to mutate\n * @internal\n */\nfunction checkInvalidationChains(config: AttestItConfig, results: SuiteVerificationResult[]): void {\n for (const [parentName, parentConfig] of Object.entries(config.suites)) {\n const invalidates = parentConfig.invalidates ?? []\n const parentResult = results.find((r) => r.suite === parentName)\n\n if (!parentResult?.attestation) continue\n\n const parentTime = new Date(parentResult.attestation.attestedAt).getTime()\n\n for (const childName of invalidates) {\n const childResult = results.find((r) => r.suite === childName)\n if (!childResult?.attestation) continue\n\n const childTime = new Date(childResult.attestation.attestedAt).getTime()\n\n // If parent was attested AFTER child, child is invalidated\n if (parentTime > childTime && childResult.status === 'VALID') {\n childResult.status = 'INVALIDATED_BY_PARENT'\n childResult.message = `Invalidated by ${parentName} (attested later)`\n }\n }\n }\n}\n\n/**\n * Resolve a path relative to a base directory.\n * @param relativePath - Path that may be relative or absolute\n * @param baseDir - Base directory for resolving relative paths\n * @returns Absolute path\n * @internal\n */\nfunction resolvePath(relativePath: string, baseDir: string): string {\n if (path.isAbsolute(relativePath)) {\n return relativePath\n }\n return path.join(baseDir, relativePath)\n}\n","/**\n * Filesystem-based key provider implementation.\n *\n * @remarks\n * This provider stores private keys on the local filesystem, maintaining\n * backward compatibility with the existing attest-it key storage behavior.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs/promises'\nimport { generateKeyPair as cryptoGenerateKeyPair, getDefaultPrivateKeyPath } from '../crypto.js'\nimport type {\n KeyProvider,\n KeyProviderConfig,\n KeyRetrievalResult,\n KeyGenerationResult,\n KeygenProviderOptions,\n} from './types.js'\n\n/**\n * Options for creating a FilesystemKeyProvider.\n * @public\n */\nexport interface FilesystemKeyProviderOptions {\n /** Path to the private key file (defaults to OS-specific config dir) */\n privateKeyPath?: string\n}\n\n/**\n * Key provider that stores private keys on the filesystem.\n *\n * @remarks\n * This is the default provider and maintains backward compatibility with\n * existing attest-it installations. Private keys are stored at:\n * - macOS/Linux: ~/.config/attest-it/private.pem\n * - Windows: %APPDATA%\\attest-it\\private.pem\n *\n * @public\n */\nexport class FilesystemKeyProvider implements KeyProvider {\n readonly type = 'filesystem'\n readonly displayName = 'Filesystem'\n\n private readonly privateKeyPath: string\n\n /**\n * Create a new FilesystemKeyProvider.\n * @param options - Provider options\n */\n constructor(options: FilesystemKeyProviderOptions = {}) {\n this.privateKeyPath = options.privateKeyPath ?? getDefaultPrivateKeyPath()\n }\n\n /**\n * Check if this provider is available.\n * Filesystem provider is always available.\n */\n async isAvailable(): Promise<boolean> {\n // Filesystem provider is always available\n return Promise.resolve(true)\n }\n\n /**\n * Check if a key exists at the given path.\n * @param keyRef - Path to the private key file\n */\n async keyExists(keyRef: string): Promise<boolean> {\n try {\n await fs.access(keyRef)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the private key path for signing.\n * Returns the path directly with a no-op cleanup function.\n * @param keyRef - Path to the private key file\n */\n async getPrivateKey(keyRef: string): Promise<KeyRetrievalResult> {\n // Verify the key exists\n if (!(await this.keyExists(keyRef))) {\n throw new Error(`Private key not found: ${keyRef}`)\n }\n\n return {\n keyPath: keyRef,\n // No-op cleanup for filesystem provider\n cleanup: async () => {\n // Nothing to clean up - key stays on filesystem\n },\n }\n }\n\n /**\n * Generate a new keypair and store on filesystem.\n * @param options - Key generation options\n */\n async generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult> {\n const { publicKeyPath, force = false } = options\n\n // Delegate to existing crypto module function\n const result = await cryptoGenerateKeyPair({\n privatePath: this.privateKeyPath,\n publicPath: publicKeyPath,\n force,\n })\n\n return {\n privateKeyRef: result.privatePath,\n publicKeyPath: result.publicPath,\n storageDescription: `Filesystem: ${result.privatePath}`,\n }\n }\n\n /**\n * Get the configuration for this provider.\n */\n getConfig(): KeyProviderConfig {\n return {\n type: this.type,\n options: {\n privateKeyPath: this.privateKeyPath,\n },\n }\n }\n}\n","/**\n * 1Password-based key provider implementation.\n *\n * @remarks\n * This provider stores private keys in 1Password and retrieves them via the\n * `op` CLI tool. Keys are downloaded to a temporary file for signing and\n * securely deleted after use.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { generateKeyPair as cryptoGenerateKeyPair, setKeyPermissions } from '../crypto.js'\nimport type {\n KeyProvider,\n KeyProviderConfig,\n KeyRetrievalResult,\n KeyGenerationResult,\n KeygenProviderOptions,\n} from './types.js'\n\n/**\n * Options for creating a OnePasswordKeyProvider.\n * @public\n */\nexport interface OnePasswordKeyProviderOptions {\n /** 1Password account email (optional if only one account) */\n account?: string\n /** Vault name or ID where the key is stored */\n vault: string\n /** Item name in 1Password */\n itemName: string\n}\n\n/**\n * Information about a 1Password account.\n * @public\n */\nexport interface OnePasswordAccount {\n /** Account UUID */\n account_uuid: string\n /** User email address */\n email: string\n /** Account URL */\n url: string\n /** User UUID */\n user_uuid: string\n}\n\n/**\n * Information about a 1Password vault.\n * @public\n */\nexport interface OnePasswordVault {\n /** Vault UUID */\n id: string\n /** Vault name */\n name: string\n}\n\n/**\n * Key provider that stores private keys in 1Password.\n *\n * @remarks\n * This provider requires the `op` CLI tool to be installed and authenticated.\n * Private keys are stored as documents in 1Password and downloaded to\n * temporary files for signing operations.\n *\n * @public\n */\nexport class OnePasswordKeyProvider implements KeyProvider {\n readonly type = '1password'\n readonly displayName = '1Password'\n\n private readonly account?: string\n private readonly vault: string\n private readonly itemName: string\n\n /**\n * Create a new OnePasswordKeyProvider.\n * @param options - Provider options\n */\n constructor(options: OnePasswordKeyProviderOptions) {\n // Only assign account if it's defined (to satisfy exactOptionalPropertyTypes)\n if (options.account !== undefined) {\n this.account = options.account\n }\n this.vault = options.vault\n this.itemName = options.itemName\n }\n\n /**\n * Check if the 1Password CLI is installed.\n * @returns True if `op` command is available\n */\n static async isInstalled(): Promise<boolean> {\n try {\n await execCommand('op', ['--version'])\n return true\n } catch {\n return false\n }\n }\n\n /**\n * List all 1Password accounts.\n * @returns Array of account information\n */\n static async listAccounts(): Promise<OnePasswordAccount[]> {\n try {\n const output = await execCommand('op', ['account', 'list', '--format=json'])\n const parsed: unknown = JSON.parse(output)\n if (!Array.isArray(parsed)) {\n return []\n }\n // Type assertion needed: We validate it's an array, but can't validate structure\n // at runtime without a full validation library. The op CLI output format is trusted.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return parsed as OnePasswordAccount[]\n } catch (error) {\n // Log in development for debugging, but don't fail\n if (process.env.NODE_ENV !== 'production') {\n console.error('Failed to list 1Password accounts:', error)\n }\n return []\n }\n }\n\n /**\n * List vaults in a specific account.\n * @param account - Account email (optional if only one account)\n * @returns Array of vault information\n */\n static async listVaults(account?: string): Promise<OnePasswordVault[]> {\n try {\n const args = ['vault', 'list', '--format=json']\n if (account) {\n args.push('--account', account)\n }\n const output = await execCommand('op', args)\n const parsed: unknown = JSON.parse(output)\n if (!Array.isArray(parsed)) {\n return []\n }\n // Type assertion needed: We validate it's an array, but can't validate structure\n // at runtime without a full validation library. The op CLI output format is trusted.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return parsed as OnePasswordVault[]\n } catch (error) {\n // Log in development for debugging, but don't fail\n if (process.env.NODE_ENV !== 'production') {\n console.error('Failed to list 1Password vaults:', error)\n }\n return []\n }\n }\n\n /**\n * Check if this provider is available.\n * Requires `op` CLI to be installed and authenticated.\n */\n async isAvailable(): Promise<boolean> {\n return OnePasswordKeyProvider.isInstalled()\n }\n\n /**\n * Check if a key exists in 1Password.\n * @param keyRef - Item name in 1Password\n */\n async keyExists(keyRef: string): Promise<boolean> {\n try {\n const args = ['item', 'get', keyRef, '--vault', this.vault, '--format=json']\n if (this.account) {\n args.push('--account', this.account)\n }\n await execCommand('op', args)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the private key from 1Password for signing.\n * Downloads to a temporary file and returns a cleanup function.\n * @param keyRef - Item name in 1Password\n * @throws Error if the key does not exist in 1Password\n */\n async getPrivateKey(keyRef: string): Promise<KeyRetrievalResult> {\n // Check if key exists first for better error messages\n if (!(await this.keyExists(keyRef))) {\n throw new Error(\n `Key not found in 1Password: \"${keyRef}\" (vault: ${this.vault})` +\n (this.account ? ` (account: ${this.account})` : ''),\n )\n }\n\n // Create a temporary file\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-'))\n const tempKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Download the key from 1Password\n const args = ['document', 'get', keyRef, '--vault', this.vault, '--out-file', tempKeyPath]\n if (this.account) {\n args.push('--account', this.account)\n }\n\n await execCommand('op', args)\n\n // Set proper permissions\n await setKeyPermissions(tempKeyPath)\n\n return {\n keyPath: tempKeyPath,\n cleanup: async () => {\n // Securely delete the temporary file and directory\n try {\n await fs.unlink(tempKeyPath)\n await fs.rmdir(tempDir)\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key file at ${tempKeyPath}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n },\n }\n } catch (error) {\n // Clean up temp directory on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Generate a new keypair and store private key in 1Password.\n * Public key is written to filesystem for repository commit.\n * @param options - Key generation options\n */\n async generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult> {\n const { publicKeyPath, force = false } = options\n\n // Create a temporary directory for key generation\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-keygen-'))\n const tempPrivateKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Generate the keypair to temporary location\n await cryptoGenerateKeyPair({\n privatePath: tempPrivateKeyPath,\n publicPath: publicKeyPath,\n force,\n })\n\n // Upload the private key to 1Password as a document\n const args = [\n 'document',\n 'create',\n tempPrivateKeyPath,\n '--title',\n this.itemName,\n '--vault',\n this.vault,\n ]\n if (this.account) {\n args.push('--account', this.account)\n }\n\n await execCommand('op', args)\n\n // Clean up temporary private key\n await fs.unlink(tempPrivateKeyPath)\n await fs.rmdir(tempDir)\n\n return {\n privateKeyRef: this.itemName,\n publicKeyPath,\n storageDescription: `1Password: ${this.vault}/${this.itemName}`,\n }\n } catch (error) {\n // Clean up on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Get the configuration for this provider.\n */\n getConfig(): KeyProviderConfig {\n return {\n type: this.type,\n options: {\n ...(this.account && { account: this.account }),\n vault: this.vault,\n itemName: this.itemName,\n },\n }\n }\n}\n\n/**\n * Execute a command and return stdout.\n * @internal\n */\nasync function execCommand(command: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] })\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 if (code === 0) {\n resolve(stdout.trim())\n } else {\n reject(new Error(`Command failed with exit code ${String(code)}: ${stderr}`))\n }\n })\n\n proc.on('error', (error) => {\n reject(error)\n })\n })\n}\n","/**\n * macOS Keychain-based key provider implementation.\n *\n * @remarks\n * This provider stores private keys in the macOS Keychain and retrieves them via the\n * `security` CLI tool. Keys are stored as base64-encoded strings and downloaded to\n * temporary files for signing operations, then securely deleted after use.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport { spawn } from 'node:child_process'\nimport { generateKeyPair as cryptoGenerateKeyPair, setKeyPermissions } from '../crypto.js'\nimport type {\n KeyProvider,\n KeyProviderConfig,\n KeyRetrievalResult,\n KeyGenerationResult,\n KeygenProviderOptions,\n} from './types.js'\n\n/**\n * Options for creating a MacOSKeychainKeyProvider.\n * @public\n */\nexport interface MacOSKeychainKeyProviderOptions {\n /** Item name in keychain (e.g., \"attest-it-private-key\") */\n itemName: string\n /** Path to the keychain file (optional, uses default keychain if not specified) */\n keychain?: string\n}\n\n/**\n * Information about a macOS keychain.\n * @public\n */\nexport interface MacOSKeychain {\n /** Full path to the keychain file */\n path: string\n /** Display name (filename without extension) */\n name: string\n}\n\n/**\n * Key provider that stores private keys in macOS Keychain.\n *\n * @remarks\n * This provider requires macOS and uses the `security` CLI tool.\n * Private keys are stored as base64-encoded strings in the keychain and decoded\n * to temporary files for signing operations.\n *\n * @public\n */\nexport class MacOSKeychainKeyProvider implements KeyProvider {\n readonly type = 'macos-keychain'\n readonly displayName = 'macOS Keychain'\n\n private readonly itemName: string\n private readonly keychain?: string\n private static readonly ACCOUNT = 'attest-it'\n\n /**\n * Create a new MacOSKeychainKeyProvider.\n * @param options - Provider options\n */\n constructor(options: MacOSKeychainKeyProviderOptions) {\n this.itemName = options.itemName\n if (options.keychain !== undefined) {\n this.keychain = options.keychain\n }\n }\n\n /**\n * Check if this provider is available.\n * Only available on macOS platforms.\n */\n static isAvailable(): boolean {\n return process.platform === 'darwin'\n }\n\n /**\n * List available keychains on the system.\n * @returns Array of keychain information\n */\n static async listKeychains(): Promise<MacOSKeychain[]> {\n if (!MacOSKeychainKeyProvider.isAvailable()) {\n return []\n }\n\n try {\n const output = await execCommand('security', ['list-keychains'])\n // Parse output - each line is a quoted path like:\n // \" \"/Users/name/Library/Keychains/login.keychain-db\"\"\n const keychains: MacOSKeychain[] = []\n const lines = output.split('\\n')\n for (const line of lines) {\n const match = /\"(.+)\"/.exec(line.trim())\n if (match?.[1]) {\n const fullPath = match[1]\n // Extract display name from path (filename without extension)\n const filename = fullPath.split('/').pop() ?? fullPath\n const name = filename.replace(/\\.keychain(-db)?$/, '')\n keychains.push({ path: fullPath, name })\n }\n }\n return keychains\n } catch {\n return []\n }\n }\n\n /**\n * Check if this provider is available on the current system.\n */\n isAvailable(): Promise<boolean> {\n return Promise.resolve(MacOSKeychainKeyProvider.isAvailable())\n }\n\n /**\n * Check if a key exists in the keychain.\n * @param keyRef - Item name in keychain\n */\n async keyExists(keyRef: string): Promise<boolean> {\n try {\n const args = ['find-generic-password', '-a', MacOSKeychainKeyProvider.ACCOUNT, '-s', keyRef]\n if (this.keychain) {\n args.push(this.keychain)\n }\n await execCommand('security', args)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the private key from keychain for signing.\n * Downloads to a temporary file and returns a cleanup function.\n * @param keyRef - Item name in keychain\n * @throws Error if the key does not exist in keychain\n */\n async getPrivateKey(keyRef: string): Promise<KeyRetrievalResult> {\n // Check if key exists first for better error messages\n if (!(await this.keyExists(keyRef))) {\n throw new Error(\n `Key not found in macOS Keychain: \"${keyRef}\" (account: ${MacOSKeychainKeyProvider.ACCOUNT})`,\n )\n }\n\n // Create a temporary file\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-'))\n const tempKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Retrieve the base64-encoded key from keychain\n const findArgs = [\n 'find-generic-password',\n '-a',\n MacOSKeychainKeyProvider.ACCOUNT,\n '-s',\n keyRef,\n '-w',\n ]\n if (this.keychain) {\n findArgs.push(this.keychain)\n }\n const base64Key = await execCommand('security', findArgs)\n\n // Decode from base64 and write to temp file\n const keyContent = Buffer.from(base64Key, 'base64').toString('utf8')\n await fs.writeFile(tempKeyPath, keyContent, { mode: 0o600 })\n\n // Set proper permissions\n await setKeyPermissions(tempKeyPath)\n\n return {\n keyPath: tempKeyPath,\n cleanup: async () => {\n // Securely delete the temporary file and directory\n try {\n await fs.unlink(tempKeyPath)\n await fs.rmdir(tempDir)\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key file at ${tempKeyPath}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n },\n }\n } catch (error) {\n // Clean up temp directory on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Generate a new keypair and store private key in keychain.\n * Public key is written to filesystem for repository commit.\n * @param options - Key generation options\n */\n async generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult> {\n const { publicKeyPath, force = false } = options\n\n // Create a temporary directory for key generation\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-keygen-'))\n const tempPrivateKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Generate the keypair to temporary location\n await cryptoGenerateKeyPair({\n privatePath: tempPrivateKeyPath,\n publicPath: publicKeyPath,\n force,\n })\n\n // Read the private key and encode as base64\n const privateKeyContent = await fs.readFile(tempPrivateKeyPath, 'utf8')\n const base64Key = Buffer.from(privateKeyContent, 'utf8').toString('base64')\n\n // Store in keychain\n // The -T \"\" flag allows all applications to access the key\n // The -U flag updates if the item already exists\n const addArgs = [\n 'add-generic-password',\n '-a',\n MacOSKeychainKeyProvider.ACCOUNT,\n '-s',\n this.itemName,\n '-w',\n base64Key,\n '-T',\n '',\n '-U',\n ]\n if (this.keychain) {\n addArgs.push(this.keychain)\n }\n await execCommand('security', addArgs)\n\n // Clean up temporary private key\n await fs.unlink(tempPrivateKeyPath)\n await fs.rmdir(tempDir)\n\n return {\n privateKeyRef: this.itemName,\n publicKeyPath,\n storageDescription: `macOS Keychain: ${this.itemName}`,\n }\n } catch (error) {\n // Clean up on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch (cleanupError) {\n // Log warning for security audit - temporary keys may not have been cleaned up\n console.warn(\n `Warning: Failed to clean up temporary key directory at ${tempDir}: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`,\n )\n }\n throw error\n }\n }\n\n /**\n * Get the configuration for this provider.\n */\n getConfig(): KeyProviderConfig {\n return {\n type: this.type,\n options: {\n itemName: this.itemName,\n },\n }\n }\n}\n\n/**\n * Execute a command and return stdout.\n * @internal\n */\nasync function execCommand(command: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] })\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 if (code === 0) {\n resolve(stdout.trim())\n } else {\n reject(new Error(`Command failed with exit code ${String(code)}: ${stderr}`))\n }\n })\n\n proc.on('error', (error) => {\n reject(error)\n })\n })\n}\n","/**\n * Configuration loading for local identity system.\n * @packageDocumentation\n */\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { mkdir as mkdirAsync, readFile, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml'\nimport { z } from 'zod'\nimport type { Identity, LocalConfig, PrivateKeyRef } from './types.js'\n\n/**\n * Module-level override for the attest-it home directory.\n * When set, this overrides the default ~/.config/attest-it location.\n * @internal\n */\nlet homeDirOverride: string | null = null\n\n/**\n * Set a custom home directory for attest-it configuration.\n * This is useful for testing or running with isolated state.\n *\n * @param dir - The directory to use, or null to reset to default\n * @public\n */\nexport function setAttestItHomeDir(dir: string | null): void {\n homeDirOverride = dir\n}\n\n/**\n * Get the current attest-it home directory override.\n *\n * @returns The override directory, or null if using default\n * @public\n */\nexport function getAttestItHomeDir(): string | null {\n return homeDirOverride\n}\n\n/**\n * Zod schema for private key references.\n */\nconst privateKeyRefSchema = z.discriminatedUnion('type', [\n z.object({\n type: z.literal('file'),\n path: z.string().min(1, 'File path cannot be empty'),\n }),\n z.object({\n type: z.literal('keychain'),\n service: z.string().min(1, 'Service name cannot be empty'),\n account: z.string().min(1, 'Account name cannot be empty'),\n keychain: z.string().optional(),\n }),\n z.object({\n type: z.literal('1password'),\n account: z.string().optional(),\n vault: z.string().min(1, 'Vault name cannot be empty'),\n item: z.string().min(1, 'Item name cannot be empty'),\n field: z.string().optional(),\n }),\n])\n\n/**\n * Zod schema for a single identity.\n */\nconst identitySchema = z\n .object({\n name: z.string().min(1, 'Identity name cannot be empty'),\n email: z.string().optional(),\n github: z.string().optional(),\n publicKey: z.string().min(1, 'Public key cannot be empty'),\n privateKey: privateKeyRefSchema,\n })\n .strict()\n\n/**\n * Zod schema for the local config file.\n */\nconst localConfigSchema = z\n .object({\n activeIdentity: z.string().min(1, 'Active identity name cannot be empty'),\n identities: z\n .record(z.string(), identitySchema)\n .refine((identities) => Object.keys(identities).length >= 1, {\n message: 'At least one identity must be defined',\n }),\n })\n .strict()\n\n/**\n * Error thrown when local config validation fails.\n * @public\n */\nexport class LocalConfigValidationError extends Error {\n constructor(\n message: string,\n public readonly issues: z.ZodIssue[],\n ) {\n super(message)\n this.name = 'LocalConfigValidationError'\n }\n}\n\n/**\n * Get the path to the local config file.\n *\n * If a home directory override is set via setAttestItHomeDir(),\n * returns {homeDir}/config.yaml. Otherwise returns ~/.config/attest-it/config.yaml.\n *\n * @returns Path to the local config file\n * @public\n */\nexport function getLocalConfigPath(): string {\n if (homeDirOverride) {\n return join(homeDirOverride, 'config.yaml')\n }\n const home = homedir()\n return join(home, '.config', 'attest-it', 'config.yaml')\n}\n\n/**\n * Get the attest-it configuration directory.\n *\n * If a home directory override is set via setAttestItHomeDir(),\n * returns that directory. Otherwise returns ~/.config/attest-it.\n *\n * @returns Path to the configuration directory\n * @public\n */\nexport function getAttestItConfigDir(): string {\n if (homeDirOverride) {\n return homeDirOverride\n }\n return join(homedir(), '.config', 'attest-it')\n}\n\n/**\n * Parse and validate local config content.\n *\n * @param content - YAML content to parse\n * @returns Validated LocalConfig object\n * @throws {LocalConfigValidationError} If validation fails\n */\nfunction parseLocalConfigContent(content: string): LocalConfig {\n let rawConfig: unknown\n\n try {\n rawConfig = parseYaml(content)\n } catch (error) {\n throw new LocalConfigValidationError(\n `Failed to parse YAML: ${error instanceof Error ? error.message : String(error)}`,\n [],\n )\n }\n\n const result = localConfigSchema.safeParse(rawConfig)\n\n if (!result.success) {\n throw new LocalConfigValidationError(\n 'Local configuration validation failed:\\n' +\n result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n'),\n result.error.issues,\n )\n }\n\n // Transform Zod output to match LocalConfig interface by removing undefined values\n const identities: Record<string, Identity> = Object.fromEntries(\n Object.entries(result.data.identities).map(([key, identity]) => {\n // Transform private key ref to remove undefined optional fields\n let privateKey: PrivateKeyRef\n if (identity.privateKey.type === '1password') {\n privateKey = {\n type: '1password',\n vault: identity.privateKey.vault,\n item: identity.privateKey.item,\n ...(identity.privateKey.account !== undefined && {\n account: identity.privateKey.account,\n }),\n ...(identity.privateKey.field !== undefined && { field: identity.privateKey.field }),\n }\n } else if (identity.privateKey.type === 'keychain') {\n privateKey = {\n type: 'keychain',\n service: identity.privateKey.service,\n account: identity.privateKey.account,\n ...(identity.privateKey.keychain !== undefined && {\n keychain: identity.privateKey.keychain,\n }),\n }\n } else {\n privateKey = identity.privateKey\n }\n\n return [\n key,\n {\n name: identity.name,\n publicKey: identity.publicKey,\n privateKey,\n ...(identity.email !== undefined && { email: identity.email }),\n ...(identity.github !== undefined && { github: identity.github }),\n },\n ]\n }),\n )\n\n return {\n activeIdentity: result.data.activeIdentity,\n identities,\n }\n}\n\n/**\n * Load and validate local config from file (async).\n *\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @returns Validated LocalConfig object, or null if file does not exist\n * @throws {LocalConfigValidationError} If validation fails\n * @public\n */\nexport async function loadLocalConfig(configPath?: string): Promise<LocalConfig | null> {\n const resolvedPath = configPath ?? getLocalConfigPath()\n\n try {\n const content = await readFile(resolvedPath, 'utf8')\n return parseLocalConfigContent(content)\n } catch (error) {\n if (error instanceof LocalConfigValidationError) {\n throw error\n }\n // Check if it's a file not found error\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n (error.code === 'ENOENT' || error.code === 'ENOTDIR')\n ) {\n return null\n }\n // Re-throw other errors\n throw error\n }\n}\n\n/**\n * Load and validate local config from file (sync).\n *\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @returns Validated LocalConfig object, or null if file does not exist\n * @throws {LocalConfigValidationError} If validation fails\n * @public\n */\nexport function loadLocalConfigSync(configPath?: string): LocalConfig | null {\n const resolvedPath = configPath ?? getLocalConfigPath()\n\n try {\n const content = readFileSync(resolvedPath, 'utf8')\n return parseLocalConfigContent(content)\n } catch (error) {\n if (error instanceof LocalConfigValidationError) {\n throw error\n }\n // Check if it's a file not found error\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n (error.code === 'ENOENT' || error.code === 'ENOTDIR')\n ) {\n return null\n }\n // Re-throw other errors\n throw error\n }\n}\n\n/**\n * Save local config to file (async).\n *\n * @param config - LocalConfig object to save\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @throws {Error} If write fails\n * @public\n */\nexport async function saveLocalConfig(config: LocalConfig, configPath?: string): Promise<void> {\n const resolvedPath = configPath ?? getLocalConfigPath()\n const content = stringifyYaml(config)\n\n // Ensure parent directory exists\n const dir = dirname(resolvedPath)\n await mkdirAsync(dir, { recursive: true })\n\n await writeFile(resolvedPath, content, 'utf8')\n}\n\n/**\n * Save local config to file (sync).\n *\n * @param config - LocalConfig object to save\n * @param configPath - Optional path to config file. If not provided, uses default location.\n * @throws {Error} If write fails\n * @public\n */\nexport function saveLocalConfigSync(config: LocalConfig, configPath?: string): void {\n const resolvedPath = configPath ?? getLocalConfigPath()\n const content = stringifyYaml(config)\n\n // Ensure parent directory exists\n const dir = dirname(resolvedPath)\n mkdirSync(dir, { recursive: true })\n\n writeFileSync(resolvedPath, content, 'utf8')\n}\n\n/**\n * Get the active identity from a config.\n *\n * @param config - LocalConfig object\n * @returns The active Identity, or undefined if not found\n * @public\n */\nexport function getActiveIdentity(config: LocalConfig): Identity | undefined {\n return config.identities[config.activeIdentity]\n}\n","/**\n * YubiKey-based key provider implementation.\n *\n * @remarks\n * This provider stores private keys encrypted with a key derived from YubiKey\n * HMAC-SHA1 challenge-response. The key cannot be decrypted without the physical\n * YubiKey present. Uses HKDF to derive an AES-256-GCM encryption key from the\n * challenge-response output.\n *\n * Requires the `ykman` (YubiKey Manager) CLI tool to be installed.\n *\n * **Security Note**: Private keys are temporarily held in memory as JavaScript\n * strings during encryption/decryption. JavaScript strings are immutable and\n * cannot be securely zeroed. The key remains in memory until garbage collected.\n * For maximum security, use full-disk encryption and disable swap on systems\n * handling sensitive keys.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport * as crypto from 'node:crypto'\nimport { spawn } from 'node:child_process'\nimport { z } from 'zod'\nimport { generateKeyPair as cryptoGenerateKeyPair, setKeyPermissions } from '../crypto.js'\nimport { getAttestItConfigDir } from '../identity/config.js'\nimport type {\n KeyProvider,\n KeyProviderConfig,\n KeyRetrievalResult,\n KeyGenerationResult,\n KeygenProviderOptions,\n} from './types.js'\n\n/**\n * Options for creating a YubiKeyProvider.\n * @public\n */\nexport interface YubiKeyProviderOptions {\n /** Path to the encrypted key file */\n encryptedKeyPath: string\n /** YubiKey slot to use for challenge-response (default: 2) */\n slot?: 1 | 2\n /** Serial number of specific YubiKey to use (optional but recommended) */\n serial?: string\n}\n\n/**\n * Information about a connected YubiKey.\n * @public\n */\nexport interface YubiKeyInfo {\n /** Device serial number */\n serial: string\n /** Device type (e.g., \"YubiKey 5 NFC\") */\n type: string\n /** Firmware version */\n firmware: string\n}\n\n/**\n * Zod schema for validating encrypted key file structure.\n * @internal\n */\nconst EncryptedKeyFileSchema = z.object({\n version: z.literal(1),\n iv: z.string().min(1),\n authTag: z.string().min(1),\n salt: z.string().min(1),\n challenge: z.string().min(1),\n ciphertext: z.string().min(1),\n slot: z.union([z.literal(1), z.literal(2)]),\n serial: z.string().optional(),\n aad: z.string().optional(),\n})\n\n/**\n * Encrypted key file structure.\n * @internal\n */\ninterface EncryptedKeyFile {\n /** Version of the encryption format */\n version: 1\n /** AES-256-GCM initialization vector (base64) */\n iv: string\n /** Authentication tag (base64) */\n authTag: string\n /** Salt used for HKDF (base64) */\n salt: string\n /** Challenge sent to YubiKey (base64) */\n challenge: string\n /** Encrypted private key (base64) */\n ciphertext: string\n /** YubiKey slot used */\n slot: 1 | 2\n /** YubiKey serial (for device verification) */\n serial?: string | undefined\n /** Additional authenticated data (base64) - binds metadata to ciphertext */\n aad?: string | undefined\n}\n\n/**\n * Track active cleanup handlers for process exit.\n * @internal\n */\nconst activeCleanupHandlers = new Set<() => Promise<void>>()\nlet processHandlersInstalled = false\n\n/**\n * Install process exit handlers to ensure cleanup on unexpected termination.\n * @internal\n */\nfunction installProcessHandlers(): void {\n if (processHandlersInstalled) return\n processHandlersInstalled = true\n\n const runCleanup = async () => {\n const handlers = Array.from(activeCleanupHandlers)\n await Promise.allSettled(handlers.map((h) => h()))\n }\n\n // Handle graceful shutdown\n process.once('beforeExit', () => {\n void runCleanup()\n })\n\n // Handle SIGINT (Ctrl+C)\n process.once('SIGINT', () => {\n void runCleanup().finally(() => process.exit(130))\n })\n\n // Handle SIGTERM\n process.once('SIGTERM', () => {\n void runCleanup().finally(() => process.exit(143))\n })\n}\n\n/**\n * Validate encrypted key file structure and buffer sizes.\n * @param data - Parsed JSON data\n * @returns Validated EncryptedKeyFile\n * @throws Error if validation fails\n * @internal\n */\nfunction validateEncryptedKeyFile(data: unknown): EncryptedKeyFile {\n // Schema validation\n const parsed = EncryptedKeyFileSchema.parse(data)\n\n // Validate decoded buffer sizes\n const iv = Buffer.from(parsed.iv, 'base64')\n if (iv.length !== 12) {\n throw new Error(`Invalid IV size: expected 12 bytes, got ${String(iv.length)}`)\n }\n\n const authTag = Buffer.from(parsed.authTag, 'base64')\n if (authTag.length !== 16) {\n throw new Error(`Invalid auth tag size: expected 16 bytes, got ${String(authTag.length)}`)\n }\n\n const salt = Buffer.from(parsed.salt, 'base64')\n if (salt.length !== 32) {\n throw new Error(`Invalid salt size: expected 32 bytes, got ${String(salt.length)}`)\n }\n\n const challenge = Buffer.from(parsed.challenge, 'base64')\n if (challenge.length !== 32) {\n throw new Error(`Invalid challenge size: expected 32 bytes, got ${String(challenge.length)}`)\n }\n\n return parsed\n}\n\n/**\n * Construct Additional Authenticated Data (AAD) for GCM encryption.\n * This binds the metadata to the ciphertext, preventing tampering.\n * @internal\n */\nfunction constructAAD(version: number, slot: 1 | 2, serial: string | undefined): Buffer {\n const aadObject = {\n version,\n slot,\n serial: serial ?? 'unspecified',\n }\n return Buffer.from(JSON.stringify(aadObject), 'utf8')\n}\n\n/**\n * Key provider that encrypts private keys using YubiKey HMAC challenge-response.\n *\n * @remarks\n * This provider uses the YubiKey HMAC-SHA1 challenge-response feature (typically slot 2)\n * to derive an encryption key. The Ed25519 private key is encrypted with AES-256-GCM,\n * and can only be decrypted when the correct YubiKey is present.\n *\n * This approach:\n * - Works with all YubiKeys that support HMAC-SHA1 challenge-response\n * - Preserves Ed25519 compatibility (signing happens in software)\n * - Requires physical YubiKey presence to decrypt and use the key\n *\n * **Security Note**: Always use the `serial` option to bind keys to a specific YubiKey.\n * Without serial verification, any YubiKey with the same HMAC secret could decrypt the key.\n *\n * @public\n */\nexport class YubiKeyProvider implements KeyProvider {\n readonly type = 'yubikey'\n readonly displayName = 'YubiKey'\n\n private readonly encryptedKeyPath: string\n private readonly slot: 1 | 2\n private readonly serial?: string\n\n /**\n * Create a new YubiKeyProvider.\n * @param options - Provider options\n * @throws Error if encryptedKeyPath is outside the attest-it config directory\n */\n constructor(options: YubiKeyProviderOptions) {\n // Validate and normalize the encrypted key path\n const resolvedPath = path.resolve(options.encryptedKeyPath)\n const configDir = getAttestItConfigDir()\n\n // Security: Ensure path is within the config directory to prevent path traversal\n if (!resolvedPath.startsWith(configDir)) {\n throw new Error(\n `Encrypted key path must be within attest-it config directory (${configDir}). ` +\n `Got: ${resolvedPath}`,\n )\n }\n\n this.encryptedKeyPath = resolvedPath\n this.slot = options.slot ?? 2\n if (options.serial !== undefined) {\n this.serial = options.serial\n }\n }\n\n /**\n * Check if ykman CLI is installed and available.\n * @returns true if ykman is available\n */\n static async isInstalled(): Promise<boolean> {\n try {\n await execCommand('ykman', ['--version'])\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Check if any YubiKey is connected.\n * @returns true if at least one YubiKey is connected\n */\n static async isConnected(): Promise<boolean> {\n try {\n const output = await execCommand('ykman', ['list', '--serials'])\n return output.trim().length > 0\n } catch {\n return false\n }\n }\n\n /**\n * Check if HMAC challenge-response is configured on a slot.\n * @param slot - Slot number (1 or 2)\n * @param serial - Optional YubiKey serial number\n * @returns true if challenge-response is configured\n */\n static async isChallengeResponseConfigured(slot: 1 | 2 = 2, serial?: string): Promise<boolean> {\n try {\n const args = ['otp', 'info']\n if (serial) {\n args.unshift('--device', serial)\n }\n const output = await execCommand('ykman', args)\n // Look for \"Slot X: programmed (challenge-response)\" pattern\n const slotPattern = new RegExp(`Slot ${String(slot)}:\\\\s+programmed.*challenge-response`, 'i')\n return slotPattern.test(output)\n } catch {\n return false\n }\n }\n\n /**\n * List connected YubiKeys.\n * @returns Array of YubiKey information\n */\n static async listDevices(): Promise<YubiKeyInfo[]> {\n if (!(await YubiKeyProvider.isInstalled())) {\n return []\n }\n\n try {\n const output = await execCommand('ykman', ['list', '--serials'])\n const serials = output\n .trim()\n .split('\\n')\n .filter((s) => s.length > 0)\n\n const devices: YubiKeyInfo[] = []\n for (const serial of serials) {\n try {\n const infoOutput = await execCommand('ykman', ['--device', serial, 'info'])\n // Parse device type and firmware from info output\n const typeMatch = /Device type:\\s+(.+)/i.exec(infoOutput)\n const fwMatch = /Firmware version:\\s+(.+)/i.exec(infoOutput)\n\n devices.push({\n serial,\n type: typeMatch?.[1]?.trim() ?? 'YubiKey',\n firmware: fwMatch?.[1]?.trim() ?? 'Unknown',\n })\n } catch {\n // If we can't get info, just use the serial\n devices.push({\n serial,\n type: 'YubiKey',\n firmware: 'Unknown',\n })\n }\n }\n return devices\n } catch {\n return []\n }\n }\n\n /**\n * Check if this provider is available on the current system.\n * Requires ykman to be installed.\n */\n async isAvailable(): Promise<boolean> {\n return YubiKeyProvider.isInstalled()\n }\n\n /**\n * Check if an encrypted key file exists.\n * @param keyRef - Path to encrypted key file\n */\n async keyExists(keyRef: string): Promise<boolean> {\n try {\n await fs.access(keyRef)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the private key by decrypting with YubiKey.\n * Downloads to a temporary file and returns a cleanup function.\n *\n * **Important**: Always call the cleanup function when done to securely delete\n * the temporary key file. The cleanup is also registered for process exit handlers.\n *\n * @param keyRef - Path to encrypted key file\n * @throws Error if the key cannot be decrypted\n */\n async getPrivateKey(keyRef: string): Promise<KeyRetrievalResult> {\n // Install process handlers for cleanup on unexpected exit\n installProcessHandlers()\n\n // Check if encrypted key file exists\n if (!(await this.keyExists(keyRef))) {\n throw new Error(`Encrypted key file not found: ${keyRef}`)\n }\n\n // Read and parse the encrypted key file with validation\n const encryptedData = await fs.readFile(keyRef, 'utf8')\n let keyFile: EncryptedKeyFile\n try {\n const parsed: unknown = JSON.parse(encryptedData)\n keyFile = validateEncryptedKeyFile(parsed)\n } catch (err) {\n if (err instanceof z.ZodError) {\n throw new Error(\n `Invalid encrypted key file format: ${err.errors.map((e) => e.message).join(', ')}`,\n )\n }\n throw new Error(`Invalid encrypted key file: malformed JSON or structure`)\n }\n\n // Determine which serial to use (provider setting takes precedence, then key file)\n const expectedSerial = this.serial ?? keyFile.serial\n\n // Security warning if no serial verification\n if (!expectedSerial) {\n console.warn(\n 'WARNING: No YubiKey serial number specified for key verification. ' +\n 'Any YubiKey with the correct HMAC secret could decrypt this key. ' +\n 'For better security, re-encrypt the key with a serial number specified.',\n )\n }\n\n // Verify YubiKey serial if specified\n if (expectedSerial) {\n const devices = await YubiKeyProvider.listDevices()\n const matchingDevice = devices.find((d) => d.serial === expectedSerial)\n if (!matchingDevice) {\n throw new Error(\n `Required YubiKey not found. Expected serial: ${expectedSerial}. ` +\n `Connected devices: ${devices.map((d) => d.serial).join(', ') || 'none'}`,\n )\n }\n }\n\n // Perform challenge-response to get the decryption key\n const challenge = Buffer.from(keyFile.challenge, 'base64')\n const response = await performChallengeResponse(challenge, keyFile.slot, expectedSerial)\n\n // Derive AES-256 key from response using HKDF\n const salt = Buffer.from(keyFile.salt, 'base64')\n const aesKey = deriveKey(response, salt)\n\n // Decrypt the private key\n const iv = Buffer.from(keyFile.iv, 'base64')\n const authTag = Buffer.from(keyFile.authTag, 'base64')\n const ciphertext = Buffer.from(keyFile.ciphertext, 'base64')\n\n let privateKeyContent: string\n try {\n const decipher = crypto.createDecipheriv('aes-256-gcm', aesKey, iv)\n\n // Set AAD if present (for files created with AAD support)\n if (keyFile.aad) {\n decipher.setAAD(Buffer.from(keyFile.aad, 'base64'))\n }\n\n decipher.setAuthTag(authTag)\n const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])\n privateKeyContent = decrypted.toString('utf8')\n } catch {\n // Sanitized error message - don't leak crypto details\n throw new Error(\n 'Failed to decrypt private key. Verify you are using the correct YubiKey ' +\n 'and the encrypted key file has not been corrupted or tampered with.',\n )\n }\n\n // Create a temporary file\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-'))\n const tempKeyPath = path.join(tempDir, 'private.pem')\n\n // Create cleanup function with tracking\n const cleanup = async () => {\n activeCleanupHandlers.delete(cleanup)\n try {\n // Overwrite with random data before deleting (defense in depth)\n const keySize = Buffer.byteLength(privateKeyContent)\n await fs.writeFile(tempKeyPath, crypto.randomBytes(keySize))\n await fs.unlink(tempKeyPath)\n await fs.rmdir(tempDir)\n } catch {\n // Silently ignore cleanup errors - file may already be deleted\n }\n }\n\n try {\n // Write decrypted key to temp file\n await fs.writeFile(tempKeyPath, privateKeyContent, { mode: 0o600 })\n await setKeyPermissions(tempKeyPath)\n\n // Register cleanup for process exit\n activeCleanupHandlers.add(cleanup)\n\n return {\n keyPath: tempKeyPath,\n cleanup,\n }\n } catch (error) {\n // Clean up temp directory on error\n await cleanup()\n throw error\n }\n }\n\n /**\n * Generate a new keypair and store encrypted with YubiKey.\n * Public key is written to filesystem for repository commit.\n *\n * **Security Note**: Always specify a serial number to bind the key to a specific YubiKey.\n *\n * @param options - Key generation options\n */\n async generateKeyPair(options: KeygenProviderOptions): Promise<KeyGenerationResult> {\n const { publicKeyPath, force = false } = options\n\n // Check if challenge-response is configured (this also verifies YubiKey is connected)\n if (!(await YubiKeyProvider.isChallengeResponseConfigured(this.slot, this.serial))) {\n throw new Error(\n `YubiKey slot ${String(this.slot)} is not configured for HMAC challenge-response. ` +\n 'Ensure your YubiKey is connected and use \"ykman otp chalresp --generate 2\" to configure it.',\n )\n }\n\n // Check if encrypted key file already exists\n if (!force && (await this.keyExists(this.encryptedKeyPath))) {\n throw new Error(\n `Encrypted key file already exists: ${this.encryptedKeyPath}. Use force: true to overwrite.`,\n )\n }\n\n // Get YubiKey serial for the encrypted file (required for security)\n let serial: string | undefined\n if (this.serial) {\n serial = this.serial\n } else {\n const devices = await YubiKeyProvider.listDevices()\n if (devices.length === 1 && devices[0]) {\n serial = devices[0].serial\n } else if (devices.length > 1) {\n console.warn(\n 'WARNING: Multiple YubiKeys detected but no serial specified. ' +\n 'Key will not be bound to a specific device. ' +\n 'For better security, specify a serial number.',\n )\n }\n }\n\n // Create a temporary directory for key generation\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'attest-it-keygen-'))\n const tempPrivateKeyPath = path.join(tempDir, 'private.pem')\n\n try {\n // Generate the keypair to temporary location\n await cryptoGenerateKeyPair({\n privatePath: tempPrivateKeyPath,\n publicPath: publicKeyPath,\n force,\n })\n\n // Read the private key\n const privateKeyContent = await fs.readFile(tempPrivateKeyPath, 'utf8')\n\n // Generate random challenge and salt\n const challenge = crypto.randomBytes(32)\n const salt = crypto.randomBytes(32)\n const iv = crypto.randomBytes(12) // 96 bits for GCM\n\n // Perform challenge-response\n const response = await performChallengeResponse(challenge, this.slot, this.serial)\n\n // Derive AES-256 key from response using HKDF\n const aesKey = deriveKey(response, salt)\n\n // Construct AAD to bind metadata to ciphertext\n const aad = constructAAD(1, this.slot, serial)\n\n // Encrypt the private key with AES-256-GCM\n const cipher = crypto.createCipheriv('aes-256-gcm', aesKey, iv)\n cipher.setAAD(aad)\n const ciphertext = Buffer.concat([\n cipher.update(Buffer.from(privateKeyContent, 'utf8')),\n cipher.final(),\n ])\n const authTag = cipher.getAuthTag()\n\n // Create the encrypted key file\n const keyFile: EncryptedKeyFile = {\n version: 1,\n iv: iv.toString('base64'),\n authTag: authTag.toString('base64'),\n salt: salt.toString('base64'),\n challenge: challenge.toString('base64'),\n ciphertext: ciphertext.toString('base64'),\n slot: this.slot,\n aad: aad.toString('base64'),\n ...(serial && { serial }),\n }\n\n // Ensure parent directory exists\n await fs.mkdir(path.dirname(this.encryptedKeyPath), { recursive: true })\n\n // Write the encrypted key file\n await fs.writeFile(this.encryptedKeyPath, JSON.stringify(keyFile, null, 2), { mode: 0o600 })\n await setKeyPermissions(this.encryptedKeyPath)\n\n // Clean up temporary private key (overwrite before delete)\n const keySize = Buffer.byteLength(privateKeyContent)\n await fs.writeFile(tempPrivateKeyPath, crypto.randomBytes(keySize))\n await fs.unlink(tempPrivateKeyPath)\n await fs.rmdir(tempDir)\n\n return {\n privateKeyRef: this.encryptedKeyPath,\n publicKeyPath,\n storageDescription: `YubiKey-encrypted: ${this.encryptedKeyPath}`,\n }\n } catch (error) {\n // Clean up on error\n try {\n await fs.rm(tempDir, { recursive: true, force: true })\n } catch {\n // Ignore cleanup errors\n }\n throw error\n }\n }\n\n /**\n * Encrypt an existing private key with YubiKey challenge-response.\n *\n * @remarks\n * This static method allows encrypting a private key that was generated\n * elsewhere (e.g., by the CLI) without having to create a provider instance first.\n *\n * **Security Note**: Always specify a serial number to bind the key to a specific YubiKey.\n * The serial provides defense-in-depth by ensuring only the intended YubiKey can decrypt.\n *\n * @param options - Encryption options\n * @returns Path to the encrypted key file and storage description\n * @public\n */\n static async encryptPrivateKey(options: {\n /** The private key content (PEM format) */\n privateKey: string\n /** Path where the encrypted key file will be saved */\n encryptedKeyPath: string\n /** YubiKey slot to use (default: 2) */\n slot?: 1 | 2\n /** YubiKey serial number (recommended for security) */\n serial?: string\n }): Promise<{ encryptedKeyPath: string; storageDescription: string }> {\n const { privateKey, encryptedKeyPath, slot = 2, serial } = options\n\n // Validate path is within config directory\n const resolvedPath = path.resolve(encryptedKeyPath)\n const configDir = getAttestItConfigDir()\n if (!resolvedPath.startsWith(configDir)) {\n throw new Error(\n `Encrypted key path must be within attest-it config directory (${configDir}). ` +\n `Got: ${resolvedPath}`,\n )\n }\n\n // Security warning if no serial specified\n if (!serial) {\n console.warn(\n 'WARNING: No YubiKey serial number specified. ' +\n 'Key will not be bound to a specific device. ' +\n 'For better security, specify a serial number.',\n )\n }\n\n // Check if challenge-response is configured (this also verifies YubiKey is connected)\n if (!(await YubiKeyProvider.isChallengeResponseConfigured(slot, serial))) {\n throw new Error(\n `YubiKey slot ${String(slot)} is not configured for HMAC challenge-response. ` +\n 'Ensure your YubiKey is connected and use \"ykman otp chalresp --generate 2\" to configure it.',\n )\n }\n\n // Generate random challenge, salt, and IV\n const challenge = crypto.randomBytes(32)\n const salt = crypto.randomBytes(32)\n const iv = crypto.randomBytes(12) // 96 bits for GCM\n\n // Perform challenge-response\n const response = await performChallengeResponse(challenge, slot, serial)\n\n // Derive AES-256 key from response using HKDF\n const aesKey = deriveKey(response, salt)\n\n // Construct AAD to bind metadata to ciphertext\n const aad = constructAAD(1, slot, serial)\n\n // Encrypt the private key with AES-256-GCM\n const cipher = crypto.createCipheriv('aes-256-gcm', aesKey, iv)\n cipher.setAAD(aad)\n const ciphertext = Buffer.concat([\n cipher.update(Buffer.from(privateKey, 'utf8')),\n cipher.final(),\n ])\n const authTag = cipher.getAuthTag()\n\n // Create the encrypted key file\n const keyFile: EncryptedKeyFile = {\n version: 1,\n iv: iv.toString('base64'),\n authTag: authTag.toString('base64'),\n salt: salt.toString('base64'),\n challenge: challenge.toString('base64'),\n ciphertext: ciphertext.toString('base64'),\n slot,\n aad: aad.toString('base64'),\n ...(serial && { serial }),\n }\n\n // Ensure parent directory exists\n await fs.mkdir(path.dirname(resolvedPath), { recursive: true })\n\n // Write the encrypted key file\n await fs.writeFile(resolvedPath, JSON.stringify(keyFile, null, 2), { mode: 0o600 })\n await setKeyPermissions(resolvedPath)\n\n return {\n encryptedKeyPath: resolvedPath,\n storageDescription: `YubiKey-encrypted: ${resolvedPath}`,\n }\n }\n\n /**\n * Get the configuration for this provider.\n */\n getConfig(): KeyProviderConfig {\n return {\n type: this.type,\n options: {\n encryptedKeyPath: this.encryptedKeyPath,\n slot: this.slot,\n ...(this.serial && { serial: this.serial }),\n },\n }\n }\n}\n\n/**\n * Execute a command and return stdout.\n * @internal\n */\nasync function execCommand(command: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, { stdio: ['ignore', 'pipe', 'pipe'] })\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 if (code === 0) {\n resolve(stdout.trim())\n } else {\n reject(new Error(`Command failed with exit code ${String(code)}: ${stderr}`))\n }\n })\n\n proc.on('error', (error) => {\n reject(error)\n })\n })\n}\n\n/**\n * Perform HMAC-SHA1 challenge-response with YubiKey.\n * @param challenge - Challenge bytes to send\n * @param slot - YubiKey slot (1 or 2)\n * @param serial - Optional YubiKey serial number\n * @returns Response from YubiKey (20 bytes for HMAC-SHA1)\n * @internal\n */\nasync function performChallengeResponse(\n challenge: Buffer,\n slot: 1 | 2,\n serial?: string,\n): Promise<Buffer> {\n const args = ['otp', 'chalresp', '--slot', String(slot)]\n if (serial) {\n args.unshift('--device', serial)\n }\n args.push(challenge.toString('hex'))\n\n try {\n const output = await execCommand('ykman', args)\n // Response is hex-encoded\n return Buffer.from(output.trim(), 'hex')\n } catch {\n // Sanitized error - don't leak command details\n throw new Error(\n 'YubiKey challenge-response failed. ' +\n 'Verify your YubiKey is inserted and the slot is configured for challenge-response.',\n )\n }\n}\n\n/**\n * Derive an AES-256 key from the challenge-response using HKDF.\n * @param response - Challenge-response output from YubiKey\n * @param salt - Random salt for HKDF\n * @returns 32-byte AES-256 key\n * @internal\n */\nfunction deriveKey(response: Buffer, salt: Buffer): Buffer {\n // Use HKDF to derive a 256-bit key\n // hkdfSync returns ArrayBuffer, convert to Buffer\n const derived = crypto.hkdfSync('sha256', response, salt, 'attest-it-yubikey-v1', 32)\n return Buffer.from(derived)\n}\n","/**\n * Registry for key provider implementations.\n *\n * @remarks\n * The registry maintains a mapping of provider types to factory functions,\n * allowing dynamic creation of key providers based on configuration.\n *\n * @packageDocumentation\n */\n\nimport type { KeyProvider, KeyProviderConfig } from './types.js'\nimport { FilesystemKeyProvider } from './filesystem-provider.js'\nimport { OnePasswordKeyProvider } from './one-password-provider.js'\nimport { MacOSKeychainKeyProvider } from './macos-keychain-provider.js'\nimport { YubiKeyProvider } from './yubikey-provider.js'\n\n/**\n * Type for a key provider factory function.\n * @public\n */\nexport type KeyProviderFactory = (config: KeyProviderConfig) => KeyProvider\n\n/**\n * Registry for key provider implementations.\n *\n * @remarks\n * The registry allows registration of custom key providers and provides\n * a factory method to create provider instances from configuration.\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 KeyProviderRegistry {\n private static providers = new Map<string, KeyProviderFactory>()\n\n /**\n * Register a key provider factory.\n * @param type - Provider type identifier\n * @param factory - Factory function to create provider instances\n */\n static register(type: string, factory: KeyProviderFactory): void {\n this.providers.set(type, factory)\n }\n\n /**\n * Create a key provider from configuration.\n * @param config - Provider configuration\n * @returns A key provider instance\n * @throws Error if the provider type is not registered\n */\n static create(config: KeyProviderConfig): KeyProvider {\n const factory = this.providers.get(config.type)\n if (!factory) {\n throw new Error(\n `Unknown key provider type: ${config.type}. ` +\n `Available types: ${Array.from(this.providers.keys()).join(', ')}`,\n )\n }\n return factory(config)\n }\n\n /**\n * Get all registered provider types.\n * @returns Array of provider type identifiers\n */\n static getProviderTypes(): string[] {\n return Array.from(this.providers.keys())\n }\n}\n\n// Register the filesystem provider by default\nKeyProviderRegistry.register('filesystem', (config) => {\n const privateKeyPath =\n typeof config.options.privateKeyPath === 'string' ? config.options.privateKeyPath : undefined\n\n // Only pass privateKeyPath if it's defined (to satisfy exactOptionalPropertyTypes)\n if (privateKeyPath !== undefined) {\n return new FilesystemKeyProvider({ privateKeyPath })\n }\n return new FilesystemKeyProvider()\n})\n\n// Register the 1Password provider\nKeyProviderRegistry.register('1password', (config) => {\n const { options } = config\n const account = typeof options.account === 'string' ? options.account : undefined\n const vault = typeof options.vault === 'string' ? options.vault : ''\n const itemName = typeof options.itemName === 'string' ? options.itemName : ''\n\n if (!vault || !itemName) {\n throw new Error('1Password provider requires vault and itemName options')\n }\n\n // Only pass account if it's defined (to satisfy exactOptionalPropertyTypes)\n if (account !== undefined) {\n return new OnePasswordKeyProvider({ account, vault, itemName })\n }\n return new OnePasswordKeyProvider({ vault, itemName })\n})\n\n// Register the macOS Keychain provider\nKeyProviderRegistry.register('macos-keychain', (config) => {\n const { options } = config\n const itemName = typeof options.itemName === 'string' ? options.itemName : ''\n\n if (!itemName) {\n throw new Error('macOS Keychain provider requires itemName option')\n }\n\n return new MacOSKeychainKeyProvider({ itemName })\n})\n\n// Register the YubiKey provider\nKeyProviderRegistry.register('yubikey', (config) => {\n const { options } = config\n const encryptedKeyPath =\n typeof options.encryptedKeyPath === 'string' ? options.encryptedKeyPath : ''\n\n if (!encryptedKeyPath) {\n throw new Error('YubiKey provider requires encryptedKeyPath option')\n }\n\n const slot =\n typeof options.slot === 'number' && (options.slot === 1 || options.slot === 2)\n ? options.slot\n : undefined\n const serial = typeof options.serial === 'string' ? options.serial : undefined\n\n // Build options object, only including defined properties\n const providerOptions: { encryptedKeyPath: string; slot?: 1 | 2; serial?: string } = {\n encryptedKeyPath,\n }\n if (slot !== undefined) {\n providerOptions.slot = slot\n }\n if (serial !== undefined) {\n providerOptions.serial = serial\n }\n\n return new YubiKeyProvider(providerOptions)\n})\n","/**\n * User preferences management for attest-it.\n * Stored separately from identity config to allow preferences\n * before any identity exists.\n * @packageDocumentation\n */\n\nimport { mkdir as mkdirAsync, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml'\nimport { z } from 'zod'\nimport { getAttestItConfigDir } from './config.js'\n\n/**\n * Zod schema for CLI experience preferences.\n * This ensures type safety when loading from disk.\n */\nconst cliExperienceSchema = z\n .object({\n declinedCompletionInstall: z.boolean().optional(),\n })\n .strict()\n\n/**\n * Zod schema for user preferences.\n * Using strict() ensures no unknown keys are accepted.\n */\nconst userPreferencesSchema = z\n .object({\n cliExperience: cliExperienceSchema.optional(),\n })\n .strict()\n\n/**\n * CLI experience preferences (UX-related settings).\n * @public\n */\nexport interface CliExperiencePreferences {\n /** Whether the user has declined shell completion installation */\n declinedCompletionInstall?: boolean\n}\n\n/**\n * User preferences stored in ~/.config/attest-it/preferences.yaml\n * @public\n */\nexport interface UserPreferences {\n /** CLI experience and UX settings */\n cliExperience?: CliExperiencePreferences\n}\n\n/**\n * Get the path to the preferences file.\n *\n * @returns Path to the preferences file\n * @public\n */\nexport function getPreferencesPath(): string {\n return join(getAttestItConfigDir(), 'preferences.yaml')\n}\n\n/**\n * Load user preferences from file.\n * Validates the file contents against the schema and returns\n * only valid, known preferences.\n *\n * @returns User preferences, or empty object if file doesn't exist\n * @public\n */\nexport async function loadPreferences(): Promise<UserPreferences> {\n const prefsPath = getPreferencesPath()\n\n try {\n const content = await readFile(prefsPath, 'utf8')\n const parsed: unknown = parseYaml(content)\n\n // Validate and parse with Zod - strips unknown keys via strict()\n // If parsing fails, return empty preferences (graceful degradation)\n const result = userPreferencesSchema.safeParse(parsed)\n if (result.success) {\n // Transform Zod output to match interface (handle undefined optionals)\n const prefs: UserPreferences = {}\n if (result.data.cliExperience) {\n prefs.cliExperience = {\n ...(result.data.cliExperience.declinedCompletionInstall !== undefined && {\n declinedCompletionInstall: result.data.cliExperience.declinedCompletionInstall,\n }),\n }\n }\n return prefs\n }\n\n // Log warning but don't fail - preferences aren't critical\n console.warn('Invalid preferences file, using defaults:', result.error.message)\n return {}\n } catch (error) {\n // Return empty preferences if file doesn't exist\n if (\n error &&\n typeof error === 'object' &&\n 'code' in error &&\n (error.code === 'ENOENT' || error.code === 'ENOTDIR')\n ) {\n return {}\n }\n throw error\n }\n}\n\n/**\n * Save user preferences to file.\n *\n * @param preferences - Preferences to save\n * @public\n */\nexport async function savePreferences(preferences: UserPreferences): Promise<void> {\n const prefsPath = getPreferencesPath()\n const content = stringifyYaml(preferences)\n\n // Ensure parent directory exists\n const dir = dirname(prefsPath)\n await mkdirAsync(dir, { recursive: true })\n\n await writeFile(prefsPath, content, 'utf8')\n}\n\n/**\n * Update a single preference value.\n *\n * @param key - Preference key to update\n * @param value - New value\n * @public\n */\nexport async function setPreference<K extends keyof UserPreferences>(\n key: K,\n value: UserPreferences[K],\n): Promise<void> {\n const prefs = await loadPreferences()\n prefs[key] = value\n await savePreferences(prefs)\n}\n\n/**\n * Get a single preference value.\n *\n * @param key - Preference key to get\n * @returns Preference value, or undefined if not set\n * @public\n */\nexport async function getPreference<K extends keyof UserPreferences>(\n key: K,\n): Promise<UserPreferences[K] | undefined> {\n const prefs = await loadPreferences()\n return prefs[key]\n}\n","/**\n * Authorization logic for attest-it v2.0.\n * @packageDocumentation\n */\n\nimport ms from 'ms'\n\nimport type { AttestItConfig, GateConfig, TeamMember } from './types.js'\n\n/**\n * Check if a public key belongs to an authorized signer for a gate.\n *\n * @param config - The attest-it configuration\n * @param gateId - The gate identifier (slug)\n * @param publicKey - Base64-encoded Ed25519 public key to check\n * @returns true if the public key belongs to an authorized signer for the gate\n * @public\n */\nexport function isAuthorizedSigner(\n config: AttestItConfig,\n gateId: string,\n publicKey: string,\n): boolean {\n // eslint-disable-next-line security/detect-object-injection\n const gate = config.gates?.[gateId]\n if (!gate) {\n return false\n }\n\n const teamMember = findTeamMemberByPublicKey(config, publicKey)\n if (!teamMember) {\n return false\n }\n\n // Find the slug for this team member\n const teamMemberSlug = findTeamMemberSlug(config, teamMember)\n if (!teamMemberSlug) {\n return false\n }\n\n return gate.authorizedSigners.includes(teamMemberSlug)\n}\n\n/**\n * Get all team members authorized to sign for a gate.\n *\n * @param config - The attest-it configuration\n * @param gateId - The gate identifier (slug)\n * @returns Array of authorized team members, or empty array if gate not found\n * @public\n */\nexport function getAuthorizedSignersForGate(config: AttestItConfig, gateId: string): TeamMember[] {\n // eslint-disable-next-line security/detect-object-injection\n const gate = config.gates?.[gateId]\n if (!gate || !config.team) {\n return []\n }\n\n const authorizedMembers: TeamMember[] = []\n for (const signerSlug of gate.authorizedSigners) {\n // eslint-disable-next-line security/detect-object-injection\n const member = config.team[signerSlug]\n if (member) {\n authorizedMembers.push(member)\n }\n }\n\n return authorizedMembers\n}\n\n/**\n * Find a team member by their public key.\n *\n * @param config - The attest-it configuration\n * @param publicKey - Base64-encoded Ed25519 public key\n * @returns The team member with matching public key, or undefined if not found\n * @public\n */\nexport function findTeamMemberByPublicKey(\n config: AttestItConfig,\n publicKey: string,\n): TeamMember | undefined {\n if (!config.team) {\n return undefined\n }\n\n for (const member of Object.values(config.team)) {\n if (member.publicKey === publicKey) {\n return member\n }\n }\n\n return undefined\n}\n\n/**\n * Find the slug for a team member.\n *\n * @param config - The attest-it configuration\n * @param teamMember - The team member to find the slug for\n * @returns The team member slug, or undefined if not found\n */\nfunction findTeamMemberSlug(config: AttestItConfig, teamMember: TeamMember): string | undefined {\n if (!config.team) {\n return undefined\n }\n\n for (const [slug, member] of Object.entries(config.team)) {\n if (member === teamMember || member.publicKey === teamMember.publicKey) {\n return slug\n }\n }\n\n return undefined\n}\n\n/**\n * Get the gate configuration for a given gate ID.\n *\n * @param config - The attest-it configuration\n * @param gateId - The gate identifier (slug)\n * @returns The gate configuration, or undefined if not found\n * @public\n */\nexport function getGate(config: AttestItConfig, gateId: string): GateConfig | undefined {\n // eslint-disable-next-line security/detect-object-injection\n return config.gates?.[gateId]\n}\n\n/**\n * Regular expression pattern for valid duration strings.\n * Matches formats like \"30d\", \"7d\", \"24h\", \"1w\", \"2y\", \"100ms\", etc.\n * Negative durations are not supported.\n * @internal\n */\nconst DURATION_PATTERN = /^\\d+(\\.\\d+)?\\s*(ms|s|m|h|d|w|y)$/i\n\n/**\n * Type guard to check if a string is a valid duration format.\n *\n * @param value - String to check\n * @returns true if the string matches the duration pattern\n * @internal\n */\nfunction isValidDurationFormat(value: string): boolean {\n return DURATION_PATTERN.test(value.trim())\n}\n\n/**\n * Parse a duration string to milliseconds.\n * Uses the ms library to parse strings like \"30d\", \"7d\", \"24h\".\n *\n * @param duration - Duration string (e.g., \"30d\", \"7d\", \"24h\")\n * @returns Duration in milliseconds\n * @throws {Error} If duration string is invalid\n * @public\n */\nexport function parseDuration(duration: string): number {\n // Validate format before calling ms to avoid type assertion issues\n if (!isValidDurationFormat(duration)) {\n throw new Error(`Invalid duration string: ${duration}`)\n }\n\n // The ms function accepts the StringValue type which is a union of specific string patterns\n // After validating the format, we can safely call ms\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- safe after format validation\n const result = ms(duration as Parameters<typeof ms>[0])\n if (typeof result !== 'number' || result <= 0) {\n throw new Error(`Invalid duration string: ${duration}`)\n }\n return result\n}\n","/**\n * Seal operations for creating, verifying, and managing seals.\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { z } from 'zod'\n\nimport * as ed25519 from '../crypto/ed25519.js'\nimport type { AttestItConfig } from '../types.js'\nimport type { Seal, SealsFile } from './types.js'\n\n/**\n * Zod schema for a single seal.\n * @internal\n */\nconst sealSchema = z.object({\n gateId: z.string().min(1, 'Gate ID cannot be empty'),\n // Fingerprint format: sha256:<hex> where hex is at least 1 character\n // Full fingerprints are 64 hex chars, but tests may use shorter values\n fingerprint: z\n .string()\n .regex(/^sha256:[a-f0-9]+$/i, 'Invalid fingerprint format (expected sha256:<hex>)'),\n timestamp: z.string().datetime({ message: 'Invalid ISO 8601 timestamp' }),\n sealedBy: z.string().min(1, 'Signer slug cannot be empty'),\n signature: z.string().min(1, 'Signature cannot be empty'),\n})\n\n/**\n * Zod schema for the seals file.\n * @internal\n */\nconst sealsFileSchema = z.object({\n version: z.literal(1, { errorMap: () => ({ message: 'Unsupported seals file version' }) }),\n seals: z.record(z.string(), sealSchema),\n})\n\n/**\n * Options for creating a seal.\n * @public\n */\nexport interface CreateSealOptions {\n /** Gate identifier (slug) */\n gateId: string\n /** SHA-256 fingerprint of the gate's content */\n fingerprint: string\n /** Team member slug creating the seal */\n sealedBy: string\n /** PEM-encoded Ed25519 private key for signing */\n privateKey: string\n}\n\n/**\n * Result of seal signature verification.\n * @public\n */\nexport interface SignatureVerificationResult {\n /** Whether the seal signature is valid */\n valid: boolean\n /** Error message if verification failed */\n error?: string\n}\n\n/**\n * Create a seal by signing the canonical string: gateId:fingerprint:timestamp\n *\n * @param options - Seal creation options\n * @returns The created seal\n * @throws Error if signing fails\n * @public\n */\nexport function createSeal(options: CreateSealOptions): Seal {\n const { gateId, fingerprint, sealedBy, privateKey } = options\n\n // Create ISO 8601 timestamp\n const timestamp = new Date().toISOString()\n\n // Create canonical string to sign\n const canonicalString = `${gateId}:${fingerprint}:${timestamp}`\n\n // Sign the canonical string\n const signature = ed25519.sign(canonicalString, privateKey)\n\n return {\n gateId,\n fingerprint,\n timestamp,\n sealedBy,\n signature,\n }\n}\n\n/**\n * Verify a seal's signature against the team member's public key.\n *\n * @param seal - The seal to verify\n * @param config - The attest-it configuration containing team members\n * @returns Verification result with success status and optional error message\n * @public\n */\nexport function verifySeal(seal: Seal, config: AttestItConfig): SignatureVerificationResult {\n const { gateId, fingerprint, timestamp, sealedBy, signature } = seal\n\n // Look up team member by slug\n if (!config.team) {\n return {\n valid: false,\n error: `No team configuration found`,\n }\n }\n\n // eslint-disable-next-line security/detect-object-injection\n const teamMember = config.team[sealedBy]\n if (!teamMember) {\n return {\n valid: false,\n error: `Team member '${sealedBy}' not found in configuration`,\n }\n }\n\n // Reconstruct canonical string\n const canonicalString = `${gateId}:${fingerprint}:${timestamp}`\n\n // Verify signature\n try {\n const isValid = ed25519.verify(canonicalString, signature, teamMember.publicKey)\n if (!isValid) {\n return {\n valid: false,\n error: 'Signature verification failed',\n }\n }\n\n return { valid: true }\n } catch (error) {\n return {\n valid: false,\n error: `Signature verification error: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n}\n\n/**\n * Parse and validate seals file content.\n *\n * @param content - JSON content to parse\n * @returns Validated SealsFile\n * @throws Error if validation fails\n * @internal\n */\nfunction parseSealsContent(content: string): SealsFile {\n let rawData: unknown\n try {\n rawData = JSON.parse(content)\n } catch (error) {\n throw new Error(`Invalid JSON: ${error instanceof Error ? error.message : String(error)}`)\n }\n\n const result = sealsFileSchema.safeParse(rawData)\n if (!result.success) {\n const issues = result.error.issues\n .map((issue) => ` - ${issue.path.join('.')}: ${issue.message}`)\n .join('\\n')\n throw new Error(`Invalid seals file:\\n${issues}`)\n }\n\n return result.data\n}\n\n/**\n * Read seals from the seals.json file (async).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @returns The seals file contents, or an empty seals file if the file doesn't exist\n * @throws Error if file exists but cannot be read or parsed\n * @public\n */\nexport async function readSeals(dir: string): Promise<SealsFile> {\n const sealsPath = path.join(dir, '.attest-it', 'seals.json')\n\n try {\n const content = await fs.promises.readFile(sealsPath, 'utf8')\n return parseSealsContent(content)\n } catch (error) {\n // If file doesn't exist, return empty seals file\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n return {\n version: 1,\n seals: {},\n }\n }\n\n // Re-throw other errors (permission denied, parse errors, etc.)\n throw new Error(\n `Failed to read seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n\n/**\n * Read seals from the seals.json file (sync).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @returns The seals file contents, or an empty seals file if the file doesn't exist\n * @throws Error if file exists but cannot be read or parsed\n * @public\n */\nexport function readSealsSync(dir: string): SealsFile {\n const sealsPath = path.join(dir, '.attest-it', 'seals.json')\n\n try {\n const content = fs.readFileSync(sealsPath, 'utf8')\n return parseSealsContent(content)\n } catch (error) {\n // If file doesn't exist, return empty seals file\n if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {\n return {\n version: 1,\n seals: {},\n }\n }\n\n // Re-throw other errors (permission denied, parse errors, etc.)\n throw new Error(\n `Failed to read seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n\n/**\n * Write seals to the seals.json file (async).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @param sealsFile - The seals file to write\n * @throws Error if file cannot be written\n * @public\n */\nexport async function writeSeals(dir: string, sealsFile: SealsFile): Promise<void> {\n const attestItDir = path.join(dir, '.attest-it')\n const sealsPath = path.join(attestItDir, 'seals.json')\n\n try {\n // Ensure .attest-it directory exists\n await fs.promises.mkdir(attestItDir, { recursive: true })\n\n // Write seals file with pretty formatting\n const content = JSON.stringify(sealsFile, null, 2) + '\\n'\n await fs.promises.writeFile(sealsPath, content, 'utf8')\n } catch (error) {\n throw new Error(\n `Failed to write seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n\n/**\n * Write seals to the seals.json file (sync).\n *\n * @param dir - Directory containing .attest-it/seals.json\n * @param sealsFile - The seals file to write\n * @throws Error if file cannot be written\n * @public\n */\nexport function writeSealsSync(dir: string, sealsFile: SealsFile): void {\n const attestItDir = path.join(dir, '.attest-it')\n const sealsPath = path.join(attestItDir, 'seals.json')\n\n try {\n // Ensure .attest-it directory exists\n fs.mkdirSync(attestItDir, { recursive: true })\n\n // Write seals file with pretty formatting\n const content = JSON.stringify(sealsFile, null, 2) + '\\n'\n fs.writeFileSync(sealsPath, content, 'utf8')\n } catch (error) {\n throw new Error(\n `Failed to write seals file: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n","/**\n * Seal verification logic and states.\n * @packageDocumentation\n */\n\nimport { parseDuration, getGate, isAuthorizedSigner } from '../authorization.js'\nimport type { AttestItConfig } from '../types.js'\nimport type { Seal, SealsFile } from './types.js'\nimport { verifySeal } from './operations.js'\n\n/**\n * Verification state for a gate's seal.\n * @public\n */\nexport type VerificationState =\n | 'VALID' // Seal exists, signature valid, not stale, fingerprint matches\n | 'MISSING' // No seal for this gate\n | 'STALE' // Seal exists but exceeds maxAge\n | 'FINGERPRINT_MISMATCH' // Seal fingerprint doesn't match current fingerprint\n | 'INVALID_SIGNATURE' // Signature doesn't verify\n | 'UNKNOWN_SIGNER' // sealedBy not in team or not authorized for this gate\n\n/**\n * Result of verifying a single gate's seal.\n * @public\n */\nexport interface SealVerificationResult {\n /** Gate identifier */\n gateId: string\n /** Verification state */\n state: VerificationState\n /** The seal, if one exists */\n seal?: Seal\n /** Human-readable message explaining the state */\n message?: string\n}\n\n/**\n * Verify a single gate's seal.\n *\n * @param config - The attest-it configuration\n * @param gateId - Gate identifier to verify\n * @param seals - The seals file containing all seals\n * @param currentFingerprint - Current computed fingerprint for the gate\n * @returns Verification result for the gate\n * @public\n */\nexport function verifyGateSeal(\n config: AttestItConfig,\n gateId: string,\n seals: SealsFile,\n currentFingerprint: string,\n): SealVerificationResult {\n // Get the gate configuration\n const gate = getGate(config, gateId)\n if (!gate) {\n return {\n gateId,\n state: 'MISSING',\n message: `Gate '${gateId}' not found in configuration`,\n }\n }\n\n // Check if a seal exists for this gate\n // eslint-disable-next-line security/detect-object-injection\n const seal = seals.seals[gateId]\n if (!seal) {\n return {\n gateId,\n state: 'MISSING',\n message: `No seal found for gate '${gateId}'`,\n }\n }\n\n // Check if fingerprint matches\n if (seal.fingerprint !== currentFingerprint) {\n return {\n gateId,\n state: 'FINGERPRINT_MISMATCH',\n seal,\n message: `Fingerprint changed since seal was created`,\n }\n }\n\n // Check if signer is in team and authorized\n if (!config.team) {\n return {\n gateId,\n state: 'UNKNOWN_SIGNER',\n seal,\n message: `No team configuration found`,\n }\n }\n\n const teamMember = config.team[seal.sealedBy]\n if (!teamMember) {\n return {\n gateId,\n state: 'UNKNOWN_SIGNER',\n seal,\n message: `Signer '${seal.sealedBy}' not found in team`,\n }\n }\n\n // Check if signer is authorized for this gate\n const authorized = isAuthorizedSigner(config, gateId, teamMember.publicKey)\n if (!authorized) {\n return {\n gateId,\n state: 'UNKNOWN_SIGNER',\n seal,\n message: `Signer '${seal.sealedBy}' is not authorized for gate '${gateId}'`,\n }\n }\n\n // Verify signature\n const verificationResult = verifySeal(seal, config)\n if (!verificationResult.valid) {\n return {\n gateId,\n state: 'INVALID_SIGNATURE',\n seal,\n message: verificationResult.error ?? 'Signature verification failed',\n }\n }\n\n // Check if seal is stale (exceeds maxAge)\n try {\n const maxAgeMs = parseDuration(gate.maxAge)\n const sealTimestamp = new Date(seal.timestamp).getTime()\n const now = Date.now()\n const ageMs = now - sealTimestamp\n\n if (ageMs > maxAgeMs) {\n const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24))\n const maxAgeDays = Math.floor(maxAgeMs / (1000 * 60 * 60 * 24))\n return {\n gateId,\n state: 'STALE',\n seal,\n message: `Seal is ${ageDays.toString()} days old, exceeds maxAge of ${maxAgeDays.toString()} days`,\n }\n }\n } catch (error) {\n // If we can't parse maxAge, fail closed - treat as stale to enforce freshness\n // This prevents bypassing staleness checks with invalid maxAge values\n return {\n gateId,\n state: 'STALE',\n seal,\n message: `Cannot verify freshness: invalid maxAge format: ${error instanceof Error ? error.message : String(error)}`,\n }\n }\n\n // All checks passed\n return {\n gateId,\n state: 'VALID',\n seal,\n }\n}\n\n/**\n * Verify all gates' seals.\n *\n * @param config - The attest-it configuration\n * @param seals - The seals file containing all seals\n * @param fingerprints - Map of gate IDs to their current fingerprints\n * @returns Array of verification results for all gates\n * @public\n */\nexport function verifyAllSeals(\n config: AttestItConfig,\n seals: SealsFile,\n fingerprints: Record<string, string>,\n): SealVerificationResult[] {\n if (!config.gates) {\n return []\n }\n\n const results: SealVerificationResult[] = []\n\n for (const gateId of Object.keys(config.gates)) {\n // eslint-disable-next-line security/detect-object-injection\n const fingerprint = fingerprints[gateId]\n if (!fingerprint) {\n results.push({\n gateId,\n state: 'MISSING',\n message: `No fingerprint computed for gate '${gateId}'`,\n })\n continue\n }\n\n const result = verifyGateSeal(config, gateId, seals, fingerprint)\n results.push(result)\n }\n\n return results\n}\n","/**\n * @attest-it/core\n *\n * Core functionality for the attest-it testing framework.\n * @packageDocumentation\n */\n\n/**\n * Package version\n * @public\n */\nexport const version = '0.0.0'\n\n// Types\nexport type {\n AttestItSettings,\n KeyProviderSettings,\n TeamMember,\n FingerprintConfig,\n GateConfig,\n SuiteConfig,\n AttestItConfig,\n Attestation,\n AttestationsFile,\n VerificationStatus,\n SuiteVerificationResult,\n} from './types.js'\n\n// Config\nexport {\n loadConfig,\n loadConfigSync,\n findConfigPath,\n resolveConfigPaths,\n toAttestItConfig,\n ConfigValidationError,\n ConfigNotFoundError,\n type Config,\n} from './config.js'\n\n// Split config support\nexport {\n // Policy config\n type PolicyConfig,\n policySchema,\n parsePolicyContent,\n PolicyValidationError,\n // Operational config\n type OperationalConfig,\n operationalSchema,\n parseOperationalContent,\n OperationalValidationError,\n // Merge and validation\n mergeConfigs,\n validateSuiteGateReferences,\n type ValidationError,\n type ValidationErrorType,\n} from './config/index.js'\n\n// Fingerprinting\nexport { computeFingerprint, computeFingerprintSync, listPackageFiles } from './fingerprint.js'\nexport type { FingerprintOptions, FingerprintResult } from './fingerprint.js'\n\n// Attestations\nexport {\n readAttestations,\n readAttestationsSync,\n writeAttestations,\n writeAttestationsSync,\n findAttestation,\n upsertAttestation,\n removeAttestation,\n canonicalizeAttestations,\n createAttestation,\n writeSignedAttestations,\n readAndVerifyAttestations,\n SignatureInvalidError,\n} from './attestation.js'\nexport type {\n WriteSignedAttestationsOptions,\n ReadSignedAttestationsOptions,\n} from './attestation.js'\n\n// Cryptography\nexport {\n checkOpenSSL,\n getDefaultPrivateKeyPath,\n getDefaultPublicKeyPath,\n generateKeyPair,\n sign,\n verify,\n setKeyPermissions,\n} from './crypto.js'\nexport type {\n KeyPaths,\n KeygenOptions,\n SignOptions,\n VerifyOptions as CryptoVerifyOptions,\n} from './crypto.js'\n\n// Ed25519 Cryptography\nexport {\n generateKeyPair as generateEd25519KeyPair,\n sign as signEd25519,\n verify as verifyEd25519,\n getPublicKeyFromPrivate,\n} from './crypto/ed25519.js'\nexport type { KeyPair as Ed25519KeyPair } from './crypto/ed25519.js'\n\n// Verification\nexport { verifyAttestations } from './verify.js'\nexport type { VerifyOptions, VerifyResult } from './verify.js'\n\n// Key Providers\nexport {\n FilesystemKeyProvider,\n OnePasswordKeyProvider,\n MacOSKeychainKeyProvider,\n YubiKeyProvider,\n KeyProviderRegistry,\n type KeyProvider,\n type KeyProviderConfig,\n type KeyRetrievalResult,\n type KeyGenerationResult,\n type KeygenProviderOptions,\n type FilesystemKeyProviderOptions,\n type OnePasswordKeyProviderOptions,\n type OnePasswordAccount,\n type OnePasswordVault,\n type MacOSKeychainKeyProviderOptions,\n type MacOSKeychain,\n type YubiKeyProviderOptions,\n type YubiKeyInfo,\n type KeyProviderFactory,\n} from './key-provider/index.js'\n\n// Identity System\nexport {\n getLocalConfigPath,\n getAttestItConfigDir,\n setAttestItHomeDir,\n getAttestItHomeDir,\n loadLocalConfig,\n loadLocalConfigSync,\n saveLocalConfig,\n saveLocalConfigSync,\n getActiveIdentity,\n LocalConfigValidationError,\n type PrivateKeyRef,\n type Identity,\n type LocalConfig,\n} from './identity/index.js'\n\n// User Preferences\nexport {\n getPreferencesPath,\n loadPreferences,\n savePreferences,\n setPreference,\n getPreference,\n type UserPreferences,\n type CliExperiencePreferences,\n} from './identity/index.js'\n\n// Authorization\nexport {\n isAuthorizedSigner,\n getAuthorizedSignersForGate,\n findTeamMemberByPublicKey,\n getGate,\n parseDuration,\n} from './authorization.js'\n\n// Seal System\nexport {\n createSeal,\n verifySeal,\n readSeals,\n readSealsSync,\n writeSeals,\n writeSealsSync,\n verifyGateSeal,\n verifyAllSeals,\n type Seal,\n type SealsFile,\n type CreateSealOptions,\n type SignatureVerificationResult,\n type VerificationState,\n type SealVerificationResult,\n} from './seal/index.js'\n"]}
|