@peac/protocol 0.12.1 → 0.12.2
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/dist/index.cjs +58 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +60 -3
- package/dist/index.mjs.map +1 -1
- package/dist/issue.d.ts +1 -1
- package/dist/jwks-resolver.d.ts +2 -2
- package/dist/jwks-resolver.d.ts.map +1 -1
- package/dist/policy-binding.d.ts +4 -4
- package/dist/type-extension-check.d.ts +44 -0
- package/dist/type-extension-check.d.ts.map +1 -0
- package/dist/verifier-types.d.ts +2 -2
- package/dist/verify-local.cjs +57 -0
- package/dist/verify-local.cjs.map +1 -1
- package/dist/verify-local.d.ts +11 -5
- package/dist/verify-local.d.ts.map +1 -1
- package/dist/verify-local.mjs +59 -2
- package/dist/verify-local.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -2,9 +2,9 @@ import { uuidv7 } from 'uuidv7';
|
|
|
2
2
|
import { sign, signWire02, decode, verify, jcsHash, sha256Hex, computeJwkThumbprint, jwkToPublicKeyBytes, base64urlDecode } from '@peac/crypto';
|
|
3
3
|
export { base64urlDecode, base64urlEncode, computeJwkThumbprint, generateKeypair, jwkToPublicKeyBytes, sha256Bytes, sha256Hex, verify } from '@peac/crypto';
|
|
4
4
|
import { ZodError } from 'zod';
|
|
5
|
-
import { isValidPurposeToken, isCanonicalPurpose, isValidPurposeReason, isValidWorkflowContext, createWorkflowContextInvalidError, hasValidDagSemantics, createWorkflowDagInvalidError, WORKFLOW_EXTENSION_KEY, validateKernelConstraints, createConstraintViolationError, ReceiptClaims, createEvidenceNotJsonError, validateSubjectSnapshot, isCanonicalIss, Wire02ClaimsSchema, PEAC_ISSUER_CONFIG_MAX_BYTES, validateRevokedKeys, PEAC_ISSUER_CONFIG_PATH, PEAC_POLICY_MAX_BYTES, PEAC_POLICY_PATH, PEAC_POLICY_FALLBACK_PATH, WARNING_TYP_MISSING, parseReceiptClaims, checkOccurredAtSkew, REGISTERED_RECEIPT_TYPES, WARNING_TYPE_UNREGISTERED, REGISTERED_EXTENSION_GROUP_KEYS, isValidExtensionKey, WARNING_UNKNOWN_EXTENSION, verifyPolicyBinding, sortWarnings, PEAC_RECEIPT_HEADER, PEAC_PURPOSE_HEADER, parsePurposeHeader, PEAC_PURPOSE_APPLIED_HEADER, PEAC_PURPOSE_REASON_HEADER } from '@peac/schema';
|
|
5
|
+
import { isValidPurposeToken, isCanonicalPurpose, isValidPurposeReason, isValidWorkflowContext, createWorkflowContextInvalidError, hasValidDagSemantics, createWorkflowDagInvalidError, WORKFLOW_EXTENSION_KEY, validateKernelConstraints, createConstraintViolationError, ReceiptClaims, createEvidenceNotJsonError, validateSubjectSnapshot, isCanonicalIss, Wire02ClaimsSchema, PEAC_ISSUER_CONFIG_MAX_BYTES, validateRevokedKeys, PEAC_ISSUER_CONFIG_PATH, PEAC_POLICY_MAX_BYTES, PEAC_POLICY_PATH, PEAC_POLICY_FALLBACK_PATH, WARNING_TYP_MISSING, parseReceiptClaims, checkOccurredAtSkew, REGISTERED_RECEIPT_TYPES, WARNING_TYPE_UNREGISTERED, REGISTERED_EXTENSION_GROUP_KEYS, isValidExtensionKey, WARNING_UNKNOWN_EXTENSION, WARNING_EXTENSION_GROUP_MISSING, WARNING_EXTENSION_GROUP_MISMATCH, verifyPolicyBinding, sortWarnings, PEAC_RECEIPT_HEADER, PEAC_PURPOSE_HEADER, parsePurposeHeader, PEAC_PURPOSE_APPLIED_HEADER, PEAC_PURPOSE_REASON_HEADER } from '@peac/schema';
|
|
6
6
|
import { createHash } from 'crypto';
|
|
7
|
-
import { VERIFIER_LIMITS, VERIFIER_NETWORK, HASH, VERIFIER_POLICY_VERSION, VERIFICATION_REPORT_VERSION, WIRE_TYPE } from '@peac/kernel';
|
|
7
|
+
import { VERIFIER_LIMITS, VERIFIER_NETWORK, TYPE_TO_EXTENSION_MAP, HASH, VERIFIER_POLICY_VERSION, VERIFICATION_REPORT_VERSION, WIRE_TYPE } from '@peac/kernel';
|
|
8
8
|
|
|
9
9
|
// src/issue.ts
|
|
10
10
|
function fireTelemetryHook(fn, input) {
|
|
@@ -1392,6 +1392,35 @@ async function verifyReceipt(optionsOrJws) {
|
|
|
1392
1392
|
};
|
|
1393
1393
|
}
|
|
1394
1394
|
}
|
|
1395
|
+
|
|
1396
|
+
// src/type-extension-check.ts
|
|
1397
|
+
function checkTypeExtensionMapping(kind, type, extensions, typeToExtensionMap, registeredExtensionGroupKeys) {
|
|
1398
|
+
if (kind === "challenge") {
|
|
1399
|
+
return { status: "skip" };
|
|
1400
|
+
}
|
|
1401
|
+
const expectedGroup = typeToExtensionMap.get(type);
|
|
1402
|
+
if (expectedGroup === void 0) {
|
|
1403
|
+
return { status: "skip" };
|
|
1404
|
+
}
|
|
1405
|
+
if (extensions !== void 0 && Object.prototype.hasOwnProperty.call(extensions, expectedGroup)) {
|
|
1406
|
+
return { status: "ok" };
|
|
1407
|
+
}
|
|
1408
|
+
const presentRegistered = [];
|
|
1409
|
+
if (extensions !== void 0) {
|
|
1410
|
+
for (const key of Object.keys(extensions)) {
|
|
1411
|
+
if (key !== expectedGroup && registeredExtensionGroupKeys.has(key)) {
|
|
1412
|
+
presentRegistered.push(key);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
return {
|
|
1417
|
+
status: presentRegistered.length > 0 ? "mismatch" : "missing",
|
|
1418
|
+
expected_extension_group: expectedGroup,
|
|
1419
|
+
present_registered_extension_groups: presentRegistered
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
// src/verify-local.ts
|
|
1395
1424
|
function isCryptoError(err) {
|
|
1396
1425
|
return err !== null && typeof err === "object" && "name" in err && err.name === "CryptoError" && "code" in err && typeof err.code === "string" && err.code.startsWith("CRYPTO_") && "message" in err && typeof err.message === "string";
|
|
1397
1426
|
}
|
|
@@ -1518,6 +1547,34 @@ async function verifyLocal(jws, publicKey, options = {}) {
|
|
|
1518
1547
|
}
|
|
1519
1548
|
}
|
|
1520
1549
|
}
|
|
1550
|
+
const typeExtCheck = checkTypeExtensionMapping(
|
|
1551
|
+
claims.kind,
|
|
1552
|
+
claims.type,
|
|
1553
|
+
claims.extensions,
|
|
1554
|
+
TYPE_TO_EXTENSION_MAP,
|
|
1555
|
+
REGISTERED_EXTENSION_GROUP_KEYS
|
|
1556
|
+
);
|
|
1557
|
+
if (typeExtCheck.status === "missing" || typeExtCheck.status === "mismatch") {
|
|
1558
|
+
const warningCode = typeExtCheck.status === "missing" ? WARNING_EXTENSION_GROUP_MISSING : WARNING_EXTENSION_GROUP_MISMATCH;
|
|
1559
|
+
const errorCode = typeExtCheck.status === "missing" ? "E_EXTENSION_GROUP_REQUIRED" : "E_EXTENSION_GROUP_MISMATCH";
|
|
1560
|
+
if (strictness === "strict") {
|
|
1561
|
+
return {
|
|
1562
|
+
valid: false,
|
|
1563
|
+
code: errorCode,
|
|
1564
|
+
message: `Type "${claims.type}" expects extension group "${typeExtCheck.expected_extension_group}" but it is ${typeExtCheck.status === "mismatch" ? "replaced by a different registered group" : "absent"}`,
|
|
1565
|
+
details: {
|
|
1566
|
+
type: claims.type,
|
|
1567
|
+
expected_extension_group: typeExtCheck.expected_extension_group,
|
|
1568
|
+
present_registered_extension_groups: typeExtCheck.present_registered_extension_groups
|
|
1569
|
+
}
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
accumulatedWarnings.push({
|
|
1573
|
+
code: warningCode,
|
|
1574
|
+
message: `Type "${claims.type}" expects extension group "${typeExtCheck.expected_extension_group}"`,
|
|
1575
|
+
pointer: "/type"
|
|
1576
|
+
});
|
|
1577
|
+
}
|
|
1521
1578
|
if (policyDigest !== void 0 && !HASH.pattern.test(policyDigest)) {
|
|
1522
1579
|
return {
|
|
1523
1580
|
valid: false,
|
|
@@ -1854,7 +1911,7 @@ var VerificationReportBuilder = class {
|
|
|
1854
1911
|
reason,
|
|
1855
1912
|
severity: reasonCodeToSeverity(reason),
|
|
1856
1913
|
receipt_type: options?.receiptType ?? WIRE_TYPE,
|
|
1857
|
-
// Wire 0.1: always 'unavailable'
|
|
1914
|
+
// Wire 0.1: always 'unavailable'. Wire 0.2 will set this via options.
|
|
1858
1915
|
policy_binding: "unavailable",
|
|
1859
1916
|
...options?.issuer && { issuer: options.issuer },
|
|
1860
1917
|
...options?.kid && { kid: options.kid }
|