@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
package/dist/issue.js DELETED
@@ -1,208 +0,0 @@
1
- "use strict";
2
- /**
3
- * Receipt issuance
4
- * Validates input, generates UUIDv7 rid, and signs with Ed25519
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.IssueError = void 0;
8
- exports.issue = issue;
9
- exports.issueJws = issueJws;
10
- const uuidv7_1 = require("uuidv7");
11
- const crypto_1 = require("@peac/crypto");
12
- const zod_1 = require("zod");
13
- const schema_1 = require("@peac/schema");
14
- const telemetry_1 = require("@peac/telemetry");
15
- const telemetry_js_1 = require("./telemetry.js");
16
- /**
17
- * Error thrown during receipt issuance
18
- *
19
- * Wraps a structured PEACError for programmatic handling.
20
- */
21
- class IssueError extends Error {
22
- /** Structured error details */
23
- peacError;
24
- constructor(peacError) {
25
- const details = peacError.details;
26
- super(details?.message ?? peacError.code);
27
- this.name = 'IssueError';
28
- this.peacError = peacError;
29
- }
30
- }
31
- exports.IssueError = IssueError;
32
- /**
33
- * Issue a PEAC receipt
34
- *
35
- * @param options - Receipt options
36
- * @returns Issue result with JWS and optional subject_snapshot
37
- * @throws IssueError if evidence contains non-JSON-safe values
38
- */
39
- async function issue(options) {
40
- // Validate URLs
41
- if (!options.iss.startsWith('https://')) {
42
- throw new Error('Issuer URL must start with https://');
43
- }
44
- if (!options.aud.startsWith('https://')) {
45
- throw new Error('Audience URL must start with https://');
46
- }
47
- if (options.subject && !options.subject.startsWith('https://')) {
48
- throw new Error('Subject URI must start with https://');
49
- }
50
- // Validate currency code
51
- if (!/^[A-Z]{3}$/.test(options.cur)) {
52
- throw new Error('Currency must be ISO 4217 uppercase (e.g., USD)');
53
- }
54
- // Validate amount
55
- if (!Number.isInteger(options.amt) || options.amt < 0) {
56
- throw new Error('Amount must be a non-negative integer');
57
- }
58
- // Validate expiry (if provided)
59
- if (options.exp !== undefined) {
60
- if (!Number.isInteger(options.exp) || options.exp < 0) {
61
- throw new Error('Expiry must be a non-negative integer');
62
- }
63
- }
64
- // Normalize and validate purpose (v0.9.24+)
65
- let purposeDeclared;
66
- if (options.purpose !== undefined) {
67
- // Normalize to array
68
- const rawPurposes = Array.isArray(options.purpose) ? options.purpose : [options.purpose];
69
- // Validate each token
70
- const invalidTokens = [];
71
- for (const token of rawPurposes) {
72
- if (!(0, schema_1.isValidPurposeToken)(token)) {
73
- invalidTokens.push(token);
74
- }
75
- }
76
- if (invalidTokens.length > 0) {
77
- throw new Error(`Invalid purpose tokens: ${invalidTokens.join(', ')}`);
78
- }
79
- // Check for explicit 'undeclared' which is invalid on wire
80
- if (rawPurposes.includes('undeclared')) {
81
- throw new Error("Explicit 'undeclared' is not a valid purpose token (internal-only)");
82
- }
83
- purposeDeclared = rawPurposes;
84
- }
85
- // Validate purpose_enforced (must be canonical)
86
- if (options.purpose_enforced !== undefined) {
87
- if (!(0, schema_1.isCanonicalPurpose)(options.purpose_enforced)) {
88
- throw new Error(`purpose_enforced must be a canonical purpose, got: ${options.purpose_enforced}`);
89
- }
90
- }
91
- // Validate purpose_reason
92
- if (options.purpose_reason !== undefined) {
93
- if (!(0, schema_1.isValidPurposeReason)(options.purpose_reason)) {
94
- throw new Error(`Invalid purpose_reason: ${options.purpose_reason}`);
95
- }
96
- }
97
- // Validate workflow_context (v0.10.2+)
98
- if (options.workflow_context !== undefined) {
99
- if (!(0, schema_1.isValidWorkflowContext)(options.workflow_context)) {
100
- throw new IssueError((0, schema_1.createWorkflowContextInvalidError)('Does not conform to WorkflowContextSchema'));
101
- }
102
- if (!(0, schema_1.hasValidDagSemantics)(options.workflow_context)) {
103
- // Determine specific reason
104
- const ctx = options.workflow_context;
105
- const isSelfParent = ctx.parent_step_ids.includes(ctx.step_id);
106
- const hasDuplicates = new Set(ctx.parent_step_ids).size !== ctx.parent_step_ids.length;
107
- const reason = isSelfParent ? 'self_parent' : hasDuplicates ? 'duplicate_parent' : 'cycle';
108
- throw new IssueError((0, schema_1.createWorkflowDagInvalidError)(reason));
109
- }
110
- }
111
- // Generate UUIDv7 for receipt ID
112
- const rid = (0, uuidv7_1.uuidv7)();
113
- // Get current timestamp
114
- const iat = Math.floor(Date.now() / 1000);
115
- // Build receipt claims
116
- const claims = {
117
- iss: options.iss,
118
- aud: options.aud,
119
- iat,
120
- rid,
121
- amt: options.amt,
122
- cur: options.cur,
123
- payment: {
124
- rail: options.rail,
125
- reference: options.reference,
126
- amount: options.amt,
127
- currency: options.cur,
128
- asset: options.asset ?? options.cur, // Default asset to currency for backward compatibility
129
- env: options.env ?? 'test', // Default to test environment for backward compatibility
130
- evidence: options.evidence ?? {}, // Default to empty object for backward compatibility
131
- ...(options.network && { network: options.network }),
132
- ...(options.facilitator_ref && { facilitator_ref: options.facilitator_ref }),
133
- ...(options.idempotency_key && { idempotency_key: options.idempotency_key }),
134
- ...(options.metadata && { metadata: options.metadata }),
135
- },
136
- ...(options.exp && { exp: options.exp }),
137
- ...(options.subject && { subject: { uri: options.subject } }),
138
- // Build extensions (merge user-provided ext with workflow_context)
139
- ...((options.ext || options.workflow_context) && {
140
- ext: {
141
- ...options.ext,
142
- ...(options.workflow_context && {
143
- [schema_1.WORKFLOW_EXTENSION_KEY]: options.workflow_context,
144
- }),
145
- },
146
- }),
147
- // Purpose claims (v0.9.24+)
148
- ...(purposeDeclared && { purpose_declared: purposeDeclared }),
149
- ...(options.purpose_enforced && { purpose_enforced: options.purpose_enforced }),
150
- ...(options.purpose_reason && { purpose_reason: options.purpose_reason }),
151
- };
152
- // Validate claims with Zod - map evidence errors to typed error
153
- try {
154
- schema_1.ReceiptClaims.parse(claims);
155
- }
156
- catch (err) {
157
- if (err instanceof zod_1.ZodError) {
158
- // Check if any error path touches evidence
159
- const evidenceIssue = err.issues.find((issue) => issue.path.some((p) => p === 'evidence' || p === 'payment'));
160
- if (evidenceIssue && evidenceIssue.path.includes('evidence')) {
161
- const peacError = (0, schema_1.createEvidenceNotJsonError)(evidenceIssue.message, evidenceIssue.path);
162
- throw new IssueError(peacError);
163
- }
164
- }
165
- throw err;
166
- }
167
- // Validate subject_snapshot if provided (v0.9.17+)
168
- // This validates schema and logs advisory PII warning if applicable
169
- const validatedSnapshot = (0, schema_1.validateSubjectSnapshot)(options.subject_snapshot);
170
- // Track start time for telemetry
171
- const startTime = performance.now();
172
- // Sign with Ed25519
173
- const jws = await (0, crypto_1.sign)(claims, options.privateKey, options.kid);
174
- // Emit telemetry (no-throw guard)
175
- const p = telemetry_1.providerRef.current;
176
- if (p) {
177
- try {
178
- const durationMs = performance.now() - startTime;
179
- p.onReceiptIssued({
180
- receiptHash: (0, telemetry_js_1.hashReceipt)(jws),
181
- issuer: options.iss,
182
- kid: options.kid,
183
- durationMs,
184
- });
185
- }
186
- catch {
187
- // Telemetry MUST NOT break core flow
188
- }
189
- }
190
- return {
191
- jws,
192
- ...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),
193
- };
194
- }
195
- /**
196
- * Issue a PEAC receipt and return just the JWS string
197
- *
198
- * Convenience wrapper for common header-centric flows where only the JWS is needed.
199
- * For access to validated subject_snapshot, use issue() instead.
200
- *
201
- * @param options - Receipt options
202
- * @returns JWS compact serialization
203
- */
204
- async function issueJws(options) {
205
- const result = await issue(options);
206
- return result.jws;
207
- }
208
- //# sourceMappingURL=issue.js.map
package/dist/issue.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"issue.js","sourceRoot":"","sources":["../src/issue.ts"],"names":[],"mappings":"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"}
@@ -1,305 +0,0 @@
1
- "use strict";
2
- /**
3
- * PEAC Pointer Fetch with Digest Verification
4
- *
5
- * Implements secure receipt fetching via pointers per TRANSPORT-PROFILES.md:
6
- * - SSRF-safe fetch
7
- * - SHA-256 digest verification
8
- * - Size limits
9
- *
10
- * @packageDocumentation
11
- */
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.fetchPointerWithDigest = fetchPointerWithDigest;
14
- exports.verifyAndFetchPointer = verifyAndFetchPointer;
15
- const crypto_1 = require("@peac/crypto");
16
- const kernel_1 = require("@peac/kernel");
17
- const ssrf_safe_fetch_js_1 = require("./ssrf-safe-fetch.js");
18
- // ---------------------------------------------------------------------------
19
- // Error Mapping
20
- // ---------------------------------------------------------------------------
21
- /**
22
- * Map SSRF error reason to pointer error reason
23
- */
24
- function mapSsrfError(ssrfError) {
25
- const reason = ssrfError.reason;
26
- switch (reason) {
27
- case 'not_https':
28
- case 'private_ip':
29
- case 'loopback':
30
- case 'link_local':
31
- case 'dns_failure':
32
- case 'cross_origin_redirect':
33
- return {
34
- ok: false,
35
- reason: 'pointer_fetch_blocked',
36
- errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',
37
- message: ssrfError.message,
38
- };
39
- case 'timeout':
40
- return {
41
- ok: false,
42
- reason: 'pointer_fetch_timeout',
43
- errorCode: 'E_VERIFY_POINTER_FETCH_TIMEOUT',
44
- message: ssrfError.message,
45
- };
46
- case 'response_too_large':
47
- return {
48
- ok: false,
49
- reason: 'pointer_fetch_too_large',
50
- errorCode: 'E_VERIFY_POINTER_FETCH_TOO_LARGE',
51
- message: ssrfError.message,
52
- };
53
- default:
54
- return {
55
- ok: false,
56
- reason: 'pointer_fetch_failed',
57
- errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
58
- message: ssrfError.message,
59
- };
60
- }
61
- }
62
- // ---------------------------------------------------------------------------
63
- // Pointer Fetch
64
- // ---------------------------------------------------------------------------
65
- /**
66
- * Fetch a receipt via pointer with digest verification
67
- *
68
- * Per TRANSPORT-PROFILES.md:
69
- * - Fetch the URL using SSRF-safe fetch
70
- * - Compute SHA-256 digest of response
71
- * - Verify digest matches expected value from header
72
- * - Return receipt only if digest matches
73
- *
74
- * @param options - Pointer fetch options
75
- * @returns Fetch result
76
- */
77
- async function fetchPointerWithDigest(options) {
78
- const { url, expectedDigest, fetchOptions = {} } = options;
79
- // Validate expected digest format
80
- const hexRegex = /^[0-9a-f]{64}$/;
81
- if (!hexRegex.test(expectedDigest)) {
82
- return {
83
- ok: false,
84
- reason: 'pointer_fetch_failed',
85
- errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
86
- message: 'Invalid expected digest: must be 64 lowercase hex characters',
87
- };
88
- }
89
- // Validate URL is HTTPS (pre-check before fetch)
90
- try {
91
- const parsedUrl = new URL(url);
92
- if (parsedUrl.protocol !== 'https:') {
93
- return {
94
- ok: false,
95
- reason: 'pointer_fetch_blocked',
96
- errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',
97
- message: 'Pointer URL must use HTTPS',
98
- };
99
- }
100
- }
101
- catch {
102
- return {
103
- ok: false,
104
- reason: 'pointer_fetch_failed',
105
- errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
106
- message: 'Invalid pointer URL',
107
- };
108
- }
109
- // Fetch with SSRF protection and DoS bounds
110
- // - Size cap: maxReceiptBytes (prevents memory exhaustion)
111
- // - No redirects: prevents redirect-based SSRF (pointer URL must be direct)
112
- // - Timeout: prevents slow-loris style attacks
113
- const fetchResult = await (0, ssrf_safe_fetch_js_1.ssrfSafeFetch)(url, {
114
- ...fetchOptions,
115
- maxBytes: kernel_1.VERIFIER_LIMITS.maxReceiptBytes,
116
- allowRedirects: false, // Pointer URL must be direct - no redirects
117
- timeoutMs: fetchOptions?.timeoutMs ?? kernel_1.VERIFIER_LIMITS.fetchTimeoutMs,
118
- headers: {
119
- Accept: 'application/jose, application/json, text/plain',
120
- ...fetchOptions.headers,
121
- },
122
- });
123
- if (!fetchResult.ok) {
124
- return mapSsrfError(fetchResult);
125
- }
126
- const receipt = fetchResult.body;
127
- // Validate Content-Type if present (warn but don't reject for interoperability)
128
- // Expected: application/jose, application/json, or text/plain
129
- const contentType = fetchResult.contentType;
130
- const expectedContentTypes = ['application/jose', 'application/json', 'text/plain'];
131
- const contentTypeWarning = contentType && !expectedContentTypes.some((expected) => contentType.startsWith(expected))
132
- ? `Unexpected Content-Type: ${contentType}; expected application/jose, application/json, or text/plain`
133
- : undefined;
134
- // Validate: reject empty body
135
- if (!receipt || receipt.trim().length === 0) {
136
- return {
137
- ok: false,
138
- reason: 'malformed_receipt',
139
- errorCode: 'E_VERIFY_MALFORMED_RECEIPT',
140
- message: 'Pointer target returned empty content',
141
- };
142
- }
143
- // Validate: content must look like JWS compact serialization (3 dot-separated segments)
144
- const jwsValidation = validateJwsCompactStructure(receipt);
145
- if (!jwsValidation.valid) {
146
- return {
147
- ok: false,
148
- reason: 'malformed_receipt',
149
- errorCode: 'E_VERIFY_MALFORMED_RECEIPT',
150
- message: jwsValidation.message,
151
- };
152
- }
153
- // Compute digest of fetched content (hash the raw string bytes)
154
- const actualDigest = await (0, crypto_1.sha256Hex)(receipt);
155
- // Verify digest matches
156
- if (actualDigest !== expectedDigest) {
157
- return {
158
- ok: false,
159
- reason: 'pointer_digest_mismatch',
160
- errorCode: 'E_VERIFY_POINTER_DIGEST_MISMATCH',
161
- message: 'Fetched receipt digest does not match expected digest',
162
- actualDigest,
163
- expectedDigest,
164
- };
165
- }
166
- return {
167
- ok: true,
168
- receipt,
169
- actualDigest,
170
- digestMatched: true,
171
- contentType: fetchResult.contentType,
172
- ...(contentTypeWarning && { contentTypeWarning }),
173
- };
174
- }
175
- /**
176
- * Validate that a string looks like JWS compact serialization
177
- *
178
- * A valid JWS compact has exactly 3 dot-separated base64url segments.
179
- *
180
- * @param value - String to validate
181
- * @returns Validation result
182
- */
183
- function validateJwsCompactStructure(value) {
184
- const segments = value.split('.');
185
- if (segments.length !== 3) {
186
- return {
187
- valid: false,
188
- message: `Invalid JWS compact serialization: expected 3 segments, got ${segments.length}`,
189
- };
190
- }
191
- // All segments must be non-empty and contain only base64url characters
192
- const base64urlRegex = /^[A-Za-z0-9_-]+$/;
193
- for (let i = 0; i < segments.length; i++) {
194
- const segment = segments[i];
195
- if (segment.length === 0) {
196
- return {
197
- valid: false,
198
- message: `Invalid JWS compact serialization: segment ${i + 1} is empty`,
199
- };
200
- }
201
- if (!base64urlRegex.test(segment)) {
202
- return {
203
- valid: false,
204
- message: `Invalid JWS compact serialization: segment ${i + 1} contains invalid characters`,
205
- };
206
- }
207
- }
208
- return { valid: true };
209
- }
210
- /**
211
- * Parse pointer header key=value pairs (ReDoS-safe)
212
- *
213
- * Handles both quoted and unquoted values without complex regex alternation.
214
- */
215
- function parsePointerHeader(input) {
216
- const params = {};
217
- let i = 0;
218
- const len = input.length;
219
- while (i < len) {
220
- // Skip whitespace and commas
221
- while (i < len && (input[i] === ' ' || input[i] === ',' || input[i] === '\t')) {
222
- i++;
223
- }
224
- if (i >= len)
225
- break;
226
- // Parse key (word characters only)
227
- const keyStart = i;
228
- while (i < len && /\w/.test(input[i])) {
229
- i++;
230
- }
231
- const key = input.slice(keyStart, i);
232
- if (!key)
233
- break;
234
- // Skip whitespace before '='
235
- while (i < len && input[i] === ' ')
236
- i++;
237
- // Expect '='
238
- if (i >= len || input[i] !== '=')
239
- break;
240
- i++; // skip '='
241
- // Skip whitespace after '='
242
- while (i < len && input[i] === ' ')
243
- i++;
244
- // Parse value (quoted or unquoted)
245
- let value;
246
- if (input[i] === '"') {
247
- // Quoted value - find closing quote
248
- i++; // skip opening quote
249
- const valueStart = i;
250
- while (i < len && input[i] !== '"') {
251
- i++;
252
- }
253
- value = input.slice(valueStart, i);
254
- if (i < len)
255
- i++; // skip closing quote
256
- }
257
- else {
258
- // Unquoted value - read until comma or whitespace
259
- const valueStart = i;
260
- while (i < len && input[i] !== ',' && input[i] !== ' ' && input[i] !== '\t') {
261
- i++;
262
- }
263
- value = input.slice(valueStart, i);
264
- }
265
- params[key] = value;
266
- }
267
- return params;
268
- }
269
- /**
270
- * Verify a pointer header and fetch the receipt
271
- *
272
- * Combines parsing and fetching in a single operation.
273
- *
274
- * @param pointerHeader - PEAC-Receipt-Pointer header value
275
- * @param fetchOptions - Optional SSRF fetch options
276
- * @returns Fetch result
277
- */
278
- async function verifyAndFetchPointer(pointerHeader, fetchOptions) {
279
- // Parse pointer header (RFC 8941 dictionary format)
280
- // Format: sha256="<hex>", url="<url>"
281
- // Using explicit parsing to avoid ReDoS in regex alternation
282
- const params = parsePointerHeader(pointerHeader);
283
- if (!params.sha256) {
284
- return {
285
- ok: false,
286
- reason: 'pointer_fetch_failed',
287
- errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
288
- message: 'PEAC-Receipt-Pointer missing sha256 parameter',
289
- };
290
- }
291
- if (!params.url) {
292
- return {
293
- ok: false,
294
- reason: 'pointer_fetch_failed',
295
- errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',
296
- message: 'PEAC-Receipt-Pointer missing url parameter',
297
- };
298
- }
299
- return fetchPointerWithDigest({
300
- url: params.url,
301
- expectedDigest: params.sha256,
302
- fetchOptions,
303
- });
304
- }
305
- //# sourceMappingURL=pointer-fetch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pointer-fetch.js","sourceRoot":"","sources":["../src/pointer-fetch.ts"],"names":[],"mappings":"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"}