@clawbureau/clawverify-core 0.1.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/dist/crypto.d.ts +27 -0
  4. package/dist/crypto.d.ts.map +1 -0
  5. package/dist/crypto.js +124 -0
  6. package/dist/crypto.js.map +1 -0
  7. package/dist/index.d.ts +27 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +24 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/jcs.d.ts +13 -0
  12. package/dist/jcs.d.ts.map +1 -0
  13. package/dist/jcs.js +43 -0
  14. package/dist/jcs.js.map +1 -0
  15. package/dist/model-identity.d.ts +46 -0
  16. package/dist/model-identity.d.ts.map +1 -0
  17. package/dist/model-identity.js +233 -0
  18. package/dist/model-identity.js.map +1 -0
  19. package/dist/schema-registry.d.ts +99 -0
  20. package/dist/schema-registry.d.ts.map +1 -0
  21. package/dist/schema-registry.js +259 -0
  22. package/dist/schema-registry.js.map +1 -0
  23. package/dist/schema-validation.d.ts +35 -0
  24. package/dist/schema-validation.d.ts.map +1 -0
  25. package/dist/schema-validation.js +156 -0
  26. package/dist/schema-validation.js.map +1 -0
  27. package/dist/schema-validators.generated.d.ts +158 -0
  28. package/dist/schema-validators.generated.d.ts.map +1 -0
  29. package/dist/schema-validators.generated.js +19186 -0
  30. package/dist/schema-validators.generated.js.map +1 -0
  31. package/dist/types.d.ts +910 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +33 -0
  34. package/dist/types.js.map +1 -0
  35. package/dist/verify-audit-result-attestation.d.ts +32 -0
  36. package/dist/verify-audit-result-attestation.d.ts.map +1 -0
  37. package/dist/verify-audit-result-attestation.js +396 -0
  38. package/dist/verify-audit-result-attestation.js.map +1 -0
  39. package/dist/verify-derivation-attestation.d.ts +30 -0
  40. package/dist/verify-derivation-attestation.d.ts.map +1 -0
  41. package/dist/verify-derivation-attestation.js +371 -0
  42. package/dist/verify-derivation-attestation.js.map +1 -0
  43. package/dist/verify-execution-attestation.d.ts +32 -0
  44. package/dist/verify-execution-attestation.d.ts.map +1 -0
  45. package/dist/verify-execution-attestation.js +578 -0
  46. package/dist/verify-execution-attestation.js.map +1 -0
  47. package/dist/verify-export-bundle.d.ts +14 -0
  48. package/dist/verify-export-bundle.d.ts.map +1 -0
  49. package/dist/verify-export-bundle.js +307 -0
  50. package/dist/verify-export-bundle.js.map +1 -0
  51. package/dist/verify-log-inclusion-proof.d.ts +16 -0
  52. package/dist/verify-log-inclusion-proof.d.ts.map +1 -0
  53. package/dist/verify-log-inclusion-proof.js +216 -0
  54. package/dist/verify-log-inclusion-proof.js.map +1 -0
  55. package/dist/verify-proof-bundle.d.ts +48 -0
  56. package/dist/verify-proof-bundle.d.ts.map +1 -0
  57. package/dist/verify-proof-bundle.js +1708 -0
  58. package/dist/verify-proof-bundle.js.map +1 -0
  59. package/dist/verify-receipt.d.ts +30 -0
  60. package/dist/verify-receipt.d.ts.map +1 -0
  61. package/dist/verify-receipt.js +408 -0
  62. package/dist/verify-receipt.js.map +1 -0
  63. package/dist/verify-web-receipt.d.ts +21 -0
  64. package/dist/verify-web-receipt.d.ts.map +1 -0
  65. package/dist/verify-web-receipt.js +341 -0
  66. package/dist/verify-web-receipt.js.map +1 -0
  67. package/package.json +54 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Clawbureau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @clawbureau/clawverify-core
2
+
3
+ Pure, offline-capable verification primitives for the **Clawsig Protocol**. Zero network dependencies — just cryptographic verification.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @clawbureau/clawverify-core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { verifyProofBundle } from '@clawbureau/clawverify-core';
15
+
16
+ const bundle = JSON.parse(fs.readFileSync('run_xxx-bundle.json', 'utf-8'));
17
+ const result = verifyProofBundle(bundle);
18
+
19
+ console.log(result.status); // 'PASS' or 'FAIL'
20
+ console.log(result.reason_code); // 'OK', 'SIGNATURE_INVALID', etc.
21
+ ```
22
+
23
+ ## What it verifies
24
+
25
+ - JSON schema validation (fail-closed on unknown versions)
26
+ - Ed25519 signature verification (did:key extraction)
27
+ - Event chain hash integrity (SHA-256)
28
+ - Tool receipt validation (version, algorithm, agent DID, required fields)
29
+ - Side-effect receipt validation (effect class, version, required fields)
30
+ - Human approval receipt validation (approval type, agent DID, required fields)
31
+ - Signer DID allowlist enforcement (optional, via config)
32
+ - Export bundle and log inclusion proof verification
33
+
34
+ ## Fail-closed by design
35
+
36
+ Unknown schema versions, hash algorithms, or envelope formats produce `FAIL` — never silently pass.
37
+
38
+ ## License
39
+
40
+ MIT
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Cryptographic utilities for signature verification
3
+ */
4
+ import type { HashAlgorithm, Algorithm } from './types.js';
5
+ /**
6
+ * Decode base64url to Uint8Array
7
+ */
8
+ export declare function base64UrlDecode(str: string): Uint8Array;
9
+ /**
10
+ * Encode Uint8Array to base64url
11
+ */
12
+ export declare function base64UrlEncode(bytes: Uint8Array): string;
13
+ /**
14
+ * Compute hash of payload using specified algorithm
15
+ */
16
+ export declare function computeHash(payload: unknown, algorithm: HashAlgorithm): Promise<string>;
17
+ /**
18
+ * Extract public key bytes from did:key
19
+ * Format: did:key:z<multibase-encoded-public-key>
20
+ */
21
+ export declare function extractPublicKeyFromDidKey(did: string): Uint8Array | null;
22
+ export declare function base58Decode(str: string): Uint8Array;
23
+ /**
24
+ * Verify Ed25519 signature using Web Crypto API
25
+ */
26
+ export declare function verifySignature(algorithm: Algorithm, publicKeyBytes: Uint8Array, signature: Uint8Array, message: Uint8Array): Promise<boolean>;
27
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE3D;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAWvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIzD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAmBzE;AAQD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAkCpD;AAeD;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,UAAU,EAC1B,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,OAAO,CAAC,CAyBlB"}
package/dist/crypto.js ADDED
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Cryptographic utilities for signature verification
3
+ */
4
+ /**
5
+ * Decode base64url to Uint8Array
6
+ */
7
+ export function base64UrlDecode(str) {
8
+ // Replace base64url chars with base64
9
+ const base64 = str.replace(/-/g, '+').replace(/_/g, '/');
10
+ // Pad with = if needed
11
+ const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);
12
+ const binary = atob(padded);
13
+ const bytes = new Uint8Array(binary.length);
14
+ for (let i = 0; i < binary.length; i++) {
15
+ bytes[i] = binary.charCodeAt(i);
16
+ }
17
+ return bytes;
18
+ }
19
+ /**
20
+ * Encode Uint8Array to base64url
21
+ */
22
+ export function base64UrlEncode(bytes) {
23
+ const binary = String.fromCharCode(...bytes);
24
+ const base64 = btoa(binary);
25
+ return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
26
+ }
27
+ /**
28
+ * Compute hash of payload using specified algorithm
29
+ */
30
+ export async function computeHash(payload, algorithm) {
31
+ const encoder = new TextEncoder();
32
+ const data = encoder.encode(JSON.stringify(payload));
33
+ if (algorithm === 'SHA-256') {
34
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
35
+ return base64UrlEncode(new Uint8Array(hashBuffer));
36
+ }
37
+ // BLAKE3 would require a library - for now SHA-256 is primary
38
+ throw new Error(`Hash algorithm not implemented: ${algorithm}`);
39
+ }
40
+ /**
41
+ * Extract public key bytes from did:key
42
+ * Format: did:key:z<multibase-encoded-public-key>
43
+ */
44
+ export function extractPublicKeyFromDidKey(did) {
45
+ if (!did.startsWith('did:key:z')) {
46
+ return null;
47
+ }
48
+ try {
49
+ // Remove did:key:z prefix and decode multibase (z = base58btc)
50
+ const multibase = did.slice(9);
51
+ const decoded = base58Decode(multibase);
52
+ // Ed25519 multicodec prefix is 0xed01
53
+ if (decoded[0] === 0xed && decoded[1] === 0x01) {
54
+ return decoded.slice(2);
55
+ }
56
+ return null;
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ /**
63
+ * Base58 Bitcoin alphabet decoder
64
+ */
65
+ const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
66
+ export function base58Decode(str) {
67
+ const bytes = [0];
68
+ for (const char of str) {
69
+ const value = BASE58_ALPHABET.indexOf(char);
70
+ if (value === -1) {
71
+ throw new Error(`Invalid base58 character: ${char}`);
72
+ }
73
+ for (let i = 0; i < bytes.length; i++) {
74
+ bytes[i] *= 58;
75
+ }
76
+ bytes[0] += value;
77
+ let carry = 0;
78
+ for (let i = 0; i < bytes.length; i++) {
79
+ bytes[i] += carry;
80
+ carry = bytes[i] >> 8;
81
+ bytes[i] &= 0xff;
82
+ }
83
+ while (carry) {
84
+ bytes.push(carry & 0xff);
85
+ carry >>= 8;
86
+ }
87
+ }
88
+ // Handle leading zeros
89
+ for (const char of str) {
90
+ if (char !== '1')
91
+ break;
92
+ bytes.push(0);
93
+ }
94
+ return new Uint8Array(bytes.reverse());
95
+ }
96
+ function toArrayBuffer(bytes) {
97
+ // DOM SubtleCrypto typings reject SharedArrayBuffer-backed views.
98
+ // Our inputs are expected to be regular ArrayBuffers, but we normalize anyway.
99
+ const buf = bytes.buffer;
100
+ if (buf instanceof ArrayBuffer) {
101
+ return buf.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
102
+ }
103
+ const copy = new Uint8Array(bytes.byteLength);
104
+ copy.set(bytes);
105
+ return copy.buffer;
106
+ }
107
+ /**
108
+ * Verify Ed25519 signature using Web Crypto API
109
+ */
110
+ export async function verifySignature(algorithm, publicKeyBytes, signature, message) {
111
+ if (algorithm !== 'Ed25519') {
112
+ throw new Error(`Algorithm not supported: ${algorithm}`);
113
+ }
114
+ try {
115
+ // Import the public key
116
+ const publicKey = await crypto.subtle.importKey('raw', toArrayBuffer(publicKeyBytes), { name: 'Ed25519' }, false, ['verify']);
117
+ // Verify the signature
118
+ return await crypto.subtle.verify('Ed25519', publicKey, toArrayBuffer(signature), toArrayBuffer(message));
119
+ }
120
+ catch {
121
+ return false;
122
+ }
123
+ }
124
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @clawbureau/clawverify-core
3
+ *
4
+ * Pure, offline-capable verification primitives shared by:
5
+ * - packages/clawverify-cli (offline verifier)
6
+ * - (optional) hosted verifiers / services
7
+ *
8
+ * Hard constraints:
9
+ * - fail-closed for unknown schema/version/algorithm
10
+ * - deterministic error codes
11
+ * - no network fetches
12
+ */
13
+ export * from './types.js';
14
+ export { verifyProofBundle } from './verify-proof-bundle.js';
15
+ export type { ProofBundleVerifierOptions } from './verify-proof-bundle.js';
16
+ export { verifyExportBundle } from './verify-export-bundle.js';
17
+ export type { VerifyExportBundleOptions } from './verify-export-bundle.js';
18
+ export { verifyReceipt } from './verify-receipt.js';
19
+ export type { ReceiptVerifierOptions } from './verify-receipt.js';
20
+ export { verifyWebReceipt } from './verify-web-receipt.js';
21
+ export { verifyExecutionAttestation } from './verify-execution-attestation.js';
22
+ export { verifyDerivationAttestation } from './verify-derivation-attestation.js';
23
+ export { verifyAuditResultAttestation } from './verify-audit-result-attestation.js';
24
+ export { verifyLogInclusionProof } from './verify-log-inclusion-proof.js';
25
+ export { base64UrlDecode, base64UrlEncode, computeHash, extractPublicKeyFromDidKey, verifySignature, } from './crypto.js';
26
+ export { jcsCanonicalize } from './jcs.js';
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAE3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,0BAA0B,EAC1B,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @clawbureau/clawverify-core
3
+ *
4
+ * Pure, offline-capable verification primitives shared by:
5
+ * - packages/clawverify-cli (offline verifier)
6
+ * - (optional) hosted verifiers / services
7
+ *
8
+ * Hard constraints:
9
+ * - fail-closed for unknown schema/version/algorithm
10
+ * - deterministic error codes
11
+ * - no network fetches
12
+ */
13
+ export * from './types.js';
14
+ export { verifyProofBundle } from './verify-proof-bundle.js';
15
+ export { verifyExportBundle } from './verify-export-bundle.js';
16
+ export { verifyReceipt } from './verify-receipt.js';
17
+ export { verifyWebReceipt } from './verify-web-receipt.js';
18
+ export { verifyExecutionAttestation } from './verify-execution-attestation.js';
19
+ export { verifyDerivationAttestation } from './verify-derivation-attestation.js';
20
+ export { verifyAuditResultAttestation } from './verify-audit-result-attestation.js';
21
+ export { verifyLogInclusionProof } from './verify-log-inclusion-proof.js';
22
+ export { base64UrlDecode, base64UrlEncode, computeHash, extractPublicKeyFromDidKey, verifySignature, } from './crypto.js';
23
+ export { jcsCanonicalize } from './jcs.js';
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,0BAA0B,EAC1B,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
package/dist/jcs.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * RFC 8785 — JSON Canonicalization Scheme (JCS)
3
+ *
4
+ * Produces a deterministic JSON string suitable for signing/verifying.
5
+ *
6
+ * Notes:
7
+ * - Only valid JSON data is supported (no undefined/functions/symbols).
8
+ * - Object keys are sorted lexicographically.
9
+ * - Numbers must be finite.
10
+ * - Output contains no whitespace.
11
+ */
12
+ export declare function jcsCanonicalize(value: unknown): string;
13
+ //# sourceMappingURL=jcs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jcs.d.ts","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAqCtD"}
package/dist/jcs.js ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * RFC 8785 — JSON Canonicalization Scheme (JCS)
3
+ *
4
+ * Produces a deterministic JSON string suitable for signing/verifying.
5
+ *
6
+ * Notes:
7
+ * - Only valid JSON data is supported (no undefined/functions/symbols).
8
+ * - Object keys are sorted lexicographically.
9
+ * - Numbers must be finite.
10
+ * - Output contains no whitespace.
11
+ */
12
+ export function jcsCanonicalize(value) {
13
+ if (value === null)
14
+ return 'null';
15
+ switch (typeof value) {
16
+ case 'boolean':
17
+ return value ? 'true' : 'false';
18
+ case 'number':
19
+ if (!Number.isFinite(value)) {
20
+ throw new Error('Non-finite number not allowed in JCS');
21
+ }
22
+ // JSON.stringify() uses the ECMAScript number to string algorithm.
23
+ return JSON.stringify(value);
24
+ case 'string':
25
+ return JSON.stringify(value);
26
+ case 'object': {
27
+ if (Array.isArray(value)) {
28
+ return `[${value.map(jcsCanonicalize).join(',')}]`;
29
+ }
30
+ const obj = value;
31
+ const keys = Object.keys(obj).sort();
32
+ const parts = [];
33
+ for (const k of keys) {
34
+ parts.push(`${JSON.stringify(k)}:${jcsCanonicalize(obj[k])}`);
35
+ }
36
+ return `{${parts.join(',')}}`;
37
+ }
38
+ default:
39
+ // undefined | function | symbol | bigint
40
+ throw new Error(`Unsupported value type for JCS: ${typeof value}`);
41
+ }
42
+ }
43
+ //# sourceMappingURL=jcs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jcs.js","sourceRoot":"","sources":["../src/jcs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAElC,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAElC,KAAK,QAAQ;YACX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAC1D,CAAC;YACD,mEAAmE;YACnE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE/B,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE/B,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YACrD,CAAC;YAED,MAAM,GAAG,GAAG,KAAgC,CAAC;YAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACrC,MAAM,KAAK,GAAa,EAAE,CAAC;YAE3B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAChE,CAAC;YAED,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QAChC,CAAC;QAED;YACE,yCAAyC;YACzC,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * CVF-US-016 — Model identity extraction + verification.
3
+ *
4
+ * Model identity is an orthogonal axis to PoH tiers:
5
+ * - PoH (`proof_tier` / `poh_tier`) describes execution provenance.
6
+ * - `model_identity_tier` describes what we can honestly claim about the model identity.
7
+ *
8
+ * This module intentionally fail-closes *only* the model identity axis.
9
+ * Receipt signature/binding validity is handled elsewhere.
10
+ */
11
+ import type { GatewayReceiptPayload, ModelIdentityTier, SignedEnvelope } from './types.js';
12
+ export declare function computeModelIdentityHashB64u(identity: unknown): Promise<string>;
13
+ export interface ModelIdentityVerificationResult {
14
+ /** Whether the model identity claim itself verified (schema + hash + consistency). */
15
+ valid: boolean;
16
+ tier: ModelIdentityTier;
17
+ /** Deterministic risk flags (non-normative). */
18
+ risk_flags: string[];
19
+ computed_hash_b64u?: string;
20
+ }
21
+ /**
22
+ * Verify model identity for a single receipt payload.
23
+ *
24
+ * Returns:
25
+ * - `valid=false` only means model identity cannot be trusted. Receipt may still be cryptographically valid.
26
+ */
27
+ export declare function verifyModelIdentityFromReceiptPayload(payload: GatewayReceiptPayload): Promise<ModelIdentityVerificationResult>;
28
+ export interface ReceiptVerificationForModelIdentity {
29
+ signature_valid?: boolean;
30
+ binding_valid?: boolean;
31
+ valid?: boolean;
32
+ }
33
+ /**
34
+ * Compute a single model_identity_tier for a set of receipts.
35
+ *
36
+ * Policy/gating-friendly semantics: the overall tier is the *minimum* tier
37
+ * across all receipts that have signature-valid envelopes.
38
+ */
39
+ export declare function computeModelIdentityTierFromReceipts(input: {
40
+ receipts: SignedEnvelope<GatewayReceiptPayload>[];
41
+ receiptResults?: ReceiptVerificationForModelIdentity[] | null;
42
+ }): Promise<{
43
+ model_identity_tier: ModelIdentityTier;
44
+ risk_flags: string[];
45
+ }>;
46
+ //# sourceMappingURL=model-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-identity.d.ts","sourceRoot":"","sources":["../src/model-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAgB3F,wBAAsB,4BAA4B,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAErF;AA0DD,MAAM,WAAW,+BAA+B;IAC9C,sFAAsF;IACtF,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,iBAAiB,CAAC;IACxB,gDAAgD;IAChD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAsB,qCAAqC,CACzD,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,+BAA+B,CAAC,CAkH1C;AAED,MAAM,WAAW,mCAAmC;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,oCAAoC,CAAC,KAAK,EAAE;IAChE,QAAQ,EAAE,cAAc,CAAC,qBAAqB,CAAC,EAAE,CAAC;IAClD,cAAc,CAAC,EAAE,mCAAmC,EAAE,GAAG,IAAI,CAAC;CAC/D,GAAG,OAAO,CAAC;IAAE,mBAAmB,EAAE,iBAAiB,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAoC5E"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * CVF-US-016 — Model identity extraction + verification.
3
+ *
4
+ * Model identity is an orthogonal axis to PoH tiers:
5
+ * - PoH (`proof_tier` / `poh_tier`) describes execution provenance.
6
+ * - `model_identity_tier` describes what we can honestly claim about the model identity.
7
+ *
8
+ * This module intentionally fail-closes *only* the model identity axis.
9
+ * Receipt signature/binding validity is handled elsewhere.
10
+ */
11
+ import { base64UrlEncode } from './crypto.js';
12
+ import { jcsCanonicalize } from './jcs.js';
13
+ import { isValidBase64Url } from './schema-registry.js';
14
+ import { validateModelIdentityV1 } from './schema-validation.js';
15
+ function isRecord(x) {
16
+ return typeof x === 'object' && x !== null && !Array.isArray(x);
17
+ }
18
+ async function sha256B64uUtf8(s) {
19
+ const bytes = new TextEncoder().encode(s);
20
+ const digest = await crypto.subtle.digest('SHA-256', bytes);
21
+ return base64UrlEncode(new Uint8Array(digest));
22
+ }
23
+ export async function computeModelIdentityHashB64u(identity) {
24
+ return sha256B64uUtf8(jcsCanonicalize(identity));
25
+ }
26
+ const TIER_STRENGTH = {
27
+ unknown: 0,
28
+ closed_opaque: 1,
29
+ closed_provider_manifest: 2,
30
+ openweights_hashable: 3,
31
+ tee_measured: 4,
32
+ };
33
+ function normalizeTier(tier) {
34
+ if (tier === 'closed_opaque')
35
+ return 'closed_opaque';
36
+ if (tier === 'closed_provider_manifest')
37
+ return 'closed_provider_manifest';
38
+ if (tier === 'openweights_hashable')
39
+ return 'openweights_hashable';
40
+ if (tier === 'tee_measured')
41
+ return 'tee_measured';
42
+ return 'unknown';
43
+ }
44
+ function requireString(obj, key) {
45
+ const v = obj[key];
46
+ return typeof v === 'string' && v.trim().length > 0 ? v : null;
47
+ }
48
+ function hasProviderManifestEvidence(identity) {
49
+ const artifacts = identity.artifacts;
50
+ if (!isRecord(artifacts))
51
+ return false;
52
+ const pm = artifacts.provider_manifest;
53
+ if (!isRecord(pm))
54
+ return false;
55
+ const h = pm.hash_b64u;
56
+ return typeof h === 'string' && isValidBase64Url(h) && h.length >= 8;
57
+ }
58
+ function hasOpenweightsEvidence(identity) {
59
+ const artifacts = identity.artifacts;
60
+ if (!isRecord(artifacts))
61
+ return false;
62
+ const ow = artifacts.openweights;
63
+ if (!isRecord(ow))
64
+ return false;
65
+ const weights = ow.weights;
66
+ if (!Array.isArray(weights) || weights.length === 0)
67
+ return false;
68
+ for (const w of weights) {
69
+ if (!isRecord(w))
70
+ return false;
71
+ const h = w.hash_b64u;
72
+ if (typeof h !== 'string' || !isValidBase64Url(h) || h.length < 8)
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+ function hasTeeEvidence(identity) {
78
+ const artifacts = identity.artifacts;
79
+ if (!isRecord(artifacts))
80
+ return false;
81
+ const tm = artifacts.tee_measurement;
82
+ if (!isRecord(tm))
83
+ return false;
84
+ const ref = tm.attestation_report_ref;
85
+ if (!isRecord(ref))
86
+ return false;
87
+ const h = ref.resource_hash_b64u;
88
+ return typeof h === 'string' && isValidBase64Url(h) && h.length >= 8;
89
+ }
90
+ /**
91
+ * Verify model identity for a single receipt payload.
92
+ *
93
+ * Returns:
94
+ * - `valid=false` only means model identity cannot be trusted. Receipt may still be cryptographically valid.
95
+ */
96
+ export async function verifyModelIdentityFromReceiptPayload(payload) {
97
+ const risk = new Set();
98
+ const metadata = isRecord(payload.metadata) ? payload.metadata : null;
99
+ const providedIdentity = metadata?.model_identity;
100
+ const providedHash = typeof metadata?.model_identity_hash_b64u === 'string' ? metadata.model_identity_hash_b64u : null;
101
+ let identity;
102
+ if (providedIdentity === undefined) {
103
+ // Back-compat: older receipts may not include model identity metadata.
104
+ // Default is still "closed_opaque" for closed providers.
105
+ risk.add('MODEL_IDENTITY_MISSING_DEFAULTED');
106
+ identity = {
107
+ model_identity_version: '1',
108
+ tier: 'closed_opaque',
109
+ model: {
110
+ provider: payload.provider,
111
+ name: payload.model,
112
+ },
113
+ };
114
+ }
115
+ else {
116
+ // Strict schema validate when present.
117
+ const v = validateModelIdentityV1(providedIdentity);
118
+ if (!v.valid) {
119
+ risk.add('MODEL_IDENTITY_SCHEMA_INVALID');
120
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort() };
121
+ }
122
+ identity = providedIdentity;
123
+ }
124
+ // Ensure the identity model label matches the receipt payload model label.
125
+ if (!isRecord(identity)) {
126
+ risk.add('MODEL_IDENTITY_SCHEMA_INVALID');
127
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort() };
128
+ }
129
+ const model = identity.model;
130
+ if (!isRecord(model)) {
131
+ risk.add('MODEL_IDENTITY_SCHEMA_INVALID');
132
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort() };
133
+ }
134
+ const identityProvider = requireString(model, 'provider');
135
+ const identityName = requireString(model, 'name');
136
+ if (!identityProvider || !identityName) {
137
+ risk.add('MODEL_IDENTITY_SCHEMA_INVALID');
138
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort() };
139
+ }
140
+ if (identityProvider !== payload.provider || identityName !== payload.model) {
141
+ risk.add('MODEL_IDENTITY_MODEL_MISMATCH');
142
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort() };
143
+ }
144
+ // Validate hash (if present) against sha256_b64u(JCS(model_identity)).
145
+ let computedHash;
146
+ try {
147
+ computedHash = await computeModelIdentityHashB64u(identity);
148
+ }
149
+ catch {
150
+ risk.add('MODEL_IDENTITY_HASH_COMPUTE_FAILED');
151
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort() };
152
+ }
153
+ if (providedHash) {
154
+ if (!isValidBase64Url(providedHash)) {
155
+ risk.add('MODEL_IDENTITY_HASH_INVALID');
156
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort(), computed_hash_b64u: computedHash };
157
+ }
158
+ if (providedHash !== computedHash) {
159
+ risk.add('MODEL_IDENTITY_HASH_MISMATCH');
160
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort(), computed_hash_b64u: computedHash };
161
+ }
162
+ }
163
+ else {
164
+ risk.add('MODEL_IDENTITY_HASH_MISSING');
165
+ }
166
+ // Validate tier semantics (fail-closed on stronger tiers without evidence).
167
+ const tier = normalizeTier(identity.tier);
168
+ if (tier === 'unknown') {
169
+ risk.add('MODEL_IDENTITY_TIER_INVALID');
170
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort(), computed_hash_b64u: computedHash };
171
+ }
172
+ if (tier === 'closed_provider_manifest' && !hasProviderManifestEvidence(identity)) {
173
+ risk.add('MODEL_IDENTITY_EVIDENCE_MISSING');
174
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort(), computed_hash_b64u: computedHash };
175
+ }
176
+ if (tier === 'openweights_hashable' && !hasOpenweightsEvidence(identity)) {
177
+ risk.add('MODEL_IDENTITY_EVIDENCE_MISSING');
178
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort(), computed_hash_b64u: computedHash };
179
+ }
180
+ if (tier === 'tee_measured' && !hasTeeEvidence(identity)) {
181
+ risk.add('MODEL_IDENTITY_EVIDENCE_MISSING');
182
+ return { valid: false, tier: 'unknown', risk_flags: [...risk].sort(), computed_hash_b64u: computedHash };
183
+ }
184
+ if (tier === 'closed_opaque') {
185
+ // Not an error: this is the expected posture for closed providers.
186
+ risk.add('MODEL_IDENTITY_OPAQUE');
187
+ }
188
+ return {
189
+ valid: true,
190
+ tier,
191
+ risk_flags: [...risk].sort(),
192
+ computed_hash_b64u: computedHash,
193
+ };
194
+ }
195
+ /**
196
+ * Compute a single model_identity_tier for a set of receipts.
197
+ *
198
+ * Policy/gating-friendly semantics: the overall tier is the *minimum* tier
199
+ * across all receipts that have signature-valid envelopes.
200
+ */
201
+ export async function computeModelIdentityTierFromReceipts(input) {
202
+ const risk = new Set();
203
+ const tiers = [];
204
+ for (let i = 0; i < input.receipts.length; i++) {
205
+ const r = input.receipts[i];
206
+ const vr = input.receiptResults?.[i];
207
+ // Only consider receipts whose envelope signature+payload hash were verified.
208
+ // If we have no per-receipt verification results, assume caller already filtered.
209
+ if (vr && vr.signature_valid === false)
210
+ continue;
211
+ const out = await verifyModelIdentityFromReceiptPayload(r.payload);
212
+ for (const f of out.risk_flags)
213
+ risk.add(f);
214
+ tiers.push(out.tier);
215
+ }
216
+ if (tiers.length === 0) {
217
+ risk.add('MODEL_IDENTITY_NO_SIGNATURE_VERIFIED_RECEIPTS');
218
+ return { model_identity_tier: 'unknown', risk_flags: [...risk].sort() };
219
+ }
220
+ let minTier = tiers[0];
221
+ for (const t of tiers) {
222
+ if (TIER_STRENGTH[t] < TIER_STRENGTH[minTier])
223
+ minTier = t;
224
+ }
225
+ const distinct = new Set(tiers);
226
+ if (distinct.size > 1)
227
+ risk.add('MODEL_IDENTITY_HETEROGENEOUS');
228
+ return {
229
+ model_identity_tier: minTier,
230
+ risk_flags: [...risk].sort(),
231
+ };
232
+ }
233
+ //# sourceMappingURL=model-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-identity.js","sourceRoot":"","sources":["../src/model-identity.ts"],"names":[],"mappings":"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"}