@enactprotocol/trust 2.1.15 → 2.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -6,6 +6,8 @@
6
6
  */
7
7
  export declare const version = "0.1.0";
8
8
  export { hashContent, hashBuffer, hashFile } from "./hash";
9
+ export { createChecksumManifest, computeManifestHash, verifyChecksumManifest, verifyManifestAttestation, parseChecksumManifest, serializeChecksumManifest, MANIFEST_VERSION, } from "./manifest";
10
+ export type { ChecksumManifest, FileChecksum, CreateManifestOptions, ManifestVerificationResult, ManifestAttestationVerificationResult, } from "./manifest";
9
11
  export { generateKeyPair, isValidPEMKey, getKeyTypeFromPEM } from "./keys";
10
12
  export * from "./sigstore";
11
13
  export type { HashAlgorithm, HashResult, FileHashOptions, KeyType, KeyFormat, KeyPair, KeyGenerationOptions, } from "./types";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAG3D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAG3E,cAAc,YAAY,CAAC;AAG3B,YAAY,EACV,aAAa,EACb,UAAU,EACV,eAAe,EACf,OAAO,EACP,SAAS,EACT,OAAO,EACP,oBAAoB,GACrB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAG3D,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,qBAAqB,EACrB,0BAA0B,EAC1B,qCAAqC,GACtC,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAG3E,cAAc,YAAY,CAAC;AAG3B,YAAY,EACV,aAAa,EACb,UAAU,EACV,eAAe,EACf,OAAO,EACP,SAAS,EACT,OAAO,EACP,oBAAoB,GACrB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -7,6 +7,8 @@
7
7
  export const version = "0.1.0";
8
8
  // Hash utilities
9
9
  export { hashContent, hashBuffer, hashFile } from "./hash";
10
+ // Checksum manifest (for deterministic signing)
11
+ export { createChecksumManifest, computeManifestHash, verifyChecksumManifest, verifyManifestAttestation, parseChecksumManifest, serializeChecksumManifest, MANIFEST_VERSION, } from "./manifest";
10
12
  // Key management
11
13
  export { generateKeyPair, isValidPEMKey, getKeyTypeFromPEM } from "./keys";
12
14
  // Sigstore integration (attestation signing, verification, trust policies)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE3D,iBAAiB;AACjB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAE3E,2EAA2E;AAC3E,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE3D,gDAAgD;AAChD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AASpB,iBAAiB;AACjB,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAE3E,2EAA2E;AAC3E,cAAc,YAAY,CAAC"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Checksum manifest creation and verification
3
+ *
4
+ * Creates deterministic manifests of file checksums for signing.
5
+ * This enables pre-publish signing by avoiding tar.gz non-determinism.
6
+ *
7
+ * Based on recommendation from Bob Callaway (Google Sigstore team):
8
+ * "Most folks would just create and sign a manifest of checksums."
9
+ */
10
+ import type { HashResult } from "./types";
11
+ /**
12
+ * Checksum manifest version
13
+ */
14
+ export declare const MANIFEST_VERSION: "1.0";
15
+ /**
16
+ * Individual file checksum entry
17
+ */
18
+ export interface FileChecksum {
19
+ /** Relative path from tool root (always uses forward slashes) */
20
+ path: string;
21
+ /** SHA-256 hash of file contents */
22
+ sha256: string;
23
+ /** File size in bytes */
24
+ size: number;
25
+ }
26
+ /**
27
+ * Complete checksum manifest for a tool
28
+ */
29
+ export interface ChecksumManifest {
30
+ /** Manifest format version */
31
+ version: typeof MANIFEST_VERSION;
32
+ /** Tool metadata */
33
+ tool: {
34
+ /** Tool name (e.g., "author/tool-name") */
35
+ name: string;
36
+ /** Tool version (e.g., "1.0.0") */
37
+ version: string;
38
+ };
39
+ /** Array of file checksums, sorted by path */
40
+ files: FileChecksum[];
41
+ /** Hash of the manifest itself (for signing) */
42
+ manifestHash: {
43
+ algorithm: "sha256";
44
+ digest: string;
45
+ };
46
+ }
47
+ /**
48
+ * Options for creating a checksum manifest
49
+ */
50
+ export interface CreateManifestOptions {
51
+ /** Patterns to ignore (glob-style, relative to tool root) */
52
+ ignorePatterns?: string[] | undefined;
53
+ /** Progress callback for each file processed */
54
+ onProgress?: ((file: string) => void) | undefined;
55
+ }
56
+ /**
57
+ * Result of manifest verification
58
+ */
59
+ export interface ManifestVerificationResult {
60
+ /** Whether all files match the manifest */
61
+ valid: boolean;
62
+ /** Error messages if verification failed */
63
+ errors?: string[] | undefined;
64
+ /** Files in manifest but missing from directory */
65
+ missingFiles?: string[] | undefined;
66
+ /** Files that exist but have different hashes */
67
+ modifiedFiles?: string[] | undefined;
68
+ /** Files in directory but not in manifest */
69
+ extraFiles?: string[] | undefined;
70
+ }
71
+ /**
72
+ * Create a checksum manifest for a tool directory
73
+ *
74
+ * Scans all files in the directory, computes SHA-256 hashes,
75
+ * and creates a manifest suitable for signing.
76
+ *
77
+ * @param toolDir - Path to the tool directory
78
+ * @param toolName - Tool name (e.g., "author/tool-name")
79
+ * @param toolVersion - Tool version (e.g., "1.0.0")
80
+ * @param options - Optional settings for ignore patterns and progress
81
+ * @returns Complete checksum manifest ready for signing
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const manifest = await createChecksumManifest(
86
+ * "./my-tool",
87
+ * "alice/my-tool",
88
+ * "1.0.0",
89
+ * { onProgress: (file) => console.log(`Hashing: ${file}`) }
90
+ * );
91
+ * ```
92
+ */
93
+ export declare function createChecksumManifest(toolDir: string, toolName: string, toolVersion: string, options?: CreateManifestOptions): Promise<ChecksumManifest>;
94
+ /**
95
+ * Compute the canonical hash of a manifest (for signing)
96
+ *
97
+ * Creates a deterministic hash by:
98
+ * 1. Excluding the manifestHash field itself
99
+ * 2. Using canonical JSON (sorted keys, no whitespace)
100
+ * 3. Computing SHA-256
101
+ *
102
+ * @param manifest - The manifest to hash (manifestHash field is ignored)
103
+ * @returns Hash result with algorithm and digest
104
+ */
105
+ export declare function computeManifestHash(manifest: Omit<ChecksumManifest, "manifestHash"> | ChecksumManifest): HashResult;
106
+ /**
107
+ * Verify that files in a directory match a checksum manifest
108
+ *
109
+ * @param toolDir - Path to the tool directory
110
+ * @param manifest - The manifest to verify against
111
+ * @param options - Optional settings for ignore patterns
112
+ * @returns Verification result with details on any mismatches
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * const result = await verifyChecksumManifest("./my-tool", manifest);
117
+ * if (!result.valid) {
118
+ * console.error("Verification failed:", result.errors);
119
+ * }
120
+ * ```
121
+ */
122
+ export declare function verifyChecksumManifest(toolDir: string, manifest: ChecksumManifest, options?: {
123
+ ignorePatterns?: string[];
124
+ }): Promise<ManifestVerificationResult>;
125
+ /**
126
+ * Parse a checksum manifest from JSON string
127
+ *
128
+ * @param json - JSON string containing the manifest
129
+ * @returns Parsed manifest
130
+ * @throws Error if JSON is invalid or manifest structure is wrong
131
+ */
132
+ export declare function parseChecksumManifest(json: string): ChecksumManifest;
133
+ /**
134
+ * Serialize a checksum manifest to JSON string (pretty-printed for storage)
135
+ *
136
+ * @param manifest - The manifest to serialize
137
+ * @returns Pretty-printed JSON string
138
+ */
139
+ export declare function serializeChecksumManifest(manifest: ChecksumManifest): string;
140
+ /**
141
+ * Result of verifying a manifest attestation
142
+ */
143
+ export interface ManifestAttestationVerificationResult {
144
+ /** Whether the attestation is valid */
145
+ valid: boolean;
146
+ /** The auditor identity (email) from the certificate */
147
+ auditor?: string | undefined;
148
+ /** The OIDC provider used for signing */
149
+ provider?: string | undefined;
150
+ /** Error message if verification failed */
151
+ error?: string | undefined;
152
+ /** Detailed verification results */
153
+ details?: {
154
+ /** Whether the Sigstore bundle was verified */
155
+ bundleVerified: boolean;
156
+ /** Whether the manifest hash matches what was signed */
157
+ manifestHashMatches: boolean;
158
+ /** Whether the manifest matches the current files */
159
+ manifestMatchesFiles?: boolean | undefined;
160
+ } | undefined;
161
+ }
162
+ /**
163
+ * Verify a manifest-based attestation
164
+ *
165
+ * This verifies that:
166
+ * 1. The Sigstore bundle is valid
167
+ * 2. The bundle was signed over the manifest hash
168
+ * 3. Optionally, the manifest matches the current files on disk
169
+ *
170
+ * @param manifest - The checksum manifest that was signed
171
+ * @param sigstoreBundle - The Sigstore bundle containing the signature
172
+ * @param options - Verification options
173
+ * @returns Verification result
174
+ */
175
+ export declare function verifyManifestAttestation(manifest: ChecksumManifest, sigstoreBundle: unknown, options?: {
176
+ /** If provided, also verify manifest matches files in this directory */
177
+ toolDir?: string | undefined;
178
+ /** Additional patterns to ignore when verifying against directory */
179
+ ignorePatterns?: string[] | undefined;
180
+ }): Promise<ManifestAttestationVerificationResult>;
181
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,402 @@
1
+ /**
2
+ * Checksum manifest creation and verification
3
+ *
4
+ * Creates deterministic manifests of file checksums for signing.
5
+ * This enables pre-publish signing by avoiding tar.gz non-determinism.
6
+ *
7
+ * Based on recommendation from Bob Callaway (Google Sigstore team):
8
+ * "Most folks would just create and sign a manifest of checksums."
9
+ */
10
+ import { readdirSync, statSync } from "node:fs";
11
+ import { join, posix, relative, sep } from "node:path";
12
+ import { hashContent, hashFile } from "./hash";
13
+ // ============================================================================
14
+ // Types
15
+ // ============================================================================
16
+ /**
17
+ * Checksum manifest version
18
+ */
19
+ export const MANIFEST_VERSION = "1.0";
20
+ // ============================================================================
21
+ // Default Ignore Patterns
22
+ // ============================================================================
23
+ /**
24
+ * Files that should always be ignored when creating manifests
25
+ */
26
+ const ALWAYS_IGNORE = [
27
+ // Manifest artifacts (we're creating these)
28
+ ".enact-manifest.json",
29
+ ".sigstore-bundle.json",
30
+ // Version control
31
+ ".git",
32
+ ".gitignore",
33
+ ".gitattributes",
34
+ // OS artifacts
35
+ ".DS_Store",
36
+ "Thumbs.db",
37
+ // IDE/Editor
38
+ ".vscode",
39
+ ".idea",
40
+ "*.swp",
41
+ "*.swo",
42
+ // Dependencies (should be installed, not bundled)
43
+ "node_modules",
44
+ "__pycache__",
45
+ ".pytest_cache",
46
+ "*.pyc",
47
+ "*.pyo",
48
+ // Build artifacts
49
+ "dist",
50
+ "build",
51
+ ".next",
52
+ // Logs
53
+ "*.log",
54
+ "npm-debug.log*",
55
+ ];
56
+ // ============================================================================
57
+ // Helper Functions
58
+ // ============================================================================
59
+ /**
60
+ * Check if a path should be ignored
61
+ */
62
+ function shouldIgnore(relativePath, fileName, customPatterns = []) {
63
+ const allPatterns = [...ALWAYS_IGNORE, ...customPatterns];
64
+ for (const pattern of allPatterns) {
65
+ // Exact match
66
+ if (pattern === fileName || pattern === relativePath) {
67
+ return true;
68
+ }
69
+ // Glob pattern matching (simplified)
70
+ if (pattern.startsWith("*")) {
71
+ const suffix = pattern.slice(1);
72
+ if (fileName.endsWith(suffix) || relativePath.endsWith(suffix)) {
73
+ return true;
74
+ }
75
+ }
76
+ // Directory pattern (pattern without extension matches directories)
77
+ if (!pattern.includes(".") && !pattern.includes("*")) {
78
+ if (relativePath.startsWith(`${pattern}/`) || relativePath === pattern) {
79
+ return true;
80
+ }
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+ /**
86
+ * Normalize path to use forward slashes (for cross-platform consistency)
87
+ */
88
+ function normalizePath(filePath) {
89
+ return filePath.split(sep).join(posix.sep);
90
+ }
91
+ /**
92
+ * Recursively collect all files in a directory
93
+ */
94
+ function collectFiles(dir, baseDir, ignorePatterns, files = []) {
95
+ const entries = readdirSync(dir, { withFileTypes: true });
96
+ for (const entry of entries) {
97
+ const fullPath = join(dir, entry.name);
98
+ const relativePath = normalizePath(relative(baseDir, fullPath));
99
+ // Check if should be ignored
100
+ if (shouldIgnore(relativePath, entry.name, ignorePatterns)) {
101
+ continue;
102
+ }
103
+ if (entry.isDirectory()) {
104
+ collectFiles(fullPath, baseDir, ignorePatterns, files);
105
+ }
106
+ else if (entry.isFile()) {
107
+ files.push(fullPath);
108
+ }
109
+ // Skip symlinks and other special files
110
+ }
111
+ return files;
112
+ }
113
+ /**
114
+ * Create canonical JSON string for hashing
115
+ *
116
+ * - Sorts object keys recursively
117
+ * - No whitespace (minified)
118
+ * - Consistent output across platforms
119
+ */
120
+ function canonicalJSON(obj) {
121
+ if (obj === null || typeof obj !== "object") {
122
+ return JSON.stringify(obj);
123
+ }
124
+ if (Array.isArray(obj)) {
125
+ return `[${obj.map(canonicalJSON).join(",")}]`;
126
+ }
127
+ // Sort keys and recursively process
128
+ const sortedKeys = Object.keys(obj).sort();
129
+ const pairs = sortedKeys.map((key) => `${JSON.stringify(key)}:${canonicalJSON(obj[key])}`);
130
+ return `{${pairs.join(",")}}`;
131
+ }
132
+ // ============================================================================
133
+ // Main Functions
134
+ // ============================================================================
135
+ /**
136
+ * Create a checksum manifest for a tool directory
137
+ *
138
+ * Scans all files in the directory, computes SHA-256 hashes,
139
+ * and creates a manifest suitable for signing.
140
+ *
141
+ * @param toolDir - Path to the tool directory
142
+ * @param toolName - Tool name (e.g., "author/tool-name")
143
+ * @param toolVersion - Tool version (e.g., "1.0.0")
144
+ * @param options - Optional settings for ignore patterns and progress
145
+ * @returns Complete checksum manifest ready for signing
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * const manifest = await createChecksumManifest(
150
+ * "./my-tool",
151
+ * "alice/my-tool",
152
+ * "1.0.0",
153
+ * { onProgress: (file) => console.log(`Hashing: ${file}`) }
154
+ * );
155
+ * ```
156
+ */
157
+ export async function createChecksumManifest(toolDir, toolName, toolVersion, options = {}) {
158
+ const { ignorePatterns = [], onProgress } = options;
159
+ // Collect all files
160
+ const filePaths = collectFiles(toolDir, toolDir, ignorePatterns);
161
+ // Hash each file
162
+ const fileChecksums = [];
163
+ for (const filePath of filePaths) {
164
+ const relativePath = normalizePath(relative(toolDir, filePath));
165
+ if (onProgress) {
166
+ onProgress(relativePath);
167
+ }
168
+ const stats = statSync(filePath);
169
+ const hashResult = await hashFile(filePath);
170
+ fileChecksums.push({
171
+ path: relativePath,
172
+ sha256: hashResult.digest,
173
+ size: stats.size,
174
+ });
175
+ }
176
+ // Sort by path for deterministic ordering (using simple string comparison)
177
+ fileChecksums.sort((a, b) => {
178
+ if (a.path < b.path)
179
+ return -1;
180
+ if (a.path > b.path)
181
+ return 1;
182
+ return 0;
183
+ });
184
+ // Create manifest without the hash first
185
+ const manifestWithoutHash = {
186
+ version: MANIFEST_VERSION,
187
+ tool: {
188
+ name: toolName,
189
+ version: toolVersion,
190
+ },
191
+ files: fileChecksums,
192
+ };
193
+ // Compute manifest hash from canonical JSON
194
+ const manifestHash = computeManifestHash(manifestWithoutHash);
195
+ // Return complete manifest
196
+ return {
197
+ ...manifestWithoutHash,
198
+ manifestHash: {
199
+ algorithm: "sha256",
200
+ digest: manifestHash.digest,
201
+ },
202
+ };
203
+ }
204
+ /**
205
+ * Compute the canonical hash of a manifest (for signing)
206
+ *
207
+ * Creates a deterministic hash by:
208
+ * 1. Excluding the manifestHash field itself
209
+ * 2. Using canonical JSON (sorted keys, no whitespace)
210
+ * 3. Computing SHA-256
211
+ *
212
+ * @param manifest - The manifest to hash (manifestHash field is ignored)
213
+ * @returns Hash result with algorithm and digest
214
+ */
215
+ export function computeManifestHash(manifest) {
216
+ // Create a copy without manifestHash
217
+ const { manifestHash: _, ...manifestWithoutHash } = manifest;
218
+ // Compute canonical JSON and hash
219
+ const canonical = canonicalJSON(manifestWithoutHash);
220
+ return hashContent(canonical, "sha256");
221
+ }
222
+ /**
223
+ * Verify that files in a directory match a checksum manifest
224
+ *
225
+ * @param toolDir - Path to the tool directory
226
+ * @param manifest - The manifest to verify against
227
+ * @param options - Optional settings for ignore patterns
228
+ * @returns Verification result with details on any mismatches
229
+ *
230
+ * @example
231
+ * ```ts
232
+ * const result = await verifyChecksumManifest("./my-tool", manifest);
233
+ * if (!result.valid) {
234
+ * console.error("Verification failed:", result.errors);
235
+ * }
236
+ * ```
237
+ */
238
+ export async function verifyChecksumManifest(toolDir, manifest, options = {}) {
239
+ const { ignorePatterns = [] } = options;
240
+ const errors = [];
241
+ const missingFiles = [];
242
+ const modifiedFiles = [];
243
+ const extraFiles = [];
244
+ // First, verify the manifest hash itself
245
+ const computedHash = computeManifestHash(manifest);
246
+ if (computedHash.digest !== manifest.manifestHash.digest) {
247
+ errors.push(`Manifest hash mismatch: expected ${manifest.manifestHash.digest}, got ${computedHash.digest}`);
248
+ }
249
+ // Collect current files in directory
250
+ const currentFilePaths = collectFiles(toolDir, toolDir, ignorePatterns);
251
+ const currentFiles = new Set(currentFilePaths.map((fp) => normalizePath(relative(toolDir, fp))));
252
+ // Check each file in manifest
253
+ const manifestFiles = new Set();
254
+ for (const fileEntry of manifest.files) {
255
+ manifestFiles.add(fileEntry.path);
256
+ const fullPath = join(toolDir, fileEntry.path);
257
+ // Check if file exists
258
+ if (!currentFiles.has(fileEntry.path)) {
259
+ missingFiles.push(fileEntry.path);
260
+ errors.push(`Missing file: ${fileEntry.path}`);
261
+ continue;
262
+ }
263
+ // Check hash
264
+ try {
265
+ const hashResult = await hashFile(fullPath);
266
+ if (hashResult.digest !== fileEntry.sha256) {
267
+ modifiedFiles.push(fileEntry.path);
268
+ errors.push(`Modified file: ${fileEntry.path} (expected ${fileEntry.sha256.slice(0, 12)}..., got ${hashResult.digest.slice(0, 12)}...)`);
269
+ }
270
+ }
271
+ catch (err) {
272
+ errors.push(`Failed to hash file ${fileEntry.path}: ${err}`);
273
+ }
274
+ }
275
+ // Check for extra files not in manifest
276
+ for (const currentFile of currentFiles) {
277
+ if (!manifestFiles.has(currentFile)) {
278
+ extraFiles.push(currentFile);
279
+ errors.push(`Extra file not in manifest: ${currentFile}`);
280
+ }
281
+ }
282
+ return {
283
+ valid: errors.length === 0,
284
+ errors: errors.length > 0 ? errors : undefined,
285
+ missingFiles: missingFiles.length > 0 ? missingFiles : undefined,
286
+ modifiedFiles: modifiedFiles.length > 0 ? modifiedFiles : undefined,
287
+ extraFiles: extraFiles.length > 0 ? extraFiles : undefined,
288
+ };
289
+ }
290
+ /**
291
+ * Parse a checksum manifest from JSON string
292
+ *
293
+ * @param json - JSON string containing the manifest
294
+ * @returns Parsed manifest
295
+ * @throws Error if JSON is invalid or manifest structure is wrong
296
+ */
297
+ export function parseChecksumManifest(json) {
298
+ const parsed = JSON.parse(json);
299
+ // Validate structure
300
+ if (!parsed.version || parsed.version !== MANIFEST_VERSION) {
301
+ throw new Error(`Invalid manifest version: expected ${MANIFEST_VERSION}, got ${parsed.version}`);
302
+ }
303
+ if (!parsed.tool?.name || !parsed.tool?.version) {
304
+ throw new Error("Invalid manifest: missing tool name or version");
305
+ }
306
+ if (!Array.isArray(parsed.files)) {
307
+ throw new Error("Invalid manifest: files must be an array");
308
+ }
309
+ if (!parsed.manifestHash?.algorithm || !parsed.manifestHash?.digest) {
310
+ throw new Error("Invalid manifest: missing manifestHash");
311
+ }
312
+ return parsed;
313
+ }
314
+ /**
315
+ * Serialize a checksum manifest to JSON string (pretty-printed for storage)
316
+ *
317
+ * @param manifest - The manifest to serialize
318
+ * @returns Pretty-printed JSON string
319
+ */
320
+ export function serializeChecksumManifest(manifest) {
321
+ return JSON.stringify(manifest, null, 2);
322
+ }
323
+ /**
324
+ * Verify a manifest-based attestation
325
+ *
326
+ * This verifies that:
327
+ * 1. The Sigstore bundle is valid
328
+ * 2. The bundle was signed over the manifest hash
329
+ * 3. Optionally, the manifest matches the current files on disk
330
+ *
331
+ * @param manifest - The checksum manifest that was signed
332
+ * @param sigstoreBundle - The Sigstore bundle containing the signature
333
+ * @param options - Verification options
334
+ * @returns Verification result
335
+ */
336
+ export async function verifyManifestAttestation(manifest, sigstoreBundle, options = {}) {
337
+ // Dynamic import to avoid circular dependencies
338
+ const { verifyBundle, extractIdentityFromBundle } = await import("./sigstore");
339
+ try {
340
+ // Get the manifest hash that should have been signed
341
+ const expectedHash = manifest.manifestHash.digest;
342
+ // Convert hash to Buffer for verification
343
+ const hashBuffer = Buffer.from(expectedHash.match(/.{1,2}/g).map((byte) => Number.parseInt(byte, 16)));
344
+ // Cast the bundle to the expected type
345
+ const bundle = sigstoreBundle;
346
+ // Verify the Sigstore bundle
347
+ const bundleResult = await verifyBundle(bundle, hashBuffer);
348
+ if (!bundleResult.verified) {
349
+ return {
350
+ valid: false,
351
+ error: bundleResult.error ?? "Sigstore bundle verification failed",
352
+ details: {
353
+ bundleVerified: false,
354
+ manifestHashMatches: false,
355
+ },
356
+ };
357
+ }
358
+ // Extract identity from the bundle
359
+ const identity = extractIdentityFromBundle(bundle);
360
+ // If toolDir is provided, also verify manifest matches files
361
+ let manifestMatchesFiles;
362
+ if (options.toolDir) {
363
+ const ignoreOpts = options.ignorePatterns ? { ignorePatterns: options.ignorePatterns } : {};
364
+ const fileVerification = await verifyChecksumManifest(options.toolDir, manifest, ignoreOpts);
365
+ manifestMatchesFiles = fileVerification.valid;
366
+ if (!fileVerification.valid) {
367
+ return {
368
+ valid: false,
369
+ auditor: identity?.email ?? identity?.subject,
370
+ provider: identity?.issuer,
371
+ error: `Manifest does not match files: ${fileVerification.errors?.join(", ")}`,
372
+ details: {
373
+ bundleVerified: true,
374
+ manifestHashMatches: true,
375
+ manifestMatchesFiles: false,
376
+ },
377
+ };
378
+ }
379
+ }
380
+ return {
381
+ valid: true,
382
+ auditor: identity?.email ?? identity?.subject,
383
+ provider: identity?.issuer,
384
+ details: {
385
+ bundleVerified: true,
386
+ manifestHashMatches: true,
387
+ manifestMatchesFiles,
388
+ },
389
+ };
390
+ }
391
+ catch (error) {
392
+ return {
393
+ valid: false,
394
+ error: `Verification failed: ${error.message}`,
395
+ details: {
396
+ bundleVerified: false,
397
+ manifestHashMatches: false,
398
+ },
399
+ };
400
+ }
401
+ }
402
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enactprotocol/trust",
3
- "version": "2.1.15",
3
+ "version": "2.1.20",
4
4
  "description": "Sigstore integration, attestations, and verification for Enact",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/index.ts CHANGED
@@ -10,6 +10,24 @@ export const version = "0.1.0";
10
10
  // Hash utilities
11
11
  export { hashContent, hashBuffer, hashFile } from "./hash";
12
12
 
13
+ // Checksum manifest (for deterministic signing)
14
+ export {
15
+ createChecksumManifest,
16
+ computeManifestHash,
17
+ verifyChecksumManifest,
18
+ verifyManifestAttestation,
19
+ parseChecksumManifest,
20
+ serializeChecksumManifest,
21
+ MANIFEST_VERSION,
22
+ } from "./manifest";
23
+ export type {
24
+ ChecksumManifest,
25
+ FileChecksum,
26
+ CreateManifestOptions,
27
+ ManifestVerificationResult,
28
+ ManifestAttestationVerificationResult,
29
+ } from "./manifest";
30
+
13
31
  // Key management
14
32
  export { generateKeyPair, isValidPEMKey, getKeyTypeFromPEM } from "./keys";
15
33