@peac/kernel 0.10.9 → 0.10.11
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/constants.cjs +182 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.mjs +159 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/errors.cjs +1330 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.mjs +1323 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/index.cjs +1690 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +1647 -0
- package/dist/index.mjs.map +1 -0
- package/dist/registries.cjs +139 -0
- package/dist/registries.cjs.map +1 -0
- package/dist/registries.mjs +129 -0
- package/dist/registries.mjs.map +1 -0
- package/dist/types.cjs +21 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.mjs +19 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +23 -22
- package/dist/__tests__/http.test.js +0 -121
- package/dist/__tests__/http.test.js.map +0 -1
- package/dist/constants.js +0 -251
- package/dist/constants.js.map +0 -1
- package/dist/error-categories.generated.js +0 -30
- package/dist/error-categories.generated.js.map +0 -1
- package/dist/errors.generated.js +0 -1349
- package/dist/errors.generated.js.map +0 -1
- package/dist/errors.js +0 -18
- package/dist/errors.js.map +0 -1
- package/dist/http.js +0 -74
- package/dist/http.js.map +0 -1
- package/dist/index.js +0 -63
- package/dist/index.js.map +0 -1
- package/dist/registries.js +0 -170
- package/dist/registries.js.map +0 -1
- package/dist/types.js +0 -14
- package/dist/types.js.map +0 -1
package/LICENSE
CHANGED
|
@@ -175,7 +175,7 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
|
175
175
|
|
|
176
176
|
END OF TERMS AND CONDITIONS
|
|
177
177
|
|
|
178
|
-
Copyright 2025 PEAC Protocol Contributors
|
|
178
|
+
Copyright 2025-2026 PEAC Protocol Contributors
|
|
179
179
|
|
|
180
180
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
181
|
you may not use this file except in compliance with the License.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/constants.ts
|
|
4
|
+
var WIRE_TYPE = "peac-receipt/0.1";
|
|
5
|
+
var WIRE_VERSION = "0.1";
|
|
6
|
+
var ALGORITHMS = {
|
|
7
|
+
supported: ["EdDSA"],
|
|
8
|
+
default: "EdDSA"
|
|
9
|
+
};
|
|
10
|
+
var HEADERS = {
|
|
11
|
+
receipt: "PEAC-Receipt",
|
|
12
|
+
receiptPointer: "PEAC-Receipt-Pointer",
|
|
13
|
+
dpop: "DPoP",
|
|
14
|
+
// Purpose headers (v0.9.24+)
|
|
15
|
+
purpose: "PEAC-Purpose",
|
|
16
|
+
purposeApplied: "PEAC-Purpose-Applied",
|
|
17
|
+
purposeReason: "PEAC-Purpose-Reason"
|
|
18
|
+
};
|
|
19
|
+
var POLICY = {
|
|
20
|
+
manifestPath: "/.well-known/peac.txt",
|
|
21
|
+
fallbackPath: "/peac.txt",
|
|
22
|
+
manifestVersion: "peac-policy/0.1",
|
|
23
|
+
cacheTtlSeconds: 3600,
|
|
24
|
+
maxBytes: 262144,
|
|
25
|
+
// 256 KiB
|
|
26
|
+
maxDepth: 8
|
|
27
|
+
};
|
|
28
|
+
var ISSUER_CONFIG = {
|
|
29
|
+
configPath: "/.well-known/peac-issuer.json",
|
|
30
|
+
configVersion: "peac-issuer/0.1",
|
|
31
|
+
cacheTtlSeconds: 3600,
|
|
32
|
+
maxBytes: 65536,
|
|
33
|
+
// 64 KiB
|
|
34
|
+
maxDepth: 4,
|
|
35
|
+
fetchTimeoutMs: 1e4
|
|
36
|
+
};
|
|
37
|
+
var DISCOVERY = {
|
|
38
|
+
manifestPath: POLICY.manifestPath,
|
|
39
|
+
manifestVersion: "peac/0.9",
|
|
40
|
+
cacheTtlSeconds: POLICY.cacheTtlSeconds
|
|
41
|
+
};
|
|
42
|
+
var JWKS = {
|
|
43
|
+
rotationDays: 90,
|
|
44
|
+
overlapDays: 7,
|
|
45
|
+
emergencyRevocationHours: 24
|
|
46
|
+
};
|
|
47
|
+
var RECEIPT = {
|
|
48
|
+
minReceiptIdLength: 16,
|
|
49
|
+
maxReceiptIdLength: 64,
|
|
50
|
+
defaultTtlSeconds: 86400
|
|
51
|
+
// 24 hours
|
|
52
|
+
};
|
|
53
|
+
var LIMITS = {
|
|
54
|
+
maxAmountCents: 999999999999,
|
|
55
|
+
minAmountCents: 1
|
|
56
|
+
};
|
|
57
|
+
var BUNDLE_VERSION = "peac-bundle/0.1";
|
|
58
|
+
var VERIFICATION_REPORT_VERSION = "peac-verification-report/0.1";
|
|
59
|
+
var HASH = {
|
|
60
|
+
/** Canonical hash algorithm */
|
|
61
|
+
algorithm: "sha256",
|
|
62
|
+
/** Hash prefix pattern */
|
|
63
|
+
prefix: "sha256:",
|
|
64
|
+
/** Valid hash regex: sha256:<64 lowercase hex> */
|
|
65
|
+
pattern: /^sha256:[0-9a-f]{64}$/,
|
|
66
|
+
/** Hex-only pattern for legacy comparison */
|
|
67
|
+
hexPattern: /^[0-9a-f]{64}$/
|
|
68
|
+
};
|
|
69
|
+
function parseHash(hash) {
|
|
70
|
+
if (!HASH.pattern.test(hash)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
alg: "sha256",
|
|
75
|
+
hex: hash.slice(7)
|
|
76
|
+
// Remove 'sha256:' prefix
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function formatHash(hex) {
|
|
80
|
+
if (!HASH.hexPattern.test(hex)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return `sha256:${hex}`;
|
|
84
|
+
}
|
|
85
|
+
function isValidHash(hash) {
|
|
86
|
+
return HASH.pattern.test(hash);
|
|
87
|
+
}
|
|
88
|
+
var VERIFIER_LIMITS = {
|
|
89
|
+
/** Maximum receipt size in bytes (256 KB) */
|
|
90
|
+
maxReceiptBytes: 262144,
|
|
91
|
+
/** Maximum number of claims in a receipt */
|
|
92
|
+
maxClaimsCount: 100,
|
|
93
|
+
/** Maximum extension size in bytes (64 KB) */
|
|
94
|
+
maxExtensionBytes: 65536,
|
|
95
|
+
/** Maximum string length for individual claims (64 KB) */
|
|
96
|
+
maxStringLength: 65536,
|
|
97
|
+
/** Maximum JWKS document size in bytes (64 KB) */
|
|
98
|
+
maxJwksBytes: 65536,
|
|
99
|
+
/** Maximum number of keys in a JWKS */
|
|
100
|
+
maxJwksKeys: 20,
|
|
101
|
+
/** Maximum individual key size in bytes */
|
|
102
|
+
maxKeySize: 4096,
|
|
103
|
+
/** Network fetch timeout in milliseconds */
|
|
104
|
+
fetchTimeoutMs: 5e3,
|
|
105
|
+
/** Maximum number of redirects to follow */
|
|
106
|
+
maxRedirects: 3,
|
|
107
|
+
/** Maximum network response size in bytes (256 KB) */
|
|
108
|
+
maxResponseBytes: 262144
|
|
109
|
+
};
|
|
110
|
+
var VERIFIER_NETWORK = {
|
|
111
|
+
/** Only allow HTTPS URLs */
|
|
112
|
+
httpsOnly: true,
|
|
113
|
+
/** Block requests to private IP ranges */
|
|
114
|
+
blockPrivateIps: true,
|
|
115
|
+
/** Default redirect policy (false = no redirects) */
|
|
116
|
+
allowRedirects: false
|
|
117
|
+
};
|
|
118
|
+
var PRIVATE_IP_RANGES = {
|
|
119
|
+
/** RFC 1918 private ranges */
|
|
120
|
+
rfc1918: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
|
|
121
|
+
/** Link-local addresses */
|
|
122
|
+
linkLocal: ["169.254.0.0/16"],
|
|
123
|
+
/** Loopback addresses */
|
|
124
|
+
loopback: ["127.0.0.0/8"],
|
|
125
|
+
/** IPv6 loopback */
|
|
126
|
+
ipv6Loopback: ["::1/128"],
|
|
127
|
+
/** IPv6 link-local */
|
|
128
|
+
ipv6LinkLocal: ["fe80::/10"]
|
|
129
|
+
};
|
|
130
|
+
var VERIFIER_POLICY_VERSION = "peac-verifier-policy/0.1";
|
|
131
|
+
var VERIFICATION_MODES = {
|
|
132
|
+
/** All verification in browser/client, may fetch JWKS */
|
|
133
|
+
clientSide: "client_side",
|
|
134
|
+
/** No network access, uses bundled/pinned keys */
|
|
135
|
+
offlineOnly: "offline_only",
|
|
136
|
+
/** Prefer offline, fallback to network */
|
|
137
|
+
offlinePreferred: "offline_preferred",
|
|
138
|
+
/** Allow network fetches for key discovery */
|
|
139
|
+
networkAllowed: "network_allowed"
|
|
140
|
+
};
|
|
141
|
+
var CONSTANTS = {
|
|
142
|
+
WIRE_TYPE,
|
|
143
|
+
WIRE_VERSION,
|
|
144
|
+
ALGORITHMS,
|
|
145
|
+
HEADERS,
|
|
146
|
+
DISCOVERY,
|
|
147
|
+
JWKS,
|
|
148
|
+
RECEIPT,
|
|
149
|
+
LIMITS,
|
|
150
|
+
BUNDLE_VERSION,
|
|
151
|
+
VERIFICATION_REPORT_VERSION,
|
|
152
|
+
HASH,
|
|
153
|
+
VERIFIER_LIMITS,
|
|
154
|
+
VERIFIER_NETWORK,
|
|
155
|
+
VERIFIER_POLICY_VERSION,
|
|
156
|
+
VERIFICATION_MODES
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
exports.ALGORITHMS = ALGORITHMS;
|
|
160
|
+
exports.BUNDLE_VERSION = BUNDLE_VERSION;
|
|
161
|
+
exports.CONSTANTS = CONSTANTS;
|
|
162
|
+
exports.DISCOVERY = DISCOVERY;
|
|
163
|
+
exports.HASH = HASH;
|
|
164
|
+
exports.HEADERS = HEADERS;
|
|
165
|
+
exports.ISSUER_CONFIG = ISSUER_CONFIG;
|
|
166
|
+
exports.JWKS = JWKS;
|
|
167
|
+
exports.LIMITS = LIMITS;
|
|
168
|
+
exports.POLICY = POLICY;
|
|
169
|
+
exports.PRIVATE_IP_RANGES = PRIVATE_IP_RANGES;
|
|
170
|
+
exports.RECEIPT = RECEIPT;
|
|
171
|
+
exports.VERIFICATION_MODES = VERIFICATION_MODES;
|
|
172
|
+
exports.VERIFICATION_REPORT_VERSION = VERIFICATION_REPORT_VERSION;
|
|
173
|
+
exports.VERIFIER_LIMITS = VERIFIER_LIMITS;
|
|
174
|
+
exports.VERIFIER_NETWORK = VERIFIER_NETWORK;
|
|
175
|
+
exports.VERIFIER_POLICY_VERSION = VERIFIER_POLICY_VERSION;
|
|
176
|
+
exports.WIRE_TYPE = WIRE_TYPE;
|
|
177
|
+
exports.WIRE_VERSION = WIRE_VERSION;
|
|
178
|
+
exports.formatHash = formatHash;
|
|
179
|
+
exports.isValidHash = isValidHash;
|
|
180
|
+
exports.parseHash = parseHash;
|
|
181
|
+
//# sourceMappingURL=constants.cjs.map
|
|
182
|
+
//# sourceMappingURL=constants.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"names":[],"mappings":"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","file":"constants.cjs","sourcesContent":["/**\n * PEAC Protocol Constants\n * Derived from specs/kernel/constants.json\n *\n * NOTE: This file is manually synced for v0.9.15.\n * From v0.9.16+, this will be auto-generated via codegen.\n */\n\n/**\n * Wire format type for PEAC receipts\n * Normalized to peac-receipt/0.1 per DEC-20260114-002\n */\nexport const WIRE_TYPE = 'peac-receipt/0.1' as const;\n\n/**\n * Wire format version (extracted from WIRE_TYPE)\n * Use this for wire_version fields in receipts\n */\nexport const WIRE_VERSION = '0.1' as const;\n\n/**\n * Supported cryptographic algorithms\n */\nexport const ALGORITHMS = {\n supported: ['EdDSA'] as const,\n default: 'EdDSA' as const,\n} as const;\n\n/**\n * HTTP header names for PEAC protocol\n */\nexport const HEADERS = {\n receipt: 'PEAC-Receipt' as const,\n receiptPointer: 'PEAC-Receipt-Pointer' as const,\n dpop: 'DPoP' as const,\n // Purpose headers (v0.9.24+)\n purpose: 'PEAC-Purpose' as const,\n purposeApplied: 'PEAC-Purpose-Applied' as const,\n purposeReason: 'PEAC-Purpose-Reason' as const,\n} as const;\n\n/**\n * Policy manifest settings (/.well-known/peac.txt)\n *\n * Policy documents declare access terms for agents and gateways.\n * @see docs/specs/PEAC-TXT.md\n */\nexport const POLICY = {\n manifestPath: '/.well-known/peac.txt' as const,\n fallbackPath: '/peac.txt' as const,\n manifestVersion: 'peac-policy/0.1' as const,\n cacheTtlSeconds: 3600,\n maxBytes: 262144, // 256 KiB\n maxDepth: 8,\n} as const;\n\n/**\n * Issuer configuration settings (/.well-known/peac-issuer.json)\n *\n * Issuer config enables verifiers to discover JWKS and verification endpoints.\n * @see docs/specs/PEAC-ISSUER.md\n */\nexport const ISSUER_CONFIG = {\n configPath: '/.well-known/peac-issuer.json' as const,\n configVersion: 'peac-issuer/0.1' as const,\n cacheTtlSeconds: 3600,\n maxBytes: 65536, // 64 KiB\n maxDepth: 4,\n fetchTimeoutMs: 10000,\n} as const;\n\n/**\n * @deprecated Use POLICY instead. Will be removed in v1.0.\n */\nexport const DISCOVERY = {\n manifestPath: POLICY.manifestPath,\n manifestVersion: 'peac/0.9' as const,\n cacheTtlSeconds: POLICY.cacheTtlSeconds,\n} as const;\n\n/**\n * JWKS rotation and revocation settings\n */\nexport const JWKS = {\n rotationDays: 90,\n overlapDays: 7,\n emergencyRevocationHours: 24,\n} as const;\n\n/**\n * Receipt validation constants\n */\nexport const RECEIPT = {\n minReceiptIdLength: 16,\n maxReceiptIdLength: 64,\n defaultTtlSeconds: 86400, // 24 hours\n} as const;\n\n/**\n * Payment amount validation limits (in cents/smallest currency unit)\n */\nexport const LIMITS = {\n maxAmountCents: 999999999999,\n minAmountCents: 1,\n} as const;\n\n/**\n * Bundle format version.\n * Used in dispute bundles, audit bundles, and archive bundles.\n */\nexport const BUNDLE_VERSION = 'peac-bundle/0.1' as const;\n\n/**\n * Verification report format version.\n */\nexport const VERIFICATION_REPORT_VERSION = 'peac-verification-report/0.1' as const;\n\n/**\n * Hash format constants and utilities.\n * All hashes use the self-describing format: sha256:<64 lowercase hex chars>\n */\nexport const HASH = {\n /** Canonical hash algorithm */\n algorithm: 'sha256' as const,\n\n /** Hash prefix pattern */\n prefix: 'sha256:' as const,\n\n /** Valid hash regex: sha256:<64 lowercase hex> */\n pattern: /^sha256:[0-9a-f]{64}$/,\n\n /** Hex-only pattern for legacy comparison */\n hexPattern: /^[0-9a-f]{64}$/,\n};\n\n/**\n * Parse a sha256:<hex> hash string into components.\n * Returns null if the format is invalid.\n *\n * @param hash - Hash string to parse (e.g., \"sha256:abc123...\")\n * @returns Parsed hash or null if invalid\n */\nexport function parseHash(hash: string): { alg: 'sha256'; hex: string } | null {\n if (!HASH.pattern.test(hash)) {\n return null;\n }\n return {\n alg: 'sha256',\n hex: hash.slice(7), // Remove 'sha256:' prefix\n };\n}\n\n/**\n * Format a hex string as a sha256:<hex> hash.\n * Validates that the hex is exactly 64 lowercase characters.\n *\n * @param hex - Hex string (64 lowercase characters)\n * @returns Formatted hash or null if invalid\n */\nexport function formatHash(hex: string): string | null {\n if (!HASH.hexPattern.test(hex)) {\n return null;\n }\n return `sha256:${hex}`;\n}\n\n/**\n * Validate a hash string is in the correct format.\n *\n * @param hash - Hash string to validate\n * @returns true if valid sha256:<64 hex> format\n */\nexport function isValidHash(hash: string): boolean {\n return HASH.pattern.test(hash);\n}\n\n/**\n * Verifier security limits per VERIFIER-SECURITY-MODEL.md\n */\nexport const VERIFIER_LIMITS = {\n /** Maximum receipt size in bytes (256 KB) */\n maxReceiptBytes: 262144,\n /** Maximum number of claims in a receipt */\n maxClaimsCount: 100,\n /** Maximum extension size in bytes (64 KB) */\n maxExtensionBytes: 65536,\n /** Maximum string length for individual claims (64 KB) */\n maxStringLength: 65536,\n /** Maximum JWKS document size in bytes (64 KB) */\n maxJwksBytes: 65536,\n /** Maximum number of keys in a JWKS */\n maxJwksKeys: 20,\n /** Maximum individual key size in bytes */\n maxKeySize: 4096,\n /** Network fetch timeout in milliseconds */\n fetchTimeoutMs: 5000,\n /** Maximum number of redirects to follow */\n maxRedirects: 3,\n /** Maximum network response size in bytes (256 KB) */\n maxResponseBytes: 262144,\n} as const;\n\n/**\n * Verifier network security settings per VERIFIER-SECURITY-MODEL.md\n */\nexport const VERIFIER_NETWORK = {\n /** Only allow HTTPS URLs */\n httpsOnly: true,\n /** Block requests to private IP ranges */\n blockPrivateIps: true,\n /** Default redirect policy (false = no redirects) */\n allowRedirects: false,\n} as const;\n\n/**\n * Private IPv4 CIDR blocks to block for SSRF protection\n */\nexport const PRIVATE_IP_RANGES = {\n /** RFC 1918 private ranges */\n rfc1918: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'] as const,\n /** Link-local addresses */\n linkLocal: ['169.254.0.0/16'] as const,\n /** Loopback addresses */\n loopback: ['127.0.0.0/8'] as const,\n /** IPv6 loopback */\n ipv6Loopback: ['::1/128'] as const,\n /** IPv6 link-local */\n ipv6LinkLocal: ['fe80::/10'] as const,\n} as const;\n\n/**\n * Verifier policy version\n */\nexport const VERIFIER_POLICY_VERSION = 'peac-verifier-policy/0.1' as const;\n\n/**\n * Verification modes per VERIFIER-SECURITY-MODEL.md\n */\nexport const VERIFICATION_MODES = {\n /** All verification in browser/client, may fetch JWKS */\n clientSide: 'client_side' as const,\n /** No network access, uses bundled/pinned keys */\n offlineOnly: 'offline_only' as const,\n /** Prefer offline, fallback to network */\n offlinePreferred: 'offline_preferred' as const,\n /** Allow network fetches for key discovery */\n networkAllowed: 'network_allowed' as const,\n} as const;\n\n/**\n * All constants export\n */\nexport const CONSTANTS = {\n WIRE_TYPE,\n WIRE_VERSION,\n ALGORITHMS,\n HEADERS,\n DISCOVERY,\n JWKS,\n RECEIPT,\n LIMITS,\n BUNDLE_VERSION,\n VERIFICATION_REPORT_VERSION,\n HASH,\n VERIFIER_LIMITS,\n VERIFIER_NETWORK,\n VERIFIER_POLICY_VERSION,\n VERIFICATION_MODES,\n} as const;\n"]}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var WIRE_TYPE = "peac-receipt/0.1";
|
|
3
|
+
var WIRE_VERSION = "0.1";
|
|
4
|
+
var ALGORITHMS = {
|
|
5
|
+
supported: ["EdDSA"],
|
|
6
|
+
default: "EdDSA"
|
|
7
|
+
};
|
|
8
|
+
var HEADERS = {
|
|
9
|
+
receipt: "PEAC-Receipt",
|
|
10
|
+
receiptPointer: "PEAC-Receipt-Pointer",
|
|
11
|
+
dpop: "DPoP",
|
|
12
|
+
// Purpose headers (v0.9.24+)
|
|
13
|
+
purpose: "PEAC-Purpose",
|
|
14
|
+
purposeApplied: "PEAC-Purpose-Applied",
|
|
15
|
+
purposeReason: "PEAC-Purpose-Reason"
|
|
16
|
+
};
|
|
17
|
+
var POLICY = {
|
|
18
|
+
manifestPath: "/.well-known/peac.txt",
|
|
19
|
+
fallbackPath: "/peac.txt",
|
|
20
|
+
manifestVersion: "peac-policy/0.1",
|
|
21
|
+
cacheTtlSeconds: 3600,
|
|
22
|
+
maxBytes: 262144,
|
|
23
|
+
// 256 KiB
|
|
24
|
+
maxDepth: 8
|
|
25
|
+
};
|
|
26
|
+
var ISSUER_CONFIG = {
|
|
27
|
+
configPath: "/.well-known/peac-issuer.json",
|
|
28
|
+
configVersion: "peac-issuer/0.1",
|
|
29
|
+
cacheTtlSeconds: 3600,
|
|
30
|
+
maxBytes: 65536,
|
|
31
|
+
// 64 KiB
|
|
32
|
+
maxDepth: 4,
|
|
33
|
+
fetchTimeoutMs: 1e4
|
|
34
|
+
};
|
|
35
|
+
var DISCOVERY = {
|
|
36
|
+
manifestPath: POLICY.manifestPath,
|
|
37
|
+
manifestVersion: "peac/0.9",
|
|
38
|
+
cacheTtlSeconds: POLICY.cacheTtlSeconds
|
|
39
|
+
};
|
|
40
|
+
var JWKS = {
|
|
41
|
+
rotationDays: 90,
|
|
42
|
+
overlapDays: 7,
|
|
43
|
+
emergencyRevocationHours: 24
|
|
44
|
+
};
|
|
45
|
+
var RECEIPT = {
|
|
46
|
+
minReceiptIdLength: 16,
|
|
47
|
+
maxReceiptIdLength: 64,
|
|
48
|
+
defaultTtlSeconds: 86400
|
|
49
|
+
// 24 hours
|
|
50
|
+
};
|
|
51
|
+
var LIMITS = {
|
|
52
|
+
maxAmountCents: 999999999999,
|
|
53
|
+
minAmountCents: 1
|
|
54
|
+
};
|
|
55
|
+
var BUNDLE_VERSION = "peac-bundle/0.1";
|
|
56
|
+
var VERIFICATION_REPORT_VERSION = "peac-verification-report/0.1";
|
|
57
|
+
var HASH = {
|
|
58
|
+
/** Canonical hash algorithm */
|
|
59
|
+
algorithm: "sha256",
|
|
60
|
+
/** Hash prefix pattern */
|
|
61
|
+
prefix: "sha256:",
|
|
62
|
+
/** Valid hash regex: sha256:<64 lowercase hex> */
|
|
63
|
+
pattern: /^sha256:[0-9a-f]{64}$/,
|
|
64
|
+
/** Hex-only pattern for legacy comparison */
|
|
65
|
+
hexPattern: /^[0-9a-f]{64}$/
|
|
66
|
+
};
|
|
67
|
+
function parseHash(hash) {
|
|
68
|
+
if (!HASH.pattern.test(hash)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
alg: "sha256",
|
|
73
|
+
hex: hash.slice(7)
|
|
74
|
+
// Remove 'sha256:' prefix
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function formatHash(hex) {
|
|
78
|
+
if (!HASH.hexPattern.test(hex)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
return `sha256:${hex}`;
|
|
82
|
+
}
|
|
83
|
+
function isValidHash(hash) {
|
|
84
|
+
return HASH.pattern.test(hash);
|
|
85
|
+
}
|
|
86
|
+
var VERIFIER_LIMITS = {
|
|
87
|
+
/** Maximum receipt size in bytes (256 KB) */
|
|
88
|
+
maxReceiptBytes: 262144,
|
|
89
|
+
/** Maximum number of claims in a receipt */
|
|
90
|
+
maxClaimsCount: 100,
|
|
91
|
+
/** Maximum extension size in bytes (64 KB) */
|
|
92
|
+
maxExtensionBytes: 65536,
|
|
93
|
+
/** Maximum string length for individual claims (64 KB) */
|
|
94
|
+
maxStringLength: 65536,
|
|
95
|
+
/** Maximum JWKS document size in bytes (64 KB) */
|
|
96
|
+
maxJwksBytes: 65536,
|
|
97
|
+
/** Maximum number of keys in a JWKS */
|
|
98
|
+
maxJwksKeys: 20,
|
|
99
|
+
/** Maximum individual key size in bytes */
|
|
100
|
+
maxKeySize: 4096,
|
|
101
|
+
/** Network fetch timeout in milliseconds */
|
|
102
|
+
fetchTimeoutMs: 5e3,
|
|
103
|
+
/** Maximum number of redirects to follow */
|
|
104
|
+
maxRedirects: 3,
|
|
105
|
+
/** Maximum network response size in bytes (256 KB) */
|
|
106
|
+
maxResponseBytes: 262144
|
|
107
|
+
};
|
|
108
|
+
var VERIFIER_NETWORK = {
|
|
109
|
+
/** Only allow HTTPS URLs */
|
|
110
|
+
httpsOnly: true,
|
|
111
|
+
/** Block requests to private IP ranges */
|
|
112
|
+
blockPrivateIps: true,
|
|
113
|
+
/** Default redirect policy (false = no redirects) */
|
|
114
|
+
allowRedirects: false
|
|
115
|
+
};
|
|
116
|
+
var PRIVATE_IP_RANGES = {
|
|
117
|
+
/** RFC 1918 private ranges */
|
|
118
|
+
rfc1918: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
|
|
119
|
+
/** Link-local addresses */
|
|
120
|
+
linkLocal: ["169.254.0.0/16"],
|
|
121
|
+
/** Loopback addresses */
|
|
122
|
+
loopback: ["127.0.0.0/8"],
|
|
123
|
+
/** IPv6 loopback */
|
|
124
|
+
ipv6Loopback: ["::1/128"],
|
|
125
|
+
/** IPv6 link-local */
|
|
126
|
+
ipv6LinkLocal: ["fe80::/10"]
|
|
127
|
+
};
|
|
128
|
+
var VERIFIER_POLICY_VERSION = "peac-verifier-policy/0.1";
|
|
129
|
+
var VERIFICATION_MODES = {
|
|
130
|
+
/** All verification in browser/client, may fetch JWKS */
|
|
131
|
+
clientSide: "client_side",
|
|
132
|
+
/** No network access, uses bundled/pinned keys */
|
|
133
|
+
offlineOnly: "offline_only",
|
|
134
|
+
/** Prefer offline, fallback to network */
|
|
135
|
+
offlinePreferred: "offline_preferred",
|
|
136
|
+
/** Allow network fetches for key discovery */
|
|
137
|
+
networkAllowed: "network_allowed"
|
|
138
|
+
};
|
|
139
|
+
var CONSTANTS = {
|
|
140
|
+
WIRE_TYPE,
|
|
141
|
+
WIRE_VERSION,
|
|
142
|
+
ALGORITHMS,
|
|
143
|
+
HEADERS,
|
|
144
|
+
DISCOVERY,
|
|
145
|
+
JWKS,
|
|
146
|
+
RECEIPT,
|
|
147
|
+
LIMITS,
|
|
148
|
+
BUNDLE_VERSION,
|
|
149
|
+
VERIFICATION_REPORT_VERSION,
|
|
150
|
+
HASH,
|
|
151
|
+
VERIFIER_LIMITS,
|
|
152
|
+
VERIFIER_NETWORK,
|
|
153
|
+
VERIFIER_POLICY_VERSION,
|
|
154
|
+
VERIFICATION_MODES
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export { ALGORITHMS, BUNDLE_VERSION, CONSTANTS, DISCOVERY, HASH, HEADERS, ISSUER_CONFIG, JWKS, LIMITS, POLICY, PRIVATE_IP_RANGES, RECEIPT, VERIFICATION_MODES, VERIFICATION_REPORT_VERSION, VERIFIER_LIMITS, VERIFIER_NETWORK, VERIFIER_POLICY_VERSION, WIRE_TYPE, WIRE_VERSION, formatHash, isValidHash, parseHash };
|
|
158
|
+
//# sourceMappingURL=constants.mjs.map
|
|
159
|
+
//# sourceMappingURL=constants.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"names":[],"mappings":"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","file":"constants.mjs","sourcesContent":["/**\n * PEAC Protocol Constants\n * Derived from specs/kernel/constants.json\n *\n * NOTE: This file is manually synced for v0.9.15.\n * From v0.9.16+, this will be auto-generated via codegen.\n */\n\n/**\n * Wire format type for PEAC receipts\n * Normalized to peac-receipt/0.1 per DEC-20260114-002\n */\nexport const WIRE_TYPE = 'peac-receipt/0.1' as const;\n\n/**\n * Wire format version (extracted from WIRE_TYPE)\n * Use this for wire_version fields in receipts\n */\nexport const WIRE_VERSION = '0.1' as const;\n\n/**\n * Supported cryptographic algorithms\n */\nexport const ALGORITHMS = {\n supported: ['EdDSA'] as const,\n default: 'EdDSA' as const,\n} as const;\n\n/**\n * HTTP header names for PEAC protocol\n */\nexport const HEADERS = {\n receipt: 'PEAC-Receipt' as const,\n receiptPointer: 'PEAC-Receipt-Pointer' as const,\n dpop: 'DPoP' as const,\n // Purpose headers (v0.9.24+)\n purpose: 'PEAC-Purpose' as const,\n purposeApplied: 'PEAC-Purpose-Applied' as const,\n purposeReason: 'PEAC-Purpose-Reason' as const,\n} as const;\n\n/**\n * Policy manifest settings (/.well-known/peac.txt)\n *\n * Policy documents declare access terms for agents and gateways.\n * @see docs/specs/PEAC-TXT.md\n */\nexport const POLICY = {\n manifestPath: '/.well-known/peac.txt' as const,\n fallbackPath: '/peac.txt' as const,\n manifestVersion: 'peac-policy/0.1' as const,\n cacheTtlSeconds: 3600,\n maxBytes: 262144, // 256 KiB\n maxDepth: 8,\n} as const;\n\n/**\n * Issuer configuration settings (/.well-known/peac-issuer.json)\n *\n * Issuer config enables verifiers to discover JWKS and verification endpoints.\n * @see docs/specs/PEAC-ISSUER.md\n */\nexport const ISSUER_CONFIG = {\n configPath: '/.well-known/peac-issuer.json' as const,\n configVersion: 'peac-issuer/0.1' as const,\n cacheTtlSeconds: 3600,\n maxBytes: 65536, // 64 KiB\n maxDepth: 4,\n fetchTimeoutMs: 10000,\n} as const;\n\n/**\n * @deprecated Use POLICY instead. Will be removed in v1.0.\n */\nexport const DISCOVERY = {\n manifestPath: POLICY.manifestPath,\n manifestVersion: 'peac/0.9' as const,\n cacheTtlSeconds: POLICY.cacheTtlSeconds,\n} as const;\n\n/**\n * JWKS rotation and revocation settings\n */\nexport const JWKS = {\n rotationDays: 90,\n overlapDays: 7,\n emergencyRevocationHours: 24,\n} as const;\n\n/**\n * Receipt validation constants\n */\nexport const RECEIPT = {\n minReceiptIdLength: 16,\n maxReceiptIdLength: 64,\n defaultTtlSeconds: 86400, // 24 hours\n} as const;\n\n/**\n * Payment amount validation limits (in cents/smallest currency unit)\n */\nexport const LIMITS = {\n maxAmountCents: 999999999999,\n minAmountCents: 1,\n} as const;\n\n/**\n * Bundle format version.\n * Used in dispute bundles, audit bundles, and archive bundles.\n */\nexport const BUNDLE_VERSION = 'peac-bundle/0.1' as const;\n\n/**\n * Verification report format version.\n */\nexport const VERIFICATION_REPORT_VERSION = 'peac-verification-report/0.1' as const;\n\n/**\n * Hash format constants and utilities.\n * All hashes use the self-describing format: sha256:<64 lowercase hex chars>\n */\nexport const HASH = {\n /** Canonical hash algorithm */\n algorithm: 'sha256' as const,\n\n /** Hash prefix pattern */\n prefix: 'sha256:' as const,\n\n /** Valid hash regex: sha256:<64 lowercase hex> */\n pattern: /^sha256:[0-9a-f]{64}$/,\n\n /** Hex-only pattern for legacy comparison */\n hexPattern: /^[0-9a-f]{64}$/,\n};\n\n/**\n * Parse a sha256:<hex> hash string into components.\n * Returns null if the format is invalid.\n *\n * @param hash - Hash string to parse (e.g., \"sha256:abc123...\")\n * @returns Parsed hash or null if invalid\n */\nexport function parseHash(hash: string): { alg: 'sha256'; hex: string } | null {\n if (!HASH.pattern.test(hash)) {\n return null;\n }\n return {\n alg: 'sha256',\n hex: hash.slice(7), // Remove 'sha256:' prefix\n };\n}\n\n/**\n * Format a hex string as a sha256:<hex> hash.\n * Validates that the hex is exactly 64 lowercase characters.\n *\n * @param hex - Hex string (64 lowercase characters)\n * @returns Formatted hash or null if invalid\n */\nexport function formatHash(hex: string): string | null {\n if (!HASH.hexPattern.test(hex)) {\n return null;\n }\n return `sha256:${hex}`;\n}\n\n/**\n * Validate a hash string is in the correct format.\n *\n * @param hash - Hash string to validate\n * @returns true if valid sha256:<64 hex> format\n */\nexport function isValidHash(hash: string): boolean {\n return HASH.pattern.test(hash);\n}\n\n/**\n * Verifier security limits per VERIFIER-SECURITY-MODEL.md\n */\nexport const VERIFIER_LIMITS = {\n /** Maximum receipt size in bytes (256 KB) */\n maxReceiptBytes: 262144,\n /** Maximum number of claims in a receipt */\n maxClaimsCount: 100,\n /** Maximum extension size in bytes (64 KB) */\n maxExtensionBytes: 65536,\n /** Maximum string length for individual claims (64 KB) */\n maxStringLength: 65536,\n /** Maximum JWKS document size in bytes (64 KB) */\n maxJwksBytes: 65536,\n /** Maximum number of keys in a JWKS */\n maxJwksKeys: 20,\n /** Maximum individual key size in bytes */\n maxKeySize: 4096,\n /** Network fetch timeout in milliseconds */\n fetchTimeoutMs: 5000,\n /** Maximum number of redirects to follow */\n maxRedirects: 3,\n /** Maximum network response size in bytes (256 KB) */\n maxResponseBytes: 262144,\n} as const;\n\n/**\n * Verifier network security settings per VERIFIER-SECURITY-MODEL.md\n */\nexport const VERIFIER_NETWORK = {\n /** Only allow HTTPS URLs */\n httpsOnly: true,\n /** Block requests to private IP ranges */\n blockPrivateIps: true,\n /** Default redirect policy (false = no redirects) */\n allowRedirects: false,\n} as const;\n\n/**\n * Private IPv4 CIDR blocks to block for SSRF protection\n */\nexport const PRIVATE_IP_RANGES = {\n /** RFC 1918 private ranges */\n rfc1918: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'] as const,\n /** Link-local addresses */\n linkLocal: ['169.254.0.0/16'] as const,\n /** Loopback addresses */\n loopback: ['127.0.0.0/8'] as const,\n /** IPv6 loopback */\n ipv6Loopback: ['::1/128'] as const,\n /** IPv6 link-local */\n ipv6LinkLocal: ['fe80::/10'] as const,\n} as const;\n\n/**\n * Verifier policy version\n */\nexport const VERIFIER_POLICY_VERSION = 'peac-verifier-policy/0.1' as const;\n\n/**\n * Verification modes per VERIFIER-SECURITY-MODEL.md\n */\nexport const VERIFICATION_MODES = {\n /** All verification in browser/client, may fetch JWKS */\n clientSide: 'client_side' as const,\n /** No network access, uses bundled/pinned keys */\n offlineOnly: 'offline_only' as const,\n /** Prefer offline, fallback to network */\n offlinePreferred: 'offline_preferred' as const,\n /** Allow network fetches for key discovery */\n networkAllowed: 'network_allowed' as const,\n} as const;\n\n/**\n * All constants export\n */\nexport const CONSTANTS = {\n WIRE_TYPE,\n WIRE_VERSION,\n ALGORITHMS,\n HEADERS,\n DISCOVERY,\n JWKS,\n RECEIPT,\n LIMITS,\n BUNDLE_VERSION,\n VERIFICATION_REPORT_VERSION,\n HASH,\n VERIFIER_LIMITS,\n VERIFIER_NETWORK,\n VERIFIER_POLICY_VERSION,\n VERIFICATION_MODES,\n} as const;\n"]}
|