@peac/protocol 0.10.8 → 0.10.10

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 (51) hide show
  1. package/LICENSE +1 -1
  2. package/dist/discovery.d.ts.map +1 -1
  3. package/dist/index.cjs +2694 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.mjs +2612 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/dist/issue.d.ts +3 -0
  8. package/dist/issue.d.ts.map +1 -1
  9. package/dist/telemetry.d.ts +43 -0
  10. package/dist/telemetry.d.ts.map +1 -1
  11. package/dist/transport-profiles.d.ts.map +1 -1
  12. package/dist/verification-report.d.ts.map +1 -1
  13. package/dist/verifier-types.d.ts +42 -2
  14. package/dist/verifier-types.d.ts.map +1 -1
  15. package/dist/verify-local.cjs +164 -0
  16. package/dist/verify-local.cjs.map +1 -0
  17. package/dist/verify-local.d.ts +61 -4
  18. package/dist/verify-local.d.ts.map +1 -1
  19. package/dist/verify-local.mjs +160 -0
  20. package/dist/verify-local.mjs.map +1 -0
  21. package/dist/verify.d.ts +3 -0
  22. package/dist/verify.d.ts.map +1 -1
  23. package/package.json +20 -14
  24. package/dist/crypto-utils.js +0 -21
  25. package/dist/crypto-utils.js.map +0 -1
  26. package/dist/discovery.js +0 -405
  27. package/dist/discovery.js.map +0 -1
  28. package/dist/headers.js +0 -110
  29. package/dist/headers.js.map +0 -1
  30. package/dist/index.js +0 -44
  31. package/dist/index.js.map +0 -1
  32. package/dist/issue.js +0 -208
  33. package/dist/issue.js.map +0 -1
  34. package/dist/pointer-fetch.js +0 -305
  35. package/dist/pointer-fetch.js.map +0 -1
  36. package/dist/ssrf-safe-fetch.js +0 -671
  37. package/dist/ssrf-safe-fetch.js.map +0 -1
  38. package/dist/telemetry.js +0 -18
  39. package/dist/telemetry.js.map +0 -1
  40. package/dist/transport-profiles.js +0 -424
  41. package/dist/transport-profiles.js.map +0 -1
  42. package/dist/verification-report.js +0 -322
  43. package/dist/verification-report.js.map +0 -1
  44. package/dist/verifier-core.js +0 -578
  45. package/dist/verifier-core.js.map +0 -1
  46. package/dist/verifier-types.js +0 -161
  47. package/dist/verifier-types.js.map +0 -1
  48. package/dist/verify-local.js +0 -189
  49. package/dist/verify-local.js.map +0 -1
  50. package/dist/verify.js +0 -202
  51. package/dist/verify.js.map +0 -1
@@ -1,161 +0,0 @@
1
- "use strict";
2
- /**
3
- * PEAC Verifier Types
4
- *
5
- * Types for verification policy, trust pinning, and verification reports
6
- * per VERIFIER-SECURITY-MODEL.md, TRUST-PINNING-POLICY.md, and
7
- * VERIFICATION-REPORT-FORMAT.md
8
- *
9
- * @packageDocumentation
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.NON_DETERMINISTIC_ARTIFACT_KEYS = exports.CHECK_IDS = exports.DEFAULT_NETWORK_SECURITY = exports.DEFAULT_VERIFIER_LIMITS = void 0;
13
- exports.createDefaultPolicy = createDefaultPolicy;
14
- exports.createDigest = createDigest;
15
- exports.createEmptyReport = createEmptyReport;
16
- exports.ssrfErrorToReasonCode = ssrfErrorToReasonCode;
17
- exports.reasonCodeToSeverity = reasonCodeToSeverity;
18
- exports.reasonCodeToErrorCode = reasonCodeToErrorCode;
19
- const kernel_1 = require("@peac/kernel");
20
- /**
21
- * Default verifier limits from VERIFIER-SECURITY-MODEL.md
22
- */
23
- exports.DEFAULT_VERIFIER_LIMITS = {
24
- max_receipt_bytes: kernel_1.VERIFIER_LIMITS.maxReceiptBytes,
25
- max_jwks_bytes: kernel_1.VERIFIER_LIMITS.maxJwksBytes,
26
- max_jwks_keys: kernel_1.VERIFIER_LIMITS.maxJwksKeys,
27
- max_redirects: kernel_1.VERIFIER_LIMITS.maxRedirects,
28
- fetch_timeout_ms: kernel_1.VERIFIER_LIMITS.fetchTimeoutMs,
29
- max_extension_bytes: kernel_1.VERIFIER_LIMITS.maxExtensionBytes,
30
- };
31
- /**
32
- * Default network security settings from VERIFIER-SECURITY-MODEL.md
33
- */
34
- exports.DEFAULT_NETWORK_SECURITY = {
35
- https_only: kernel_1.VERIFIER_NETWORK.httpsOnly,
36
- block_private_ips: kernel_1.VERIFIER_NETWORK.blockPrivateIps,
37
- allow_redirects: kernel_1.VERIFIER_NETWORK.allowRedirects,
38
- allow_cross_origin_redirects: true, // Allow for CDN compatibility
39
- dns_failure_behavior: 'block', // Fail-closed by default
40
- };
41
- /**
42
- * Create a default verifier policy
43
- */
44
- function createDefaultPolicy(mode) {
45
- return {
46
- policy_version: kernel_1.VERIFIER_POLICY_VERSION,
47
- mode,
48
- limits: { ...exports.DEFAULT_VERIFIER_LIMITS },
49
- network: { ...exports.DEFAULT_NETWORK_SECURITY },
50
- };
51
- }
52
- /**
53
- * Standard check IDs per VERIFIER-SECURITY-MODEL.md (in order)
54
- */
55
- exports.CHECK_IDS = [
56
- 'jws.parse',
57
- 'limits.receipt_bytes',
58
- 'jws.protected_header',
59
- 'claims.schema_unverified',
60
- 'issuer.trust_policy',
61
- 'issuer.discovery',
62
- 'key.resolve',
63
- 'jws.signature',
64
- 'claims.time_window',
65
- 'extensions.limits',
66
- 'transport.profile_binding',
67
- ];
68
- /**
69
- * Keys of artifacts that are non-deterministic (depend on runtime state)
70
- */
71
- exports.NON_DETERMINISTIC_ARTIFACT_KEYS = [
72
- 'issuer_jwks_digest',
73
- ];
74
- // ---------------------------------------------------------------------------
75
- // Report Builder Utilities
76
- // ---------------------------------------------------------------------------
77
- /**
78
- * Create a digest object from a hex string
79
- */
80
- function createDigest(hexValue) {
81
- return {
82
- alg: 'sha-256',
83
- value: hexValue.toLowerCase(),
84
- };
85
- }
86
- /**
87
- * Create an empty verification report structure
88
- */
89
- function createEmptyReport(policy) {
90
- return {
91
- report_version: kernel_1.VERIFICATION_REPORT_VERSION,
92
- policy,
93
- };
94
- }
95
- /**
96
- * Map SSRF fetch error reason to verification reason code
97
- */
98
- function ssrfErrorToReasonCode(ssrfReason, fetchType) {
99
- const prefix = fetchType === 'key' ? 'key_fetch' : 'pointer_fetch';
100
- switch (ssrfReason) {
101
- case 'not_https':
102
- case 'private_ip':
103
- case 'loopback':
104
- case 'link_local':
105
- case 'cross_origin_redirect':
106
- case 'dns_failure':
107
- return `${prefix}_blocked`;
108
- case 'timeout':
109
- return `${prefix}_timeout`;
110
- case 'response_too_large':
111
- return fetchType === 'pointer' ? 'pointer_fetch_too_large' : 'jwks_too_large';
112
- case 'jwks_too_many_keys':
113
- return 'jwks_too_many_keys';
114
- case 'too_many_redirects':
115
- case 'scheme_downgrade':
116
- case 'network_error':
117
- case 'invalid_url':
118
- default:
119
- return `${prefix}_failed`;
120
- }
121
- }
122
- /**
123
- * Map reason code to severity
124
- */
125
- function reasonCodeToSeverity(reason) {
126
- if (reason === 'ok')
127
- return 'info';
128
- return 'error';
129
- }
130
- /**
131
- * Map reason code to error code
132
- */
133
- function reasonCodeToErrorCode(reason) {
134
- const mapping = {
135
- ok: '',
136
- receipt_too_large: 'E_VERIFY_RECEIPT_TOO_LARGE',
137
- malformed_receipt: 'E_VERIFY_MALFORMED_RECEIPT',
138
- signature_invalid: 'E_VERIFY_SIGNATURE_INVALID',
139
- issuer_not_allowed: 'E_VERIFY_ISSUER_NOT_ALLOWED',
140
- key_not_found: 'E_VERIFY_KEY_NOT_FOUND',
141
- key_fetch_blocked: 'E_VERIFY_KEY_FETCH_BLOCKED',
142
- key_fetch_failed: 'E_VERIFY_KEY_FETCH_FAILED',
143
- key_fetch_timeout: 'E_VERIFY_KEY_FETCH_TIMEOUT',
144
- pointer_fetch_blocked: 'E_VERIFY_POINTER_FETCH_BLOCKED',
145
- pointer_fetch_failed: 'E_VERIFY_POINTER_FETCH_FAILED',
146
- pointer_fetch_timeout: 'E_VERIFY_POINTER_FETCH_TIMEOUT',
147
- pointer_fetch_too_large: 'E_VERIFY_POINTER_FETCH_TOO_LARGE',
148
- pointer_digest_mismatch: 'E_VERIFY_POINTER_DIGEST_MISMATCH',
149
- jwks_too_large: 'E_VERIFY_JWKS_TOO_LARGE',
150
- jwks_too_many_keys: 'E_VERIFY_JWKS_TOO_MANY_KEYS',
151
- expired: 'E_VERIFY_EXPIRED',
152
- not_yet_valid: 'E_VERIFY_NOT_YET_VALID',
153
- audience_mismatch: 'E_VERIFY_AUDIENCE_MISMATCH',
154
- schema_invalid: 'E_VERIFY_SCHEMA_INVALID',
155
- policy_violation: 'E_VERIFY_POLICY_VIOLATION',
156
- extension_too_large: 'E_VERIFY_EXTENSION_TOO_LARGE',
157
- invalid_transport: 'E_VERIFY_INVALID_TRANSPORT',
158
- };
159
- return mapping[reason] || 'E_VERIFY_POLICY_VIOLATION';
160
- }
161
- //# sourceMappingURL=verifier-types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verifier-types.js","sourceRoot":"","sources":["../src/verifier-types.ts"],"names":[],"mappings":"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"}
@@ -1,189 +0,0 @@
1
- "use strict";
2
- /**
3
- * Local receipt verification with schema validation
4
- *
5
- * Use this for verifying receipts when you have the public key locally,
6
- * without JWKS discovery.
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.verifyLocal = verifyLocal;
10
- const crypto_1 = require("@peac/crypto");
11
- const schema_1 = require("@peac/schema");
12
- /**
13
- * Structural check for CryptoError
14
- * More robust than instanceof across module boundaries (ESM/CJS, duplicate packages)
15
- */
16
- function isCryptoError(err) {
17
- return (err !== null &&
18
- typeof err === 'object' &&
19
- 'name' in err &&
20
- err.name === 'CryptoError' &&
21
- 'code' in err &&
22
- typeof err.code === 'string' &&
23
- err.code.startsWith('CRYPTO_') &&
24
- 'message' in err &&
25
- typeof err.message === 'string');
26
- }
27
- /**
28
- * Crypto error codes that indicate format/validation issues
29
- * These are CRYPTO_* internal codes from @peac/crypto, mapped to canonical E_* codes
30
- */
31
- const FORMAT_ERROR_CODES = new Set([
32
- 'CRYPTO_INVALID_JWS_FORMAT',
33
- 'CRYPTO_INVALID_TYP',
34
- 'CRYPTO_INVALID_ALG',
35
- 'CRYPTO_INVALID_KEY_LENGTH',
36
- ]);
37
- /**
38
- * Verify a PEAC receipt locally with a known public key
39
- *
40
- * This function:
41
- * 1. Verifies the Ed25519 signature and header (typ, alg)
42
- * 2. Validates the receipt schema with Zod
43
- * 3. Checks issuer/audience/subject binding (if options provided)
44
- * 4. Checks time validity (exp/iat with clock skew tolerance)
45
- *
46
- * Use this when you have the issuer's public key and don't need JWKS discovery.
47
- * For JWKS-based verification, use `verifyReceipt()` instead.
48
- *
49
- * @param jws - JWS compact serialization
50
- * @param publicKey - Ed25519 public key (32 bytes)
51
- * @param options - Optional verification options (issuer, audience, subject, clock skew)
52
- * @returns Typed verification result
53
- *
54
- * @example
55
- * ```typescript
56
- * const result = await verifyLocal(jws, publicKey, {
57
- * issuer: 'https://api.example.com',
58
- * audience: 'https://client.example.com',
59
- * subjectUri: 'https://api.example.com/inference/v1',
60
- * });
61
- * if (result.valid) {
62
- * console.log('Issuer:', result.claims.iss);
63
- * console.log('Amount:', result.claims.amt, result.claims.cur);
64
- * console.log('Key ID:', result.kid);
65
- * } else {
66
- * console.error('Verification failed:', result.code, result.message);
67
- * }
68
- * ```
69
- */
70
- async function verifyLocal(jws, publicKey, options = {}) {
71
- const { issuer, audience, subjectUri, rid, requireExp = false, maxClockSkew = 300 } = options;
72
- const now = options.now ?? Math.floor(Date.now() / 1000);
73
- try {
74
- // 1. Verify signature and header (typ, alg validated by @peac/crypto)
75
- const result = await (0, crypto_1.verify)(jws, publicKey);
76
- if (!result.valid) {
77
- return {
78
- valid: false,
79
- code: 'E_INVALID_SIGNATURE',
80
- message: 'Ed25519 signature verification failed',
81
- };
82
- }
83
- // 2. Validate schema
84
- const parseResult = schema_1.ReceiptClaimsSchema.safeParse(result.payload);
85
- if (!parseResult.success) {
86
- const firstIssue = parseResult.error.issues[0];
87
- return {
88
- valid: false,
89
- code: 'E_INVALID_FORMAT',
90
- message: `Receipt schema validation failed: ${firstIssue?.message ?? 'unknown error'}`,
91
- };
92
- }
93
- const claims = parseResult.data;
94
- // 3. Check issuer binding
95
- if (issuer !== undefined && claims.iss !== issuer) {
96
- return {
97
- valid: false,
98
- code: 'E_INVALID_ISSUER',
99
- message: `Issuer mismatch: expected "${issuer}", got "${claims.iss}"`,
100
- };
101
- }
102
- // 4. Check audience binding
103
- if (audience !== undefined && claims.aud !== audience) {
104
- return {
105
- valid: false,
106
- code: 'E_INVALID_AUDIENCE',
107
- message: `Audience mismatch: expected "${audience}", got "${claims.aud}"`,
108
- };
109
- }
110
- // 5. Check subject binding
111
- if (subjectUri !== undefined) {
112
- const actualSubjectUri = claims.subject?.uri;
113
- if (actualSubjectUri !== subjectUri) {
114
- return {
115
- valid: false,
116
- code: 'E_INVALID_SUBJECT',
117
- message: `Subject mismatch: expected "${subjectUri}", got "${actualSubjectUri ?? 'undefined'}"`,
118
- };
119
- }
120
- }
121
- // 6. Check receipt ID binding
122
- if (rid !== undefined && claims.rid !== rid) {
123
- return {
124
- valid: false,
125
- code: 'E_INVALID_RECEIPT_ID',
126
- message: `Receipt ID mismatch: expected "${rid}", got "${claims.rid}"`,
127
- };
128
- }
129
- // 7. Check requireExp
130
- if (requireExp && claims.exp === undefined) {
131
- return {
132
- valid: false,
133
- code: 'E_MISSING_EXP',
134
- message: 'Receipt missing required exp claim',
135
- };
136
- }
137
- // 8. Check not-yet-valid (iat with clock skew)
138
- if (claims.iat > now + maxClockSkew) {
139
- return {
140
- valid: false,
141
- code: 'E_NOT_YET_VALID',
142
- message: `Receipt not yet valid: issued at ${new Date(claims.iat * 1000).toISOString()}, now is ${new Date(now * 1000).toISOString()}`,
143
- };
144
- }
145
- // 9. Check expiry (with clock skew tolerance)
146
- if (claims.exp !== undefined && claims.exp < now - maxClockSkew) {
147
- return {
148
- valid: false,
149
- code: 'E_EXPIRED',
150
- message: `Receipt expired at ${new Date(claims.exp * 1000).toISOString()}`,
151
- };
152
- }
153
- return {
154
- valid: true,
155
- claims,
156
- kid: result.header.kid,
157
- };
158
- }
159
- catch (err) {
160
- // Handle typed CryptoError from @peac/crypto
161
- // Use structural check instead of instanceof for robustness across ESM/CJS boundaries
162
- // Map internal CRYPTO_* codes to canonical E_* codes
163
- if (isCryptoError(err)) {
164
- if (FORMAT_ERROR_CODES.has(err.code)) {
165
- return {
166
- valid: false,
167
- code: 'E_INVALID_FORMAT',
168
- message: err.message,
169
- };
170
- }
171
- if (err.code === 'CRYPTO_INVALID_SIGNATURE') {
172
- return {
173
- valid: false,
174
- code: 'E_INVALID_SIGNATURE',
175
- message: err.message,
176
- };
177
- }
178
- }
179
- // All other errors (JSON parse, unexpected) -> E_INTERNAL
180
- // No message parsing - code-based mapping only
181
- const message = err instanceof Error ? err.message : String(err);
182
- return {
183
- valid: false,
184
- code: 'E_INTERNAL',
185
- message: `Unexpected verification error: ${message}`,
186
- };
187
- }
188
- }
189
- //# sourceMappingURL=verify-local.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verify-local.js","sourceRoot":"","sources":["../src/verify-local.ts"],"names":[],"mappings":"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"}
package/dist/verify.js DELETED
@@ -1,202 +0,0 @@
1
- "use strict";
2
- /**
3
- * Receipt verification with JWKS fetching and caching
4
- */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.verifyReceipt = verifyReceipt;
7
- const crypto_1 = require("@peac/crypto");
8
- const schema_1 = require("@peac/schema");
9
- const telemetry_1 = require("@peac/telemetry");
10
- const telemetry_js_1 = require("./telemetry.js");
11
- /**
12
- * In-memory JWKS cache
13
- * Maps issuer URL to { keys, expiresAt }
14
- */
15
- const jwksCache = new Map();
16
- /**
17
- * Cache TTL (5 minutes)
18
- */
19
- const CACHE_TTL_MS = 5 * 60 * 1000;
20
- /**
21
- * Fetch JWKS from issuer (SSRF-safe)
22
- */
23
- async function fetchJWKS(issuerUrl) {
24
- // SSRF protection: only allow https://
25
- if (!issuerUrl.startsWith('https://')) {
26
- throw new Error('Issuer URL must be https://');
27
- }
28
- // Construct JWKS URL from discovery
29
- const discoveryUrl = `${issuerUrl}/.well-known/peac.txt`;
30
- try {
31
- const discoveryResp = await fetch(discoveryUrl, {
32
- headers: { Accept: 'text/plain' },
33
- // Timeout after 5 seconds
34
- signal: AbortSignal.timeout(5000),
35
- });
36
- if (!discoveryResp.ok) {
37
- throw new Error(`Discovery fetch failed: ${discoveryResp.status}`);
38
- }
39
- const discoveryText = await discoveryResp.text();
40
- // Parse YAML-like discovery (simple key: value parsing)
41
- const jwksLine = discoveryText.split('\n').find((line) => line.startsWith('jwks:'));
42
- if (!jwksLine) {
43
- throw new Error('No jwks field in discovery');
44
- }
45
- const jwksUrl = jwksLine.replace('jwks:', '').trim();
46
- // SSRF protection: verify JWKS URL is also https://
47
- if (!jwksUrl.startsWith('https://')) {
48
- throw new Error('JWKS URL must be https://');
49
- }
50
- // Fetch JWKS
51
- const jwksResp = await fetch(jwksUrl, {
52
- headers: { Accept: 'application/json' },
53
- signal: AbortSignal.timeout(5000),
54
- });
55
- if (!jwksResp.ok) {
56
- throw new Error(`JWKS fetch failed: ${jwksResp.status}`);
57
- }
58
- const jwks = (await jwksResp.json());
59
- return jwks;
60
- }
61
- catch (err) {
62
- throw new Error(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
63
- }
64
- }
65
- /**
66
- * Get JWKS (from cache or fetch)
67
- */
68
- async function getJWKS(issuerUrl) {
69
- const now = Date.now();
70
- // Check cache
71
- const cached = jwksCache.get(issuerUrl);
72
- if (cached && cached.expiresAt > now) {
73
- return { jwks: cached.keys, fromCache: true };
74
- }
75
- // Fetch fresh JWKS
76
- const jwks = await fetchJWKS(issuerUrl);
77
- // Cache it
78
- jwksCache.set(issuerUrl, {
79
- keys: jwks,
80
- expiresAt: now + CACHE_TTL_MS,
81
- });
82
- return { jwks, fromCache: false };
83
- }
84
- /**
85
- * Convert JWK x coordinate to Ed25519 public key
86
- */
87
- function jwkToPublicKey(jwk) {
88
- if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {
89
- throw new Error('Only Ed25519 keys (OKP/Ed25519) are supported');
90
- }
91
- // Decode base64url x coordinate
92
- const xBytes = Buffer.from(jwk.x, 'base64url');
93
- if (xBytes.length !== 32) {
94
- throw new Error('Ed25519 public key must be 32 bytes');
95
- }
96
- return new Uint8Array(xBytes);
97
- }
98
- /**
99
- * Emit verification telemetry (no-throw guard)
100
- */
101
- function emitVerifyTelemetry(receiptJws, valid, reasonCode, issuer, kid, durationMs) {
102
- const p = telemetry_1.providerRef.current;
103
- if (p) {
104
- try {
105
- p.onReceiptVerified({
106
- receiptHash: (0, telemetry_js_1.hashReceipt)(receiptJws),
107
- valid,
108
- reasonCode,
109
- issuer,
110
- kid,
111
- durationMs,
112
- });
113
- }
114
- catch {
115
- // Telemetry MUST NOT break core flow
116
- }
117
- }
118
- }
119
- /**
120
- * Verify a PEAC receipt JWS
121
- *
122
- * @param optionsOrJws - Verify options or JWS compact serialization (for backwards compatibility)
123
- * @returns Verification result or failure
124
- */
125
- async function verifyReceipt(optionsOrJws) {
126
- // Support both old (string) and new (options) signatures for backwards compatibility
127
- const receiptJws = typeof optionsOrJws === 'string' ? optionsOrJws : optionsOrJws.receiptJws;
128
- const inputSnapshot = typeof optionsOrJws === 'string' ? undefined : optionsOrJws.subject_snapshot;
129
- const startTime = performance.now();
130
- let jwksFetchTime;
131
- try {
132
- // Decode JWS to get issuer
133
- const { header, payload } = (0, crypto_1.decode)(receiptJws);
134
- // Validate claims structure
135
- schema_1.ReceiptClaims.parse(payload);
136
- // Check expiry
137
- if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {
138
- const durationMs = performance.now() - startTime;
139
- emitVerifyTelemetry(receiptJws, false, 'expired', payload.iss, header.kid, durationMs);
140
- return {
141
- ok: false,
142
- reason: 'expired',
143
- details: `Receipt expired at ${new Date(payload.exp * 1000).toISOString()}`,
144
- };
145
- }
146
- // Fetch JWKS
147
- const jwksFetchStart = performance.now();
148
- const { jwks, fromCache } = await getJWKS(payload.iss);
149
- if (!fromCache) {
150
- jwksFetchTime = performance.now() - jwksFetchStart;
151
- }
152
- // Find key by kid
153
- const jwk = jwks.keys.find((k) => k.kid === header.kid);
154
- if (!jwk) {
155
- const durationMs = performance.now() - startTime;
156
- emitVerifyTelemetry(receiptJws, false, 'unknown_key', payload.iss, header.kid, durationMs);
157
- return {
158
- ok: false,
159
- reason: 'unknown_key',
160
- details: `No key found with kid=${header.kid}`,
161
- };
162
- }
163
- // Convert JWK to public key
164
- const publicKey = jwkToPublicKey(jwk);
165
- // Verify signature
166
- const result = await (0, crypto_1.verify)(receiptJws, publicKey);
167
- if (!result.valid) {
168
- const durationMs = performance.now() - startTime;
169
- emitVerifyTelemetry(receiptJws, false, 'invalid_signature', payload.iss, header.kid, durationMs);
170
- return {
171
- ok: false,
172
- reason: 'invalid_signature',
173
- details: 'Ed25519 signature verification failed',
174
- };
175
- }
176
- // Validate subject_snapshot if provided (v0.9.17+)
177
- // This validates schema and logs advisory PII warning if applicable
178
- const validatedSnapshot = (0, schema_1.validateSubjectSnapshot)(inputSnapshot);
179
- const verifyTime = performance.now() - startTime;
180
- // Emit success telemetry
181
- emitVerifyTelemetry(receiptJws, true, undefined, payload.iss, header.kid, verifyTime);
182
- return {
183
- ok: true,
184
- claims: payload,
185
- ...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),
186
- perf: {
187
- verify_ms: verifyTime,
188
- ...(jwksFetchTime && { jwks_fetch_ms: jwksFetchTime }),
189
- },
190
- };
191
- }
192
- catch (err) {
193
- const durationMs = performance.now() - startTime;
194
- emitVerifyTelemetry(receiptJws, false, 'verification_error', undefined, undefined, durationMs);
195
- return {
196
- ok: false,
197
- reason: 'verification_error',
198
- details: err instanceof Error ? err.message : String(err),
199
- };
200
- }
201
- }
202
- //# sourceMappingURL=verify.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}