@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.
- package/LICENSE +1 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/index.cjs +2694 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +2612 -0
- package/dist/index.mjs.map +1 -0
- package/dist/issue.d.ts +3 -0
- package/dist/issue.d.ts.map +1 -1
- package/dist/telemetry.d.ts +43 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/transport-profiles.d.ts.map +1 -1
- package/dist/verification-report.d.ts.map +1 -1
- package/dist/verifier-types.d.ts +42 -2
- package/dist/verifier-types.d.ts.map +1 -1
- package/dist/verify-local.cjs +164 -0
- package/dist/verify-local.cjs.map +1 -0
- package/dist/verify-local.d.ts +61 -4
- package/dist/verify-local.d.ts.map +1 -1
- package/dist/verify-local.mjs +160 -0
- package/dist/verify-local.mjs.map +1 -0
- package/dist/verify.d.ts +3 -0
- package/dist/verify.d.ts.map +1 -1
- package/package.json +20 -14
- package/dist/crypto-utils.js +0 -21
- package/dist/crypto-utils.js.map +0 -1
- package/dist/discovery.js +0 -405
- package/dist/discovery.js.map +0 -1
- package/dist/headers.js +0 -110
- package/dist/headers.js.map +0 -1
- package/dist/index.js +0 -44
- package/dist/index.js.map +0 -1
- package/dist/issue.js +0 -208
- package/dist/issue.js.map +0 -1
- package/dist/pointer-fetch.js +0 -305
- package/dist/pointer-fetch.js.map +0 -1
- package/dist/ssrf-safe-fetch.js +0 -671
- package/dist/ssrf-safe-fetch.js.map +0 -1
- package/dist/telemetry.js +0 -18
- package/dist/telemetry.js.map +0 -1
- package/dist/transport-profiles.js +0 -424
- package/dist/transport-profiles.js.map +0 -1
- package/dist/verification-report.js +0 -322
- package/dist/verification-report.js.map +0 -1
- package/dist/verifier-core.js +0 -578
- package/dist/verifier-core.js.map +0 -1
- package/dist/verifier-types.js +0 -161
- package/dist/verifier-types.js.map +0 -1
- package/dist/verify-local.js +0 -189
- package/dist/verify-local.js.map +0 -1
- package/dist/verify.js +0 -202
- package/dist/verify.js.map +0 -1
package/dist/verifier-types.js
DELETED
|
@@ -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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"}
|
package/dist/verify-local.js
DELETED
|
@@ -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
|
package/dist/verify-local.js.map
DELETED
|
@@ -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
|
package/dist/verify.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|