@tinycloud/sdk-core 2.11.0-beta.9 → 2.11.1-beta.0

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 (32) hide show
  1. package/dist/{capability-BA49Uboq.d.cts → capability-BjzXwtNw.d.cts} +1 -1
  2. package/dist/{capability-BA49Uboq.d.ts → capability-BjzXwtNw.d.ts} +1 -1
  3. package/dist/credential-admission-C_cO1QqB.d.cts +781 -0
  4. package/dist/credential-admission-cvHe-HUC.d.ts +781 -0
  5. package/dist/delegations/index.cjs +620 -221
  6. package/dist/delegations/index.cjs.map +1 -1
  7. package/dist/delegations/index.d.cts +32 -32
  8. package/dist/delegations/index.d.ts +32 -32
  9. package/dist/delegations/index.js +622 -223
  10. package/dist/delegations/index.js.map +1 -1
  11. package/dist/index.cjs +3162 -1255
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +348 -18
  14. package/dist/index.d.ts +348 -18
  15. package/dist/index.js +3959 -2050
  16. package/dist/index.js.map +1 -1
  17. package/dist/policy/index.cjs +1273 -175
  18. package/dist/policy/index.cjs.map +1 -1
  19. package/dist/policy/index.d.cts +5 -4
  20. package/dist/policy/index.d.ts +5 -4
  21. package/dist/policy/index.js +1274 -176
  22. package/dist/policy/index.js.map +1 -1
  23. package/dist/{recipient-types.schema-D5pDlIqn.d.cts → recipient-types.schema-G8NEKRoo.d.cts} +240 -183
  24. package/dist/{recipient-types.schema-D5pDlIqn.d.ts → recipient-types.schema-G8NEKRoo.d.ts} +240 -183
  25. package/dist/requester/index.cjs.map +1 -1
  26. package/dist/requester/index.d.cts +1 -1
  27. package/dist/requester/index.d.ts +1 -1
  28. package/dist/requester/index.js +1 -1
  29. package/dist/requester/index.js.map +1 -1
  30. package/package.json +5 -5
  31. package/dist/signed-object-B3dMzh8O.d.ts +0 -149
  32. package/dist/signed-object-DwPZl6kV.d.cts +0 -149
@@ -22,15 +22,37 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
22
22
  // src/policy/index.ts
23
23
  var policy_exports = {};
24
24
  __export(policy_exports, {
25
+ ATTESTED_ENFORCER_BINDING_V2_SCHEMA: () => ATTESTED_ENFORCER_BINDING_V2_SCHEMA,
26
+ CONTENT_SOURCE_V1_DOMAIN: () => CONTENT_SOURCE_V1_DOMAIN,
25
27
  ED25519_JCS_SIGNATURE_SUITE: () => ED25519_JCS_SIGNATURE_SUITE,
26
28
  EIP191_JCS_SIGNATURE_SUITE: () => EIP191_JCS_SIGNATURE_SUITE,
29
+ LAST_V2_CREATE_AT: () => LAST_V2_CREATE_AT,
30
+ LAST_V2_READ_AT: () => LAST_V2_READ_AT,
31
+ MAX_LEGACY_ENVELOPE_EXPIRES_AT: () => MAX_LEGACY_ENVELOPE_EXPIRES_AT,
32
+ NATIVE_PROJECTION_V1_DOMAIN: () => NATIVE_PROJECTION_V1_DOMAIN,
27
33
  OWNER_NODE_ENDPOINT_SCHEMA: () => OWNER_NODE_ENDPOINT_SCHEMA,
34
+ POLICY_CAPABILITY_V1_DOMAIN: () => POLICY_CAPABILITY_V1_DOMAIN,
35
+ POLICY_CAPABILITY_V1_SCHEMA: () => POLICY_CAPABILITY_V1_SCHEMA,
36
+ POLICY_CREDENTIAL_REQUIREMENT_V1_TYPE: () => POLICY_CREDENTIAL_REQUIREMENT_V1_TYPE,
37
+ POLICY_ENFORCEMENT_DELEGATION_V2_SCHEMA: () => POLICY_ENFORCEMENT_DELEGATION_V2_SCHEMA,
28
38
  POLICY_ENGINE_RECORD_SCHEMA: () => POLICY_ENGINE_RECORD_SCHEMA,
39
+ POLICY_PRESENTATION_V3_DOMAIN: () => POLICY_PRESENTATION_V3_DOMAIN,
40
+ POLICY_PRESENTATION_V3_SCHEMA: () => POLICY_PRESENTATION_V3_SCHEMA,
29
41
  POLICY_SCHEMA: () => POLICY_SCHEMA,
42
+ POLICY_SESSION_UCAN_V1_PROFILE: () => POLICY_SESSION_UCAN_V1_PROFILE,
30
43
  POLICY_STATUS_SCHEMA: () => POLICY_STATUS_SCHEMA,
44
+ POLICY_V1_DOMAIN: () => POLICY_V1_DOMAIN,
45
+ POLICY_V1_SCHEMA: () => POLICY_V1_SCHEMA,
46
+ POLICY_V2_DOMAIN: () => POLICY_V2_DOMAIN,
47
+ POLICY_V2_SCHEMA: () => POLICY_V2_SCHEMA,
31
48
  POLICY_VERSION_V0: () => POLICY_VERSION_V0,
32
49
  PolicyAuthoringError: () => PolicyAuthoringError,
33
50
  PolicyCapabilityError: () => PolicyCapabilityError,
51
+ ROOT_REVOCATION_V1_DOMAIN: () => ROOT_REVOCATION_V1_DOMAIN,
52
+ ROOT_REVOCATION_V1_SCHEMA: () => ROOT_REVOCATION_V1_SCHEMA,
53
+ ROOT_STATUS_CHECKPOINT_V1_SCHEMA: () => ROOT_STATUS_CHECKPOINT_V1_SCHEMA,
54
+ ROOT_STATUS_RENEWAL_V1_DOMAIN: () => ROOT_STATUS_RENEWAL_V1_DOMAIN,
55
+ ROOT_STATUS_V1_DOMAIN: () => ROOT_STATUS_V1_DOMAIN,
34
56
  SignatureMaterialError: () => SignatureMaterialError,
35
57
  SignatureVerificationError: () => SignatureVerificationError,
36
58
  SignedObjectCanonicalizationError: () => SignedObjectCanonicalizationError,
@@ -42,25 +64,53 @@ __export(policy_exports, {
42
64
  TRANSCRIPT_SHARE_BOOTSTRAP_SCHEMA: () => TRANSCRIPT_SHARE_BOOTSTRAP_SCHEMA,
43
65
  UnsupportedSignatureSuiteError: () => UnsupportedSignatureSuiteError,
44
66
  W3C_VC_CREDENTIAL_VERIFIER: () => W3C_VC_CREDENTIAL_VERIFIER,
67
+ admitPolicyCredentialV3: () => admitPolicyCredentialV3,
68
+ buildPolicyCredentialPresentationV3: () => buildPolicyCredentialPresentationV3,
45
69
  canonicalizePolicyCapability: () => canonicalizePolicyCapability,
46
70
  canonicalizeSignedObjectUnsigned: () => canonicalizeSignedObjectUnsigned,
71
+ canonicalizeUnifiedPolicyCapability: () => canonicalizeUnifiedPolicyCapability,
72
+ compactAttenuationContains: () => compactAttenuationContains,
47
73
  composeTranscriptShareBootstrap: () => composeTranscriptShareBootstrap,
74
+ contentSourceDigestHex: () => contentSourceDigestHex,
48
75
  createAndSignPolicy: () => createAndSignPolicy,
49
76
  createAndSignPolicyEngineRecord: () => createAndSignPolicyEngineRecord,
50
77
  createAndSignPolicyStatus: () => createAndSignPolicyStatus,
51
78
  createAndSignRequesterPolicyEngineRecord: () => createAndSignRequesterPolicyEngineRecord,
52
79
  createAndSignSignedObject: () => createAndSignSignedObject,
53
80
  createAndSignTranscriptSharePolicy: () => createAndSignTranscriptSharePolicy,
81
+ createCompactPolicyDescendant: () => createCompactPolicyDescendant,
82
+ createCompactPolicyInvocation: () => createCompactPolicyInvocation,
54
83
  createUnsignedPolicyEngineRecord: () => createUnsignedPolicyEngineRecord,
55
84
  deriveSignedObjectMaterial: () => deriveSignedObjectMaterial,
85
+ getPolicyRootStatusV3: () => getPolicyRootStatusV3,
56
86
  jcsCanonicalize: () => jcsCanonicalize,
87
+ mintPolicySessionV3: () => mintPolicySessionV3,
57
88
  normalizeJson: () => normalizeJson,
58
89
  normalizePolicyCapability: () => normalizePolicyCapability,
90
+ normalizeUnifiedPolicyCapability: () => normalizeUnifiedPolicyCapability,
91
+ parseCompactUcanAuthorization: () => parseCompactUcanAuthorization,
92
+ parsePolicySessionUcan: () => parsePolicySessionUcan,
59
93
  policyCapabilityContains: () => policyCapabilityContains,
60
94
  policyCapabilityDigestHex: () => policyCapabilityDigestHex,
95
+ policyCidFromCanonicalBytes: () => policyCidFromCanonicalBytes,
96
+ policyDigestHex: () => policyDigestHex,
97
+ policyIdForDigestHex: () => policyIdForDigestHex,
98
+ policyV2DigestHex: () => policyV2DigestHex,
99
+ projectUnifiedPolicyCapabilities: () => projectUnifiedPolicyCapabilities,
100
+ projectUnifiedPolicyCapability: () => projectUnifiedPolicyCapability,
101
+ renewPolicyRootStatusV3: () => renewPolicyRootStatusV3,
102
+ requestPolicyChallengeV3: () => requestPolicyChallengeV3,
103
+ revokePolicyRootV3: () => revokePolicyRootV3,
61
104
  serializeJcsJson: () => serialize,
105
+ signCompactUcanAuthorization: () => signCompactUcanAuthorization,
106
+ signCompactUcanRootAuthorization: () => signCompactUcanRootAuthorization,
62
107
  signedObjectIdFor: () => signedObjectIdFor,
63
108
  toSignedObjectError: () => toSignedObjectError,
109
+ unifiedNativeProjectionHashHex: () => unifiedNativeProjectionHashHex,
110
+ unifiedPolicyCapabilityContains: () => unifiedPolicyCapabilityContains,
111
+ unifiedPolicyCapabilityDigestHex: () => unifiedPolicyCapabilityDigestHex,
112
+ unifiedPolicyCapabilityFromNative: () => unifiedPolicyCapabilityFromNative,
113
+ validatePolicyCredentialRequirementV1: () => validatePolicyCredentialRequirementV1,
64
114
  validatePolicyEngineRecordSigned: () => validatePolicyEngineRecordSigned,
65
115
  validatePolicyEngineRecordSignedShape: () => validatePolicyEngineRecordSignedShape,
66
116
  validatePolicyEngineRecordUnsigned: () => validatePolicyEngineRecordUnsigned,
@@ -70,9 +120,12 @@ __export(policy_exports, {
70
120
  validatePolicyStatusSignedShape: () => validatePolicyStatusSignedShape,
71
121
  validatePolicyStatusUnsigned: () => validatePolicyStatusUnsigned,
72
122
  validatePolicyUnsigned: () => validatePolicyUnsigned,
123
+ validateUnifiedPolicyV2: () => validateUnifiedPolicyV2,
73
124
  verifyPolicy: () => verifyPolicy,
74
125
  verifyPolicyEngineRecord: () => verifyPolicyEngineRecord,
75
126
  verifyPolicyEngineRecordForRequester: () => verifyPolicyEngineRecordForRequester,
127
+ verifyPolicyRootRevocationV3: () => verifyPolicyRootRevocationV3,
128
+ verifyPolicyRootStatusCheckpointV3: () => verifyPolicyRootStatusCheckpointV3,
76
129
  verifyPolicyStatus: () => verifyPolicyStatus,
77
130
  verifySignedObject: () => verifySignedObject
78
131
  });
@@ -395,16 +448,16 @@ function policyCapabilityContains(authority, request) {
395
448
  return caveatsContain(auth.caveats, req.caveats);
396
449
  }
397
450
  function normalizePolicyCapabilityWithOptions(input, options) {
398
- const object = expectObject(input, "$");
399
- assertExactKeys(object, ["service", "space", "path", "actions", "caveats"], "$");
400
- const service = requiredString(object, "service", "$", "policy-capability-malformed-service");
451
+ const object2 = expectObject(input, "$");
452
+ assertExactKeys(object2, ["service", "space", "path", "actions", "caveats"], "$");
453
+ const service = requiredString(object2, "service", "$", "policy-capability-malformed-service");
401
454
  if (!CEILING_SERVICES.has(service)) {
402
455
  throw new PolicyCapabilityError(
403
456
  "policy-capability-malformed-service",
404
457
  "$.service is outside the frozen permissionsCeiling vocabulary"
405
458
  );
406
459
  }
407
- const space = requiredString(object, "space", "$", "policy-capability-malformed-space");
460
+ const space = requiredString(object2, "space", "$", "policy-capability-malformed-space");
408
461
  validateConcreteSpace(space);
409
462
  const canonicalSpace = space.normalize("NFC");
410
463
  if (options.requireCanonical && canonicalSpace !== space) {
@@ -413,7 +466,7 @@ function normalizePolicyCapabilityWithOptions(input, options) {
413
466
  "$.space must already be canonical NFC"
414
467
  );
415
468
  }
416
- const rawPath = requiredString(object, "path", "$", "policy-capability-malformed-path");
469
+ const rawPath = requiredString(object2, "path", "$", "policy-capability-malformed-path");
417
470
  validateRawPath(rawPath, options);
418
471
  const path = normalizePath(rawPath);
419
472
  if (options.requireCanonical && path !== rawPath) {
@@ -424,7 +477,7 @@ function normalizePolicyCapabilityWithOptions(input, options) {
424
477
  }
425
478
  validateRawPath(path, options);
426
479
  const actions = normalizeActions(
427
- requiredArray(object, "actions", "$", "policy-capability-malformed-action"),
480
+ requiredArray(object2, "actions", "$", "policy-capability-malformed-action"),
428
481
  service,
429
482
  options
430
483
  );
@@ -433,9 +486,9 @@ function normalizePolicyCapabilityWithOptions(input, options) {
433
486
  output.space = canonicalSpace;
434
487
  output.path = path;
435
488
  output.actions = actions;
436
- if (hasOwn(object, "caveats")) {
489
+ if (hasOwn(object2, "caveats")) {
437
490
  output.caveats = validateCaveats(
438
- requiredValue(object, "caveats", "$", "policy-capability-malformed-caveats"),
491
+ requiredValue(object2, "caveats", "$", "policy-capability-malformed-caveats"),
439
492
  output.service
440
493
  );
441
494
  }
@@ -458,9 +511,9 @@ function expectObject(input, path) {
458
511
  );
459
512
  }
460
513
  }
461
- function assertExactKeys(object, allowed, path) {
514
+ function assertExactKeys(object2, allowed, path) {
462
515
  const allowedSet = new Set(allowed);
463
- for (const key of Object.keys(object)) {
516
+ for (const key of Object.keys(object2)) {
464
517
  if (!allowedSet.has(key)) {
465
518
  throw new PolicyCapabilityError(
466
519
  key === "id" || key === "scope" ? "policy-capability-malformed" : "policy-capability-unknown-key",
@@ -469,21 +522,21 @@ function assertExactKeys(object, allowed, path) {
469
522
  }
470
523
  }
471
524
  }
472
- function requiredValue(object, key, path, code2) {
473
- if (!hasOwn(object, key)) {
525
+ function requiredValue(object2, key, path, code2) {
526
+ if (!hasOwn(object2, key)) {
474
527
  throw new PolicyCapabilityError(code2, `${path}.${key} is required`);
475
528
  }
476
- return object[key];
529
+ return object2[key];
477
530
  }
478
- function requiredString(object, key, path, code2) {
479
- const value = requiredValue(object, key, path, code2);
531
+ function requiredString(object2, key, path, code2) {
532
+ const value = requiredValue(object2, key, path, code2);
480
533
  if (typeof value !== "string" || value.length === 0) {
481
534
  throw new PolicyCapabilityError(code2, `${path}.${key} must be a non-empty string`);
482
535
  }
483
536
  return value;
484
537
  }
485
- function requiredArray(object, key, path, code2) {
486
- const value = requiredValue(object, key, path, code2);
538
+ function requiredArray(object2, key, path, code2) {
539
+ const value = requiredValue(object2, key, path, code2);
487
540
  if (!Array.isArray(value)) {
488
541
  throw new PolicyCapabilityError(code2, `${path}.${key} must be an array`);
489
542
  }
@@ -628,11 +681,11 @@ function validateSqlStatement(input, path) {
628
681
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
629
682
  throw new PolicyCapabilityError("policy-capability-malformed-caveats", `${path} must be an object`);
630
683
  }
631
- const object = input;
632
- assertCaveatKeys(object, ["name", "sql", "fixedParams"], path);
633
- caveatString(object, "name", path);
634
- caveatString(object, "sql", path);
635
- const fixedParams = requiredCaveat(object, "fixedParams", path);
684
+ const object2 = input;
685
+ assertCaveatKeys(object2, ["name", "sql", "fixedParams"], path);
686
+ caveatString(object2, "name", path);
687
+ caveatString(object2, "sql", path);
688
+ const fixedParams = requiredCaveat(object2, "fixedParams", path);
636
689
  if (!Array.isArray(fixedParams)) {
637
690
  throw new PolicyCapabilityError(
638
691
  "policy-capability-malformed-caveats",
@@ -647,20 +700,20 @@ function validateFixedParam(input, path) {
647
700
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
648
701
  throw new PolicyCapabilityError("policy-capability-malformed-caveats", `${path} must be an object`);
649
702
  }
650
- const object = input;
651
- assertCaveatKeys(object, ["index", "value"], path);
652
- const index = requiredCaveat(object, "index", path);
703
+ const object2 = input;
704
+ assertCaveatKeys(object2, ["index", "value"], path);
705
+ const index = requiredCaveat(object2, "index", path);
653
706
  if (typeof index !== "number" || !Number.isSafeInteger(index) || index < 0) {
654
707
  throw new PolicyCapabilityError(
655
708
  "policy-capability-malformed-caveats",
656
709
  `${path}.index must be a non-negative integer`
657
710
  );
658
711
  }
659
- requiredCaveat(object, "value", path);
712
+ requiredCaveat(object2, "value", path);
660
713
  }
661
- function assertCaveatKeys(object, allowed, path) {
714
+ function assertCaveatKeys(object2, allowed, path) {
662
715
  const allowedSet = new Set(allowed);
663
- for (const key of Object.keys(object)) {
716
+ for (const key of Object.keys(object2)) {
664
717
  if (!allowedSet.has(key)) {
665
718
  throw new PolicyCapabilityError(
666
719
  "policy-capability-malformed-caveats",
@@ -669,17 +722,17 @@ function assertCaveatKeys(object, allowed, path) {
669
722
  }
670
723
  }
671
724
  }
672
- function requiredCaveat(object, key, path) {
673
- if (!hasOwn(object, key)) {
725
+ function requiredCaveat(object2, key, path) {
726
+ if (!hasOwn(object2, key)) {
674
727
  throw new PolicyCapabilityError(
675
728
  "policy-capability-malformed-caveats",
676
729
  `${path}.${key} is required`
677
730
  );
678
731
  }
679
- return object[key];
732
+ return object2[key];
680
733
  }
681
- function caveatString(object, key, path) {
682
- const value = requiredCaveat(object, key, path);
734
+ function caveatString(object2, key, path) {
735
+ const value = requiredCaveat(object2, key, path);
683
736
  if (typeof value !== "string" || value.length === 0) {
684
737
  throw new PolicyCapabilityError(
685
738
  "policy-capability-malformed-caveats",
@@ -710,8 +763,8 @@ function caveatsContain(authority, request) {
710
763
  (statement) => authorityStatements.some((candidate) => jcsCanonicalize(candidate) === jcsCanonicalize(statement))
711
764
  );
712
765
  }
713
- function hasOwn(object, key) {
714
- return objectHasOwn2(object, key);
766
+ function hasOwn(object2, key) {
767
+ return objectHasOwn2(object2, key);
715
768
  }
716
769
 
717
770
  // src/policy/signed-object.ts
@@ -1981,17 +2034,17 @@ async function createAndSignSignedObject(input, signer) {
1981
2034
  }
1982
2035
  function createAndSignPolicy(input, signer) {
1983
2036
  return createAndSignSignedObject(input, signer).then(
1984
- (object) => validatePolicySignedShape(object)
2037
+ (object2) => validatePolicySignedShape(object2)
1985
2038
  );
1986
2039
  }
1987
2040
  function createAndSignPolicyStatus(input, signer) {
1988
2041
  return createAndSignSignedObject(input, signer).then(
1989
- (object) => validatePolicyStatusSignedShape(object)
2042
+ (object2) => validatePolicyStatusSignedShape(object2)
1990
2043
  );
1991
2044
  }
1992
2045
  function createAndSignPolicyEngineRecord(input, signer) {
1993
2046
  return createAndSignSignedObject(input, signer).then(
1994
- (object) => validatePolicyEngineRecordSignedShape(object)
2047
+ (object2) => validatePolicyEngineRecordSignedShape(object2)
1995
2048
  );
1996
2049
  }
1997
2050
  async function verifySignedObject(input) {
@@ -2095,9 +2148,9 @@ function validateUnsignedForDescriptor(input, descriptor) {
2095
2148
  }
2096
2149
  }
2097
2150
  function validatePolicyShape(input, signed) {
2098
- const object = expectJsonObject(normalizeJson(input), "$");
2151
+ const object2 = expectJsonObject(normalizeJson(input), "$");
2099
2152
  assertExactKeys2(
2100
- object,
2153
+ object2,
2101
2154
  signed ? [
2102
2155
  "schema",
2103
2156
  "policyId",
@@ -2125,30 +2178,30 @@ function validatePolicyShape(input, signed) {
2125
2178
  ],
2126
2179
  "$"
2127
2180
  );
2128
- expectConst(requiredString2(object, "schema", "$"), POLICY_SCHEMA, "$.schema");
2181
+ expectConst(requiredString2(object2, "schema", "$"), POLICY_SCHEMA, "$.schema");
2129
2182
  if (signed) {
2130
- requiredString2(object, "policyId", "$");
2131
- validateSignature(requiredValue2(object, "signature", "$"));
2183
+ requiredString2(object2, "policyId", "$");
2184
+ validateSignature(requiredValue2(object2, "signature", "$"));
2132
2185
  }
2133
- requiredString2(object, "ownerDid", "$");
2134
- requiredString2(object, "signingKeyDid", "$");
2135
- requiredDateString(object, "createdAt", "$");
2136
- optionalDateString(object, "expiresAt", "$");
2137
- validatePolicyResource(requiredValue2(object, "resource", "$"), "$.resource");
2138
- validateExpression(requiredValue2(object, "when", "$"), "$.when");
2139
- validateGrant(requiredValue2(object, "grant", "$"), "$.grant");
2140
- if (hasOwn2(object, "disclosure")) {
2141
- validateDisclosure(requiredValue2(object, "disclosure", "$"), "$.disclosure");
2186
+ requiredString2(object2, "ownerDid", "$");
2187
+ requiredString2(object2, "signingKeyDid", "$");
2188
+ requiredDateString(object2, "createdAt", "$");
2189
+ optionalDateString(object2, "expiresAt", "$");
2190
+ validatePolicyResource(requiredValue2(object2, "resource", "$"), "$.resource");
2191
+ validateExpression(requiredValue2(object2, "when", "$"), "$.when");
2192
+ validateGrant(requiredValue2(object2, "grant", "$"), "$.grant");
2193
+ if (hasOwn2(object2, "disclosure")) {
2194
+ validateDisclosure(requiredValue2(object2, "disclosure", "$"), "$.disclosure");
2142
2195
  }
2143
- if (hasOwn2(object, "audit")) {
2144
- validateAudit(requiredValue2(object, "audit", "$"), "$.audit");
2196
+ if (hasOwn2(object2, "audit")) {
2197
+ validateAudit(requiredValue2(object2, "audit", "$"), "$.audit");
2145
2198
  }
2146
- return object;
2199
+ return object2;
2147
2200
  }
2148
2201
  function validatePolicyStatusShape(input, signed) {
2149
- const object = expectJsonObject(normalizeJson(input), "$");
2202
+ const object2 = expectJsonObject(normalizeJson(input), "$");
2150
2203
  assertExactKeys2(
2151
- object,
2204
+ object2,
2152
2205
  signed ? [
2153
2206
  "schema",
2154
2207
  "statusId",
@@ -2172,28 +2225,28 @@ function validatePolicyStatusShape(input, signed) {
2172
2225
  ],
2173
2226
  "$"
2174
2227
  );
2175
- expectConst(requiredString2(object, "schema", "$"), POLICY_STATUS_SCHEMA, "$.schema");
2228
+ expectConst(requiredString2(object2, "schema", "$"), POLICY_STATUS_SCHEMA, "$.schema");
2176
2229
  if (signed) {
2177
- requiredString2(object, "statusId", "$");
2178
- validateSignature(requiredValue2(object, "signature", "$"));
2230
+ requiredString2(object2, "statusId", "$");
2231
+ validateSignature(requiredValue2(object2, "signature", "$"));
2179
2232
  }
2180
- requiredString2(object, "policyId", "$");
2181
- requiredString2(object, "ownerDid", "$");
2182
- requiredInteger(object, "sequence", "$", 0);
2183
- expectOneOf(requiredString2(object, "disposition", "$"), [
2233
+ requiredString2(object2, "policyId", "$");
2234
+ requiredString2(object2, "ownerDid", "$");
2235
+ requiredInteger(object2, "sequence", "$", 0);
2236
+ expectOneOf(requiredString2(object2, "disposition", "$"), [
2184
2237
  "active",
2185
2238
  "suspended",
2186
2239
  "revoked"
2187
2240
  ], "$.disposition");
2188
- requiredDateString(object, "effectiveAt", "$");
2189
- optionalString(object, "reasonCode", "$");
2190
- requiredString2(object, "signingKeyDid", "$");
2191
- return object;
2241
+ requiredDateString(object2, "effectiveAt", "$");
2242
+ optionalString(object2, "reasonCode", "$");
2243
+ requiredString2(object2, "signingKeyDid", "$");
2244
+ return object2;
2192
2245
  }
2193
2246
  function validatePolicyEngineRecordShape(input, signed) {
2194
- const object = expectJsonObject(normalizeJson(input), "$");
2247
+ const object2 = expectJsonObject(normalizeJson(input), "$");
2195
2248
  assertExactKeys2(
2196
- object,
2249
+ object2,
2197
2250
  signed ? [
2198
2251
  "schema",
2199
2252
  "engineRecordId",
@@ -2218,44 +2271,44 @@ function validatePolicyEngineRecordShape(input, signed) {
2218
2271
  "$"
2219
2272
  );
2220
2273
  expectConst(
2221
- requiredString2(object, "schema", "$"),
2274
+ requiredString2(object2, "schema", "$"),
2222
2275
  POLICY_ENGINE_RECORD_SCHEMA,
2223
2276
  "$.schema"
2224
2277
  );
2225
2278
  if (signed) {
2226
- requiredString2(object, "engineRecordId", "$");
2227
- validateSignature(requiredValue2(object, "signature", "$"));
2279
+ requiredString2(object2, "engineRecordId", "$");
2280
+ validateSignature(requiredValue2(object2, "signature", "$"));
2228
2281
  }
2229
- requiredString2(object, "ownerDid", "$");
2230
- requiredString2(object, "endpoint", "$");
2231
- requiredString2(object, "audience", "$");
2282
+ requiredString2(object2, "ownerDid", "$");
2283
+ requiredString2(object2, "endpoint", "$");
2284
+ requiredString2(object2, "audience", "$");
2232
2285
  requiredStringArray(
2233
- object,
2286
+ object2,
2234
2287
  "supportedPolicyVersions",
2235
2288
  "$",
2236
2289
  (value, path) => expectConst(value, "v0", path)
2237
2290
  );
2238
- requiredStringArray(object, "supportedEvidenceVerifiers", "$");
2239
- requiredString2(object, "grantIssuerDid", "$");
2240
- requiredDateString(object, "expiresAt", "$");
2241
- return object;
2291
+ requiredStringArray(object2, "supportedEvidenceVerifiers", "$");
2292
+ requiredString2(object2, "grantIssuerDid", "$");
2293
+ requiredDateString(object2, "expiresAt", "$");
2294
+ return object2;
2242
2295
  }
2243
2296
  function validateSignature(input) {
2244
- const object = expectJsonObject(input, "$.signature");
2245
- assertExactKeys2(object, ["suite", "signerDid", "value"], "$.signature");
2246
- const suite = requiredString2(object, "suite", "$.signature");
2297
+ const object2 = expectJsonObject(input, "$.signature");
2298
+ assertExactKeys2(object2, ["suite", "signerDid", "value"], "$.signature");
2299
+ const suite = requiredString2(object2, "suite", "$.signature");
2247
2300
  assertSupportedSignatureSuite(suite);
2248
- const signerDid = requiredString2(object, "signerDid", "$.signature");
2249
- const value = requiredString2(object, "value", "$.signature");
2301
+ const signerDid = requiredString2(object2, "signerDid", "$.signature");
2302
+ const value = requiredString2(object2, "value", "$.signature");
2250
2303
  decodeSignatureValue(value, suite);
2251
2304
  return { suite, signerDid, value };
2252
2305
  }
2253
2306
  function validatePolicyResource(input, path) {
2254
- const object = expectJsonObject(input, path);
2255
- assertExactKeys2(object, ["resourceType", "resourceId", "permissionsCeiling"], path);
2256
- requiredString2(object, "resourceType", path);
2257
- requiredString2(object, "resourceId", path);
2258
- const ceiling = requiredArray2(object, "permissionsCeiling", path, 1);
2307
+ const object2 = expectJsonObject(input, path);
2308
+ assertExactKeys2(object2, ["resourceType", "resourceId", "permissionsCeiling"], path);
2309
+ requiredString2(object2, "resourceType", path);
2310
+ requiredString2(object2, "resourceId", path);
2311
+ const ceiling = requiredArray2(object2, "permissionsCeiling", path, 1);
2259
2312
  for (let index = 0; index < ceiling.length; index++) {
2260
2313
  validatePolicyCapability(ceiling[index], `${path}.permissionsCeiling[${index}]`);
2261
2314
  }
@@ -2271,10 +2324,10 @@ function validatePolicyPermissionsCeilingForSigning(input) {
2271
2324
  }
2272
2325
  }
2273
2326
  function validatePolicyCapability(input, path) {
2274
- const object = expectJsonObject(input, path);
2327
+ const object2 = expectJsonObject(input, path);
2275
2328
  try {
2276
- const canonical = canonicalizePolicyCapability(object);
2277
- if (jcsCanonicalize(object) !== jcsCanonicalize(canonical)) {
2329
+ const canonical = canonicalizePolicyCapability(object2);
2330
+ if (jcsCanonicalize(object2) !== jcsCanonicalize(canonical)) {
2278
2331
  throw new SignedObjectSchemaError(`${path} must be canonical PolicyCapability JSON`);
2279
2332
  }
2280
2333
  } catch (error) {
@@ -2287,10 +2340,10 @@ function validatePolicyCapability(input, path) {
2287
2340
  }
2288
2341
  }
2289
2342
  function validatePolicyCapabilityForSigning(input, path) {
2290
- const object = expectJsonObject(input, path);
2343
+ const object2 = expectJsonObject(input, path);
2291
2344
  try {
2292
- const canonical = normalizePolicyCapability(object);
2293
- if (jcsCanonicalize(object) !== jcsCanonicalize(canonical)) {
2345
+ const canonical = normalizePolicyCapability(object2);
2346
+ if (jcsCanonicalize(object2) !== jcsCanonicalize(canonical)) {
2294
2347
  throw new SignedObjectSchemaError(`${path} must be strict canonical PolicyCapability JSON`);
2295
2348
  }
2296
2349
  } catch (error) {
@@ -2303,43 +2356,43 @@ function validatePolicyCapabilityForSigning(input, path) {
2303
2356
  }
2304
2357
  }
2305
2358
  function validateExpression(input, path) {
2306
- const object = expectJsonObject(input, path);
2307
- const keys = Object.keys(object);
2359
+ const object2 = expectJsonObject(input, path);
2360
+ const keys = Object.keys(object2);
2308
2361
  if (keys.length !== 1) {
2309
2362
  throw new SignedObjectSchemaError(`${path} must have exactly one expression key`);
2310
2363
  }
2311
2364
  const key = keys[0];
2312
2365
  if (key === "allOf" || key === "anyOf") {
2313
- const values = requiredArray2(object, key, path, 1);
2366
+ const values = requiredArray2(object2, key, path, 1);
2314
2367
  for (let index = 0; index < values.length; index++) {
2315
2368
  validateExpression(values[index], `${path}.${key}[${index}]`);
2316
2369
  }
2317
2370
  return;
2318
2371
  }
2319
2372
  if (key === "subject") {
2320
- const subject = expectJsonObject(requiredValue2(object, "subject", path), `${path}.subject`);
2373
+ const subject = expectJsonObject(requiredValue2(object2, "subject", path), `${path}.subject`);
2321
2374
  assertExactKeys2(subject, ["did"], `${path}.subject`);
2322
2375
  requiredString2(subject, "did", `${path}.subject`);
2323
2376
  return;
2324
2377
  }
2325
2378
  if (key === "evidence") {
2326
- validateEvidenceRequirement(requiredValue2(object, "evidence", path), `${path}.evidence`);
2379
+ validateEvidenceRequirement(requiredValue2(object2, "evidence", path), `${path}.evidence`);
2327
2380
  return;
2328
2381
  }
2329
2382
  throw new SignedObjectSchemaError(`${path} has unknown expression key ${key}`);
2330
2383
  }
2331
2384
  function validateEvidenceRequirement(input, path) {
2332
- const object = expectJsonObject(input, path);
2385
+ const object2 = expectJsonObject(input, path);
2333
2386
  assertExactKeys2(
2334
- object,
2387
+ object2,
2335
2388
  ["requirementId", "verifier", "requirements", "authority", "freshness"],
2336
2389
  path
2337
2390
  );
2338
- requiredString2(object, "requirementId", path);
2339
- requiredString2(object, "verifier", path);
2340
- requiredValue2(object, "requirements", path);
2341
- if (hasOwn2(object, "authority")) {
2342
- const authority = expectJsonObject(requiredValue2(object, "authority", path), `${path}.authority`);
2391
+ requiredString2(object2, "requirementId", path);
2392
+ requiredString2(object2, "verifier", path);
2393
+ requiredValue2(object2, "requirements", path);
2394
+ if (hasOwn2(object2, "authority")) {
2395
+ const authority = expectJsonObject(requiredValue2(object2, "authority", path), `${path}.authority`);
2343
2396
  assertExactKeys2(
2344
2397
  authority,
2345
2398
  ["profile", "acceptedIssuers", "allowOwnerAuthorizedIssuer"],
@@ -2351,35 +2404,35 @@ function validateEvidenceRequirement(input, path) {
2351
2404
  }
2352
2405
  optionalBoolean(authority, "allowOwnerAuthorizedIssuer", `${path}.authority`);
2353
2406
  }
2354
- if (hasOwn2(object, "freshness")) {
2355
- const freshness = expectJsonObject(requiredValue2(object, "freshness", path), `${path}.freshness`);
2407
+ if (hasOwn2(object2, "freshness")) {
2408
+ const freshness = expectJsonObject(requiredValue2(object2, "freshness", path), `${path}.freshness`);
2356
2409
  assertExactKeys2(freshness, ["maxStatusAgeSeconds"], `${path}.freshness`);
2357
2410
  requiredInteger(freshness, "maxStatusAgeSeconds", `${path}.freshness`, 0);
2358
2411
  }
2359
2412
  }
2360
2413
  function validateGrant(input, path) {
2361
- const object = expectJsonObject(input, path);
2362
- assertExactKeys2(object, ["output", "maxTtlSeconds", "delegationMode", "revocation"], path);
2363
- expectConst(requiredString2(object, "output", path), "portable-delegation", `${path}.output`);
2364
- requiredInteger(object, "maxTtlSeconds", path, 1);
2365
- expectOneOf(requiredString2(object, "delegationMode", path), [
2414
+ const object2 = expectJsonObject(input, path);
2415
+ assertExactKeys2(object2, ["output", "maxTtlSeconds", "delegationMode", "revocation"], path);
2416
+ expectConst(requiredString2(object2, "output", path), "portable-delegation", `${path}.output`);
2417
+ requiredInteger(object2, "maxTtlSeconds", path, 1);
2418
+ expectOneOf(requiredString2(object2, "delegationMode", path), [
2366
2419
  "terminal",
2367
2420
  "attenuable"
2368
2421
  ], `${path}.delegationMode`);
2369
- expectOneOf(requiredString2(object, "revocation", path), [
2422
+ expectOneOf(requiredString2(object2, "revocation", path), [
2370
2423
  "refresh_only",
2371
2424
  "active_cutoff"
2372
2425
  ], `${path}.revocation`);
2373
2426
  }
2374
2427
  function validateDisclosure(input, path) {
2375
- const object = expectJsonObject(input, path);
2376
- assertExactKeys2(object, ["denial"], path);
2377
- expectOneOf(requiredString2(object, "denial", path), ["none", "code", "debug"], `${path}.denial`);
2428
+ const object2 = expectJsonObject(input, path);
2429
+ assertExactKeys2(object2, ["denial"], path);
2430
+ expectOneOf(requiredString2(object2, "denial", path), ["none", "code", "debug"], `${path}.denial`);
2378
2431
  }
2379
2432
  function validateAudit(input, path) {
2380
- const object = expectJsonObject(input, path);
2381
- assertExactKeys2(object, ["issuance"], path);
2382
- expectOneOf(requiredString2(object, "issuance", path), ["off", "security", "full"], `${path}.issuance`);
2433
+ const object2 = expectJsonObject(input, path);
2434
+ assertExactKeys2(object2, ["issuance"], path);
2435
+ expectOneOf(requiredString2(object2, "issuance", path), ["off", "security", "full"], `${path}.issuance`);
2383
2436
  }
2384
2437
  function materialForUnsigned(unsigned, descriptor) {
2385
2438
  const jcs = jcsCanonicalize(unsigned);
@@ -2528,9 +2581,9 @@ function encodeSignatureValue(value, suite) {
2528
2581
  decodeSignatureValue(encoded, suite);
2529
2582
  return encoded;
2530
2583
  }
2531
- function stripOwnIdAndSignature(object, descriptor) {
2584
+ function stripOwnIdAndSignature(object2, descriptor) {
2532
2585
  const output = /* @__PURE__ */ Object.create(null);
2533
- for (const [key, value] of Object.entries(object)) {
2586
+ for (const [key, value] of Object.entries(object2)) {
2534
2587
  if (key === descriptor.idField || key === "signature") {
2535
2588
  continue;
2536
2589
  }
@@ -2539,8 +2592,8 @@ function stripOwnIdAndSignature(object, descriptor) {
2539
2592
  return output;
2540
2593
  }
2541
2594
  function descriptorForUnsigned(input) {
2542
- const object = expectJsonObject(normalizeJson(input), "$");
2543
- return descriptorForSchema(requiredString2(object, "schema", "$"));
2595
+ const object2 = expectJsonObject(normalizeJson(input), "$");
2596
+ return descriptorForSchema(requiredString2(object2, "schema", "$"));
2544
2597
  }
2545
2598
  function descriptorForSchema(schema) {
2546
2599
  if (schema === POLICY_SCHEMA) return DESCRIPTORS.Policy;
@@ -2554,28 +2607,28 @@ function expectJsonObject(input, path) {
2554
2607
  }
2555
2608
  return input;
2556
2609
  }
2557
- function assertExactKeys2(object, allowed, path) {
2610
+ function assertExactKeys2(object2, allowed, path) {
2558
2611
  const allowedSet = new Set(allowed);
2559
- for (const key of Object.keys(object)) {
2612
+ for (const key of Object.keys(object2)) {
2560
2613
  if (!allowedSet.has(key)) {
2561
2614
  throw new SignedObjectSchemaError(`${path} has unknown field ${key}`);
2562
2615
  }
2563
2616
  }
2564
2617
  }
2565
- function requiredValue2(object, key, path) {
2566
- if (!hasOwn2(object, key)) {
2618
+ function requiredValue2(object2, key, path) {
2619
+ if (!hasOwn2(object2, key)) {
2567
2620
  throw new SignedObjectSchemaError(`${path}.${key} is required`);
2568
2621
  }
2569
- return object[key];
2622
+ return object2[key];
2570
2623
  }
2571
- function requiredString2(object, key, path) {
2572
- return requireStringType(requiredValue2(object, key, path), `${path}.${key}`);
2624
+ function requiredString2(object2, key, path) {
2625
+ return requireStringType(requiredValue2(object2, key, path), `${path}.${key}`);
2573
2626
  }
2574
- function optionalString(object, key, path) {
2575
- if (!hasOwn2(object, key)) {
2627
+ function optionalString(object2, key, path) {
2628
+ if (!hasOwn2(object2, key)) {
2576
2629
  return;
2577
2630
  }
2578
- requireStringType(requiredValue2(object, key, path), `${path}.${key}`);
2631
+ requireStringType(requiredValue2(object2, key, path), `${path}.${key}`);
2579
2632
  }
2580
2633
  function requireStringType(value, path) {
2581
2634
  if (typeof value !== "string" || value.length === 0) {
@@ -2583,16 +2636,16 @@ function requireStringType(value, path) {
2583
2636
  }
2584
2637
  return value;
2585
2638
  }
2586
- function optionalBoolean(object, key, path) {
2587
- if (!hasOwn2(object, key)) {
2639
+ function optionalBoolean(object2, key, path) {
2640
+ if (!hasOwn2(object2, key)) {
2588
2641
  return;
2589
2642
  }
2590
- if (typeof requiredValue2(object, key, path) !== "boolean") {
2643
+ if (typeof requiredValue2(object2, key, path) !== "boolean") {
2591
2644
  throw new SignedObjectSchemaError(`${path}.${key} must be a boolean`);
2592
2645
  }
2593
2646
  }
2594
- function requiredInteger(object, key, path, minimum) {
2595
- const value = requiredValue2(object, key, path);
2647
+ function requiredInteger(object2, key, path, minimum) {
2648
+ const value = requiredValue2(object2, key, path);
2596
2649
  if (typeof value !== "number" || !Number.isSafeInteger(value) || value < minimum) {
2597
2650
  throw new SignedObjectSchemaError(
2598
2651
  `${path}.${key} must be an integer >= ${minimum}`
@@ -2600,8 +2653,8 @@ function requiredInteger(object, key, path, minimum) {
2600
2653
  }
2601
2654
  return value;
2602
2655
  }
2603
- function requiredArray2(object, key, path, minimum) {
2604
- const value = requiredValue2(object, key, path);
2656
+ function requiredArray2(object2, key, path, minimum) {
2657
+ const value = requiredValue2(object2, key, path);
2605
2658
  if (!Array.isArray(value) || value.length < minimum) {
2606
2659
  throw new SignedObjectSchemaError(
2607
2660
  `${path}.${key} must be an array with at least ${minimum} item(s)`
@@ -2609,22 +2662,22 @@ function requiredArray2(object, key, path, minimum) {
2609
2662
  }
2610
2663
  return value;
2611
2664
  }
2612
- function requiredStringArray(object, key, path, check) {
2613
- const values = requiredArray2(object, key, path, 0);
2665
+ function requiredStringArray(object2, key, path, check) {
2666
+ const values = requiredArray2(object2, key, path, 0);
2614
2667
  for (let index = 0; index < values.length; index++) {
2615
2668
  const itemPath = `${path}.${key}[${index}]`;
2616
2669
  const value = requireStringType(values[index], itemPath);
2617
2670
  check?.(value, itemPath);
2618
2671
  }
2619
2672
  }
2620
- function requiredDateString(object, key, path) {
2621
- assertRfc3339(requiredString2(object, key, path), `${path}.${key}`);
2673
+ function requiredDateString(object2, key, path) {
2674
+ assertRfc3339(requiredString2(object2, key, path), `${path}.${key}`);
2622
2675
  }
2623
- function optionalDateString(object, key, path) {
2624
- if (!hasOwn2(object, key)) {
2676
+ function optionalDateString(object2, key, path) {
2677
+ if (!hasOwn2(object2, key)) {
2625
2678
  return;
2626
2679
  }
2627
- assertRfc3339(requiredString2(object, key, path), `${path}.${key}`);
2680
+ assertRfc3339(requiredString2(object2, key, path), `${path}.${key}`);
2628
2681
  }
2629
2682
  function assertRfc3339(value, path) {
2630
2683
  const match = value.match(
@@ -2656,8 +2709,8 @@ function expectOneOf(actual, allowed, path) {
2656
2709
  }
2657
2710
  throw new SignedObjectSchemaError(`${path} has unsupported value ${actual}`);
2658
2711
  }
2659
- function hasOwn2(object, key) {
2660
- return objectHasOwn3(object, key);
2712
+ function hasOwn2(object2, key) {
2713
+ return objectHasOwn3(object2, key);
2661
2714
  }
2662
2715
  function assertSupportedSignatureSuite(suite) {
2663
2716
  if (suite !== ED25519_JCS_SIGNATURE_SUITE && suite !== EIP191_JCS_SIGNATURE_SUITE) {
@@ -2736,13 +2789,13 @@ function base64UrlDecode(value) {
2736
2789
  return decoded;
2737
2790
  }
2738
2791
  function hexToBytes(value) {
2739
- const hex = value.slice(2);
2740
- if (hex.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(hex)) {
2792
+ const hex3 = value.slice(2);
2793
+ if (hex3.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(hex3)) {
2741
2794
  throw new SignatureMaterialError("hex signature must have even length");
2742
2795
  }
2743
- const output = new Uint8Array(hex.length / 2);
2796
+ const output = new Uint8Array(hex3.length / 2);
2744
2797
  for (let index = 0; index < output.length; index++) {
2745
- output[index] = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16);
2798
+ output[index] = Number.parseInt(hex3.slice(index * 2, index * 2 + 2), 16);
2746
2799
  }
2747
2800
  return output;
2748
2801
  }
@@ -3093,9 +3146,9 @@ function expectPolicyEngineRecord(input) {
3093
3146
  );
3094
3147
  }
3095
3148
  }
3096
- function assertExactKeys3(object, allowed, path) {
3149
+ function assertExactKeys3(object2, allowed, path) {
3097
3150
  const allowedSet = new Set(allowed);
3098
- for (const key of Object.keys(object)) {
3151
+ for (const key of Object.keys(object2)) {
3099
3152
  if (!allowedSet.has(key)) {
3100
3153
  throw new PolicyAuthoringError(
3101
3154
  "policy-authoring-unknown-key",
@@ -3104,17 +3157,17 @@ function assertExactKeys3(object, allowed, path) {
3104
3157
  }
3105
3158
  }
3106
3159
  }
3107
- function requiredValue3(object, key, path) {
3108
- if (!hasOwn3(object, key)) {
3160
+ function requiredValue3(object2, key, path) {
3161
+ if (!hasOwn3(object2, key)) {
3109
3162
  throw new PolicyAuthoringError(
3110
3163
  "policy-authoring-malformed",
3111
3164
  `${path}.${key} is required`
3112
3165
  );
3113
3166
  }
3114
- return object[key];
3167
+ return object2[key];
3115
3168
  }
3116
- function requiredString3(object, key, path) {
3117
- const value = requiredValue3(object, key, path);
3169
+ function requiredString3(object2, key, path) {
3170
+ const value = requiredValue3(object2, key, path);
3118
3171
  if (typeof value !== "string" || value.length === 0) {
3119
3172
  throw new PolicyAuthoringError(
3120
3173
  "policy-authoring-malformed",
@@ -3123,11 +3176,11 @@ function requiredString3(object, key, path) {
3123
3176
  }
3124
3177
  return value;
3125
3178
  }
3126
- function fieldString(object, key, path, code2) {
3127
- if (!hasOwn3(object, key)) {
3179
+ function fieldString(object2, key, path, code2) {
3180
+ if (!hasOwn3(object2, key)) {
3128
3181
  throw new PolicyAuthoringError(code2, `${path}.${key} is required`);
3129
3182
  }
3130
- const value = object[key];
3183
+ const value = object2[key];
3131
3184
  if (typeof value !== "string" || value.length === 0) {
3132
3185
  throw new PolicyAuthoringError(
3133
3186
  code2,
@@ -3136,8 +3189,8 @@ function fieldString(object, key, path, code2) {
3136
3189
  }
3137
3190
  return value;
3138
3191
  }
3139
- function requiredObject(object, key, path) {
3140
- const value = requiredValue3(object, key, path);
3192
+ function requiredObject(object2, key, path) {
3193
+ const value = requiredValue3(object2, key, path);
3141
3194
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
3142
3195
  throw new PolicyAuthoringError(
3143
3196
  "policy-authoring-malformed",
@@ -3146,8 +3199,8 @@ function requiredObject(object, key, path) {
3146
3199
  }
3147
3200
  return value;
3148
3201
  }
3149
- function requiredArray3(object, key, path) {
3150
- const value = requiredValue3(object, key, path);
3202
+ function requiredArray3(object2, key, path) {
3203
+ const value = requiredValue3(object2, key, path);
3151
3204
  if (!Array.isArray(value)) {
3152
3205
  throw new PolicyAuthoringError(
3153
3206
  "policy-authoring-malformed",
@@ -3156,8 +3209,8 @@ function requiredArray3(object, key, path) {
3156
3209
  }
3157
3210
  return value;
3158
3211
  }
3159
- function requiredStringArray2(object, key, path) {
3160
- const values = requiredArray3(object, key, path);
3212
+ function requiredStringArray2(object2, key, path) {
3213
+ const values = requiredArray3(object2, key, path);
3161
3214
  return values.map((value, index) => {
3162
3215
  if (typeof value !== "string" || value.length === 0) {
3163
3216
  throw new PolicyAuthoringError(
@@ -3254,7 +3307,1052 @@ function parseStrictRfc3339(value, path) {
3254
3307
  var objectHasOwn4 = Object.hasOwn ?? Object.prototype.hasOwnProperty.call.bind(
3255
3308
  Object.prototype.hasOwnProperty
3256
3309
  );
3257
- function hasOwn3(object, key) {
3258
- return objectHasOwn4(object, key);
3310
+ function hasOwn3(object2, key) {
3311
+ return objectHasOwn4(object2, key);
3312
+ }
3313
+
3314
+ // src/policy/unified.ts
3315
+ var import_sha256 = require("@noble/hashes/sha256");
3316
+ var import_blake3 = require("@noble/hashes/blake3");
3317
+ var import_ed255192 = require("@noble/curves/ed25519");
3318
+ var import_zod = require("zod");
3319
+ var POLICY_V1_SCHEMA = "xyz.tinycloud.policy/policy/v1";
3320
+ var POLICY_CAPABILITY_V1_SCHEMA = "xyz.tinycloud.policy/capability/v1";
3321
+ var POLICY_ENFORCEMENT_DELEGATION_V2_SCHEMA = "xyz.tinycloud.policy/enforcement-delegation/v2";
3322
+ var ATTESTED_ENFORCER_BINDING_V2_SCHEMA = "xyz.tinycloud.policy/attested-enforcer/v2";
3323
+ var ROOT_STATUS_CHECKPOINT_V1_SCHEMA = "xyz.tinycloud.policy/root-status/v1";
3324
+ var ROOT_REVOCATION_V1_SCHEMA = "xyz.tinycloud.policy/root-revocation/v1";
3325
+ var POLICY_SESSION_UCAN_V1_PROFILE = "policy-session-ucan/v1";
3326
+ var POLICY_V1_DOMAIN = "xyz.tinycloud.policy/policy/v1\0";
3327
+ var POLICY_CAPABILITY_V1_DOMAIN = "xyz.tinycloud.policy/PolicyCapability/v1\0";
3328
+ var CONTENT_SOURCE_V1_DOMAIN = "xyz.tinycloud.policy/ContentSource/v1\0";
3329
+ var NATIVE_PROJECTION_V1_DOMAIN = "xyz.tinycloud.policy/NativeProjection/v1\0";
3330
+ var ROOT_STATUS_V1_DOMAIN = "xyz.tinycloud.policy/RootStatusCheckpoint/v1\0";
3331
+ var ROOT_STATUS_RENEWAL_V1_DOMAIN = "xyz.tinycloud.policy/RootStatusRenewal/v1\0";
3332
+ var ROOT_REVOCATION_V1_DOMAIN = "xyz.tinycloud.policy/RootRevocation/v1\0";
3333
+ var LAST_V2_CREATE_AT = "2026-09-30T00:00:00Z";
3334
+ var MAX_LEGACY_ENVELOPE_EXPIRES_AT = "2026-12-29T00:00:00Z";
3335
+ var LAST_V2_READ_AT = "2027-01-05T00:00:00Z";
3336
+ async function requestPolicyChallengeV3(input) {
3337
+ const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
3338
+ const response = await fetchFn(new URL("/share/v3/policy/challenges", input.nodeOrigin), {
3339
+ method: "POST",
3340
+ redirect: "error",
3341
+ headers: { accept: "application/json", "content-type": "application/json" },
3342
+ body: JSON.stringify({ policyCid: input.policyCid, recipientDid: input.recipientDid, requestedCapabilities: input.requestedCapabilities.map(normalizeUnifiedPolicyCapability) })
3343
+ });
3344
+ if (!response.ok) throw new Error(`policy challenge rejected (${response.status})`);
3345
+ const value = object(await response.json(), "policy challenge");
3346
+ if (typeof value.challengeId !== "string" || typeof value.nonce !== "string" || value.policyCid !== input.policyCid || value.recipientDid !== input.recipientDid)
3347
+ throw new Error("policy challenge binding is invalid");
3348
+ return value;
3349
+ }
3350
+ async function mintPolicySessionV3(input) {
3351
+ const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
3352
+ const challenge = input.challenge ?? await requestPolicyChallengeV3(input);
3353
+ if (challenge.policyCid !== input.policyCid || challenge.recipientDid !== input.recipientDid)
3354
+ throw new Error("policy challenge binding is invalid");
3355
+ const response = await fetchFn(new URL("/share/v3/policy/delegations", input.nodeOrigin), {
3356
+ method: "POST",
3357
+ redirect: "error",
3358
+ headers: { accept: "application/json", "content-type": "application/json" },
3359
+ body: JSON.stringify({ policyCid: input.policyCid, challengeId: challenge.challengeId, nonce: challenge.nonce, claim: input.claim, presentation: input.presentation })
3360
+ });
3361
+ if (!response.ok) throw new Error(`policy delegation rejected (${response.status})`);
3362
+ const value = object(await response.json(), "policy delegation");
3363
+ if (value.admitted !== true || typeof value.sessionCid !== "string" || typeof value.authorization !== "string")
3364
+ throw new Error("policy delegation response is invalid");
3365
+ const session = parsePolicySessionUcan(value.authorization, [input.policyRootCid, input.enforcementRootCid]);
3366
+ const expectedAttenuation = compactAttenuationForPolicyCapabilities(input.requestedCapabilities);
3367
+ if (session.cid !== value.sessionCid || session.aud !== input.recipientDid || session.fact.policyCid !== input.policyCid || session.fact.recipientDid !== input.recipientDid || session.fact.policyDelegationCid !== input.policyRootCid || session.fact.enforcementDelegationCid !== input.enforcementRootCid || jcsCanonicalize(session.att) !== jcsCanonicalize(expectedAttenuation) || Object.entries(input.expectedFacts ?? {}).some(([key, expected]) => session.fact[key] !== expected))
3368
+ throw new Error("policy delegation signed binding is invalid");
3369
+ return session;
3370
+ }
3371
+ function compactAttenuationForPolicyCapabilities(input) {
3372
+ const attenuation = {};
3373
+ for (const raw of input) {
3374
+ const capability = normalizeUnifiedPolicyCapability(raw);
3375
+ if (attenuation[capability.resource] !== void 0)
3376
+ throw new Error("policy capabilities contain a duplicate resource");
3377
+ attenuation[capability.resource] = capability.kind === "encryption" ? { [capability.action]: [{}] } : Object.fromEntries(capability.actions.map((action) => [action, [{
3378
+ type: "xyz.tinycloud.resource/selector",
3379
+ kind: capability.selector,
3380
+ value: capability.resource
3381
+ }]]));
3382
+ }
3383
+ return attenuation;
3384
+ }
3385
+ function verifyPolicyRootStatusCheckpointV3(input) {
3386
+ const checkpoint = input.checkpoint;
3387
+ const allowed = /* @__PURE__ */ new Set(["schema", "targetCid", "targetRole", "ownerDid", "nodeAudience", "state", "sequence", "checkedAt", "freshUntil", "revokedAt", "revocationCid", "previousCheckpointDigestHex", "issuerDid", "signature"]);
3388
+ if (Object.keys(checkpoint).some((key) => !allowed.has(key)) || checkpoint.schema !== ROOT_STATUS_CHECKPOINT_V1_SCHEMA || checkpoint.targetCid !== input.rootCid || checkpoint.targetRole !== "policy-authority" && checkpoint.targetRole !== "policy-enforcement" || checkpoint.state !== "active" && checkpoint.state !== "revoked" || typeof checkpoint.ownerDid !== "string" || typeof checkpoint.nodeAudience !== "string" || checkpoint.issuerDid !== checkpoint.nodeAudience || input.expectedNodeAudience !== void 0 && checkpoint.nodeAudience !== input.expectedNodeAudience || !Number.isInteger(checkpoint.sequence) || checkpoint.sequence < 1 || typeof checkpoint.checkedAt !== "string" || typeof checkpoint.freshUntil !== "string") return false;
3389
+ const checkedAt = Date.parse(checkpoint.checkedAt);
3390
+ const freshUntil = Date.parse(checkpoint.freshUntil);
3391
+ const now = (input.now ?? /* @__PURE__ */ new Date()).getTime();
3392
+ if (!Number.isFinite(checkedAt) || !Number.isFinite(freshUntil) || freshUntil < now || freshUntil <= checkedAt || freshUntil - checkedAt > 3e5) return false;
3393
+ if (checkpoint.sequence === 1 !== (checkpoint.previousCheckpointDigestHex === void 0)) return false;
3394
+ if (checkpoint.sequence !== 1 && (typeof checkpoint.previousCheckpointDigestHex !== "string" || !/^[0-9a-f]{64}$/.test(checkpoint.previousCheckpointDigestHex))) return false;
3395
+ if (checkpoint.state === "active" && (checkpoint.revokedAt !== void 0 || checkpoint.revocationCid !== void 0)) return false;
3396
+ if (checkpoint.state === "revoked" && (typeof checkpoint.revokedAt !== "string" || typeof checkpoint.revocationCid !== "string")) return false;
3397
+ const signature = checkpoint.signature;
3398
+ if (!isRecordValue(signature) || Object.keys(signature).length !== 3 || signature.suite !== "Ed25519" || signature.signerDid !== checkpoint.issuerDid || typeof signature.value !== "string") return false;
3399
+ try {
3400
+ const principal = checkpoint.issuerDid.split("#", 1)[0];
3401
+ const didMaterial = principal.startsWith("did:key:") ? base58btc.decode(principal.slice("did:key:".length)) : new Uint8Array();
3402
+ if (didMaterial.length !== 34 || didMaterial[0] !== 237 || didMaterial[1] !== 1) return false;
3403
+ const unsigned = { ...checkpoint };
3404
+ delete unsigned.signature;
3405
+ return import_ed255192.ed25519.verify(
3406
+ decodeBase64Url(signature.value),
3407
+ (0, import_sha256.sha256)(new TextEncoder().encode(ROOT_STATUS_V1_DOMAIN + jcsCanonicalize(unsigned))),
3408
+ didMaterial.slice(2)
3409
+ );
3410
+ } catch {
3411
+ return false;
3412
+ }
3413
+ }
3414
+ async function getPolicyRootStatusV3(input) {
3415
+ const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
3416
+ const response = await fetchFn(new URL(`/share/v3/policy/status/${encodeURIComponent(input.rootCid)}`, input.nodeOrigin), {
3417
+ method: "GET",
3418
+ redirect: "error",
3419
+ headers: { accept: "application/json" }
3420
+ });
3421
+ if (!response.ok) throw new Error(`policy root status rejected (${response.status})`);
3422
+ const value = object(await response.json(), "policy root status");
3423
+ const checkpoint = object(value.checkpoint, "policy root checkpoint");
3424
+ if (value.rootCid !== input.rootCid || value.state !== "active" && value.state !== "revoked" || value.state !== checkpoint.state || !verifyPolicyRootStatusCheckpointV3({ rootCid: input.rootCid, checkpoint, expectedNodeAudience: input.expectedNodeAudience, now: input.now }))
3425
+ throw new Error("policy root status binding is invalid");
3426
+ const revocation = value.revocation === void 0 ? void 0 : object(value.revocation, "policy root revocation");
3427
+ if (value.state === "revoked" !== (revocation !== void 0) || revocation !== void 0 && !verifyPolicyRootRevocationV3({
3428
+ rootCid: input.rootCid,
3429
+ checkpoint,
3430
+ revocation,
3431
+ expectedEnforcerDid: input.expectedEnforcerDid
3432
+ })) throw new Error("policy root status revocation evidence is invalid");
3433
+ return { rootCid: input.rootCid, state: value.state, checkpoint, ...revocation === void 0 ? {} : { revocation } };
3434
+ }
3435
+ function verifyPolicyRootRevocationV3(input) {
3436
+ const value = input.revocation;
3437
+ const allowed = ["schema", "targetCid", "targetRole", "ownerDid", "nodeAudience", "revokedAt", "reason", "issuerDid", "signature"];
3438
+ if (Object.keys(value).length !== allowed.length || Object.keys(value).some((key) => !allowed.includes(key)) || value.schema !== ROOT_REVOCATION_V1_SCHEMA || value.targetCid !== input.rootCid || value.targetRole !== input.checkpoint.targetRole || value.ownerDid !== input.checkpoint.ownerDid || value.nodeAudience !== input.checkpoint.nodeAudience || value.revokedAt !== input.checkpoint.revokedAt || typeof value.reason !== "string" || value.reason.length === 0 || typeof value.issuerDid !== "string") return false;
3439
+ const authorized = value.issuerDid === value.ownerDid || value.targetRole === "policy-enforcement" && value.issuerDid === input.expectedEnforcerDid;
3440
+ if (!authorized) return false;
3441
+ const signature = value.signature;
3442
+ if (!isRecordValue(signature) || Object.keys(signature).length !== 3 || signature.suite !== "Ed25519" || signature.signerDid !== value.issuerDid || typeof signature.value !== "string") return false;
3443
+ try {
3444
+ const principal = value.issuerDid.split("#", 1)[0];
3445
+ const didMaterial = principal.startsWith("did:key:") ? base58btc.decode(principal.slice("did:key:".length)) : new Uint8Array();
3446
+ if (didMaterial.length !== 34 || didMaterial[0] !== 237 || didMaterial[1] !== 1) return false;
3447
+ const unsigned = { ...value };
3448
+ delete unsigned.signature;
3449
+ const digest2 = (0, import_sha256.sha256)(new TextEncoder().encode(ROOT_REVOCATION_V1_DOMAIN + jcsCanonicalize(unsigned)));
3450
+ return input.checkpoint.revocationCid === hex(digest2) && import_ed255192.ed25519.verify(decodeBase64Url(signature.value), digest2, didMaterial.slice(2));
3451
+ } catch {
3452
+ return false;
3453
+ }
3454
+ }
3455
+ async function renewPolicyRootStatusV3(input) {
3456
+ const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
3457
+ const current = await getPolicyRootStatusV3({ nodeOrigin: input.nodeOrigin, rootCid: input.rootCid, expectedNodeAudience: input.nodeAudience, now: input.now, fetch: fetchFn });
3458
+ if (current.state !== "active" || current.checkpoint.ownerDid !== input.ownerDid || current.checkpoint.nodeAudience !== input.nodeAudience || current.checkpoint.state !== "active" || !Number.isInteger(current.checkpoint.sequence))
3459
+ throw new Error("policy root status cannot be renewed");
3460
+ const currentUnsigned = { ...current.checkpoint };
3461
+ delete currentUnsigned.signature;
3462
+ const previousCheckpointDigestHex = hex((0, import_sha256.sha256)(new TextEncoder().encode(ROOT_STATUS_V1_DOMAIN + jcsCanonicalize(currentUnsigned))));
3463
+ const unsigned = {
3464
+ schema: "xyz.tinycloud.policy/root-status-renewal/v1",
3465
+ targetCid: input.rootCid,
3466
+ ownerDid: input.ownerDid,
3467
+ nodeAudience: input.nodeAudience,
3468
+ issuedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
3469
+ nonce: input.nonce ?? encodeBase64Url(crypto.getRandomValues(new Uint8Array(16))),
3470
+ sequence: current.checkpoint.sequence + 1,
3471
+ previousCheckpointDigestHex
3472
+ };
3473
+ const signature = await input.sign((0, import_sha256.sha256)(new TextEncoder().encode(ROOT_STATUS_RENEWAL_V1_DOMAIN + jcsCanonicalize(unsigned))));
3474
+ if (signature.length !== 64) throw new Error("policy root renewal signature must be Ed25519");
3475
+ const response = await fetchFn(new URL("/share/v3/policy/status", input.nodeOrigin), {
3476
+ method: "POST",
3477
+ redirect: "error",
3478
+ headers: { accept: "application/json", "content-type": "application/json" },
3479
+ body: JSON.stringify({ rootCid: input.rootCid, renewal: { ...unsigned, signature: { suite: "Ed25519", signerDid: input.ownerDid, value: encodeBase64Url(signature) } } })
3480
+ });
3481
+ if (!response.ok) throw new Error(`policy root renewal rejected (${response.status})`);
3482
+ return object(await response.json(), "policy root renewal");
3483
+ }
3484
+ async function revokePolicyRootV3(input) {
3485
+ if (input.reason.length === 0) throw new Error("policy root revocation reason is required");
3486
+ const unsigned = {
3487
+ schema: ROOT_REVOCATION_V1_SCHEMA,
3488
+ targetCid: input.rootCid,
3489
+ targetRole: input.targetRole,
3490
+ ownerDid: input.ownerDid,
3491
+ nodeAudience: input.nodeAudience,
3492
+ revokedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
3493
+ reason: input.reason,
3494
+ issuerDid: input.issuerDid
3495
+ };
3496
+ const signature = await input.sign((0, import_sha256.sha256)(new TextEncoder().encode(ROOT_REVOCATION_V1_DOMAIN + jcsCanonicalize(unsigned))));
3497
+ if (signature.length !== 64) throw new Error("policy root revocation signature must be Ed25519");
3498
+ const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
3499
+ const response = await fetchFn(new URL("/revoke", input.nodeOrigin), {
3500
+ method: "POST",
3501
+ redirect: "error",
3502
+ headers: { accept: "application/json", "content-type": "application/json" },
3503
+ body: JSON.stringify({ revocation: { ...unsigned, signature: { suite: "Ed25519", signerDid: input.issuerDid, value: encodeBase64Url(signature) } } })
3504
+ });
3505
+ if (!response.ok) throw new Error(`policy root revocation rejected (${response.status})`);
3506
+ return object(await response.json(), "policy root revocation");
3507
+ }
3508
+ var POLICY_SESSION_FACT_KEYS = [
3509
+ "profile",
3510
+ "ownerDid",
3511
+ "policyId",
3512
+ "policyDigestHex",
3513
+ "policyCid",
3514
+ "policyDelegationCid",
3515
+ "enforcementDelegationCid",
3516
+ "contentSourceDigestHex",
3517
+ "capabilityCeilingHashHex",
3518
+ "nativeProjectionHashHex",
3519
+ "enforcerDid",
3520
+ "nodeAudience",
3521
+ "recipientDid",
3522
+ "challengeId",
3523
+ "claimDigestHex",
3524
+ "claimJti",
3525
+ "vpDigestHex",
3526
+ "credentialEvidenceDigestHex",
3527
+ "decisionContextDigestHex",
3528
+ "issuanceAuditDigestHex",
3529
+ "remainingRedelegationDepth"
3530
+ ];
3531
+ var KV_ACTIONS = /* @__PURE__ */ new Set([
3532
+ "tinycloud.kv/get",
3533
+ "tinycloud.kv/list",
3534
+ "tinycloud.kv/metadata",
3535
+ "tinycloud.kv/put"
3536
+ ]);
3537
+ function object(value, label) {
3538
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
3539
+ throw new Error(`${label} must be an object`);
3540
+ }
3541
+ return value;
3542
+ }
3543
+ function exactKeys(value, allowed, label) {
3544
+ const keys = new Set(allowed);
3545
+ if (Object.keys(value).some((key) => !keys.has(key)))
3546
+ throw new Error(`${label} contains an unknown field`);
3547
+ }
3548
+ function nonEmptyString(value, label) {
3549
+ if (typeof value !== "string" || value.length === 0)
3550
+ throw new Error(`${label} must be a non-empty string`);
3551
+ return value;
3552
+ }
3553
+ function parseKvResource(resource) {
3554
+ const marker = resource.indexOf("/kv/");
3555
+ const encodedSpace = marker < 1 ? "" : resource.slice(0, marker);
3556
+ const legacy = encodedSpace.startsWith("tinycloud://");
3557
+ const space = legacy ? encodedSpace.slice("tinycloud://".length) : encodedSpace;
3558
+ const path = marker < 1 ? "" : resource.slice(marker + 4);
3559
+ if (marker < 1 || (legacy ? /[:/?#%]/.test(space) : !encodedSpace.startsWith("tinycloud:") || /[/?#%]/.test(encodedSpace)) || path.startsWith("/") || path.endsWith("/") || path.includes("//") || path.split("/").some((part) => part === "." || part === ".." || part.length === 0)) {
3560
+ throw new Error("KV resource is not canonical");
3561
+ }
3562
+ return { space, path };
3563
+ }
3564
+ function parseEncryptionResource(resource) {
3565
+ if (!resource.startsWith("urn:tinycloud:encryption:")) throw new Error("encryption capability is invalid");
3566
+ const rest = resource.slice("urn:tinycloud:encryption:".length);
3567
+ const separator = rest.lastIndexOf(":");
3568
+ const ownerDid = separator < 0 ? "" : rest.slice(0, separator);
3569
+ const network = separator < 0 ? "" : rest.slice(separator + 1);
3570
+ if (!ownerDid.startsWith("did:") || network.length === 0 || network.includes(":") || network.includes("/") || network.includes("%") || network.includes("?") || network.includes("#")) {
3571
+ throw new Error("encryption capability is invalid");
3572
+ }
3573
+ }
3574
+ function normalizeUnifiedPolicyCapability(input) {
3575
+ const value = object(input, "capability");
3576
+ const kind = nonEmptyString(value.kind, "capability.kind");
3577
+ if (kind === "kv") {
3578
+ exactKeys(
3579
+ value,
3580
+ ["kind", "resource", "selector", "actions"],
3581
+ "KV capability"
3582
+ );
3583
+ const resource = nonEmptyString(value.resource, "capability.resource");
3584
+ parseKvResource(resource);
3585
+ if (value.selector !== "exact" && value.selector !== "prefix")
3586
+ throw new Error("capability.selector is invalid");
3587
+ if (!Array.isArray(value.actions) || value.actions.length === 0)
3588
+ throw new Error("capability.actions is invalid");
3589
+ const actions = value.actions.map(
3590
+ (action) => nonEmptyString(action, "capability.actions[]")
3591
+ );
3592
+ if (new Set(actions).size !== actions.length || actions.some((action) => !KV_ACTIONS.has(action)))
3593
+ throw new Error("capability.actions is invalid");
3594
+ return {
3595
+ kind: "kv",
3596
+ resource,
3597
+ selector: value.selector,
3598
+ actions: [...actions].sort()
3599
+ };
3600
+ }
3601
+ if (kind === "encryption") {
3602
+ exactKeys(value, ["kind", "resource", "action"], "encryption capability");
3603
+ const resource = nonEmptyString(value.resource, "capability.resource");
3604
+ if (value.action !== "tinycloud.encryption/decrypt")
3605
+ throw new Error("encryption capability is invalid");
3606
+ parseEncryptionResource(resource);
3607
+ return {
3608
+ kind: "encryption",
3609
+ resource,
3610
+ action: "tinycloud.encryption/decrypt"
3611
+ };
3612
+ }
3613
+ throw new Error("capability.kind is invalid");
3614
+ }
3615
+ function canonicalizeUnifiedPolicyCapability(input) {
3616
+ return normalizeUnifiedPolicyCapability(input);
3617
+ }
3618
+ function unifiedPolicyCapabilityDigestHex(input) {
3619
+ return hex(
3620
+ (0, import_sha256.sha256)(
3621
+ new TextEncoder().encode(
3622
+ POLICY_CAPABILITY_V1_DOMAIN + jcsCanonicalize(normalizeUnifiedPolicyCapability(input))
3623
+ )
3624
+ )
3625
+ );
3626
+ }
3627
+ function unifiedPolicyCapabilityContains(authorityInput, requestedInput) {
3628
+ try {
3629
+ const authority = normalizeUnifiedPolicyCapability(authorityInput);
3630
+ const requested = normalizeUnifiedPolicyCapability(requestedInput);
3631
+ if (authority.kind !== requested.kind) return false;
3632
+ if (authority.kind === "encryption" && requested.kind === "encryption")
3633
+ return authority.resource === requested.resource && authority.action === requested.action;
3634
+ if (authority.kind !== "kv" || requested.kind !== "kv") return false;
3635
+ const { resource: authorized } = authority;
3636
+ const { resource: requestedResource } = requested;
3637
+ const pathContained = authority.selector === "exact" ? authorized === requestedResource : authorized === requestedResource || requestedResource.startsWith(`${authorized}/`);
3638
+ if (!pathContained || authority.selector === "exact" && requested.selector === "prefix")
3639
+ return false;
3640
+ return requested.actions.every(
3641
+ (action) => authority.actions.includes(action)
3642
+ );
3643
+ } catch {
3644
+ return false;
3645
+ }
3646
+ }
3647
+ function projectUnifiedPolicyCapability(input) {
3648
+ const capability = normalizeUnifiedPolicyCapability(input);
3649
+ if (capability.kind === "encryption") {
3650
+ return {
3651
+ service: "tinycloud.encryption",
3652
+ space: capability.resource,
3653
+ path: capability.resource,
3654
+ actions: [capability.action]
3655
+ };
3656
+ }
3657
+ const { space, path } = parseKvResource(capability.resource);
3658
+ return {
3659
+ service: "tinycloud.kv",
3660
+ space,
3661
+ path,
3662
+ actions: [...capability.actions],
3663
+ caveat: {
3664
+ type: "xyz.tinycloud.resource/selector",
3665
+ kind: capability.selector,
3666
+ value: capability.resource
3667
+ }
3668
+ };
3669
+ }
3670
+ function projectUnifiedPolicyCapabilities(input) {
3671
+ return input.map(projectUnifiedPolicyCapability).sort((left, right) => {
3672
+ const a = jcsCanonicalize(left);
3673
+ const b = jcsCanonicalize(right);
3674
+ return a < b ? -1 : a > b ? 1 : 0;
3675
+ });
3676
+ }
3677
+ function unifiedNativeProjectionHashHex(input) {
3678
+ return hex(
3679
+ (0, import_sha256.sha256)(
3680
+ new TextEncoder().encode(
3681
+ NATIVE_PROJECTION_V1_DOMAIN + jcsCanonicalize(projectUnifiedPolicyCapabilities(input))
3682
+ )
3683
+ )
3684
+ );
3685
+ }
3686
+ function unifiedPolicyCapabilityFromNative(input) {
3687
+ const value = object(input, "native capability");
3688
+ exactKeys(
3689
+ value,
3690
+ ["service", "space", "path", "actions", "caveat"],
3691
+ "native capability"
3692
+ );
3693
+ const service = nonEmptyString(value.service, "native.service");
3694
+ const actions = value.actions;
3695
+ if (!Array.isArray(actions)) throw new Error("native.actions is invalid");
3696
+ if (service === "tinycloud.encryption" && value.caveat === void 0 && value.space === value.path && actions.length === 1 && actions[0] === "tinycloud.encryption/decrypt") {
3697
+ return normalizeUnifiedPolicyCapability({
3698
+ kind: "encryption",
3699
+ resource: value.space,
3700
+ action: actions[0]
3701
+ });
3702
+ }
3703
+ if (service !== "tinycloud.kv" || typeof value.space !== "string" || typeof value.path !== "string")
3704
+ throw new Error("native capability is not supported");
3705
+ const caveat = object(value.caveat, "native.caveat");
3706
+ exactKeys(caveat, ["type", "kind", "value"], "native selector caveat");
3707
+ if (caveat.type !== "xyz.tinycloud.resource/selector" || caveat.kind !== "exact" && caveat.kind !== "prefix" || caveat.value !== `${value.space.startsWith("tinycloud:") ? value.space : `tinycloud://${value.space}`}/kv/${value.path}`)
3708
+ throw new Error("native selector caveat does not match capability");
3709
+ return normalizeUnifiedPolicyCapability({
3710
+ kind: "kv",
3711
+ resource: caveat.value,
3712
+ selector: caveat.kind,
3713
+ actions
3714
+ });
3715
+ }
3716
+ function contentSourceDigestHex(input) {
3717
+ return hex(
3718
+ (0, import_sha256.sha256)(
3719
+ new TextEncoder().encode(
3720
+ CONTENT_SOURCE_V1_DOMAIN + jcsCanonicalize(input)
3721
+ )
3722
+ )
3723
+ );
3724
+ }
3725
+ function policyDigestHex(policy) {
3726
+ const canonicalPolicy = {
3727
+ ...policy,
3728
+ capabilityCeiling: policy.capabilityCeiling.map(
3729
+ normalizeUnifiedPolicyCapability
3730
+ )
3731
+ };
3732
+ return hex(
3733
+ (0, import_sha256.sha256)(
3734
+ new TextEncoder().encode(
3735
+ POLICY_V1_DOMAIN + jcsCanonicalize(canonicalPolicy)
3736
+ )
3737
+ )
3738
+ );
3739
+ }
3740
+ function policyIdForDigestHex(digestHex) {
3741
+ const digest2 = Uint8Array.from(
3742
+ (digestHex.match(/.{2}/g) ?? []).map((byte) => Number.parseInt(byte, 16))
3743
+ );
3744
+ if (digest2.length !== 32) throw new Error("policy digest must be 32 bytes");
3745
+ return `pol_${base32Lower(digest2)}`;
3746
+ }
3747
+ function policyCidFromCanonicalBytes(bytes) {
3748
+ return CID.createV1(85, create(18, (0, import_sha256.sha256)(bytes))).toString();
3749
+ }
3750
+ var CompactHeaderSchema = import_zod.z.object({
3751
+ alg: import_zod.z.literal("EdDSA"),
3752
+ jwk: import_zod.z.object({ alg: import_zod.z.literal("EdDSA"), crv: import_zod.z.literal("Ed25519"), kty: import_zod.z.literal("OKP"), x: import_zod.z.string().min(1) }).strict(),
3753
+ typ: import_zod.z.literal("JWT"),
3754
+ ucv: import_zod.z.literal("0.10.0")
3755
+ }).strict();
3756
+ var CompactPayloadSchema = import_zod.z.object({
3757
+ att: import_zod.z.record(import_zod.z.record(import_zod.z.array(import_zod.z.unknown()).min(1))),
3758
+ aud: import_zod.z.string().min(1),
3759
+ exp: import_zod.z.number().int(),
3760
+ fct: import_zod.z.array(import_zod.z.record(import_zod.z.unknown())).length(1),
3761
+ iss: import_zod.z.string().min(1),
3762
+ nbf: import_zod.z.number().int(),
3763
+ nnc: import_zod.z.string().min(1),
3764
+ prf: import_zod.z.array(import_zod.z.string().min(1))
3765
+ }).strict();
3766
+ async function signCompactUcan(input) {
3767
+ const principal = input.issuerDid.split("#", 1)[0];
3768
+ const didMaterial = principal.startsWith("did:key:") ? base58btc.decode(principal.slice("did:key:".length)) : new Uint8Array();
3769
+ if (didMaterial.length !== 34 || didMaterial[0] !== 237 || didMaterial[1] !== 1)
3770
+ throw new Error("compact UCAN signer must be did:key Ed25519");
3771
+ const header = { alg: "EdDSA", jwk: { alg: "EdDSA", crv: "Ed25519", kty: "OKP", x: encodeBase64Url(didMaterial.slice(2)) }, typ: "JWT", ucv: "0.10.0" };
3772
+ const payload = {
3773
+ att: input.attenuation,
3774
+ aud: input.audienceDid,
3775
+ exp: input.expiresAt,
3776
+ fct: input.facts,
3777
+ iss: input.issuerDid.includes("#") ? input.issuerDid : `${principal}#${principal.slice("did:key:".length)}`,
3778
+ nbf: input.notBefore,
3779
+ nnc: input.nonce,
3780
+ prf: input.proofs
3781
+ };
3782
+ const protectedSegment = encodeBase64Url(new TextEncoder().encode(jcsCanonicalize(header)));
3783
+ const payloadSegment = encodeBase64Url(new TextEncoder().encode(jcsCanonicalize(payload)));
3784
+ const signature = await input.sign(new TextEncoder().encode(`${protectedSegment}.${payloadSegment}`));
3785
+ if (signature.length !== 64) throw new Error("compact Authorization signature must be Ed25519");
3786
+ return parseCompactUcanAuthorization(`${protectedSegment}.${payloadSegment}.${encodeBase64Url(signature)}`);
3787
+ }
3788
+ async function signCompactUcanAuthorization(input) {
3789
+ if (input.notBefore >= input.expiresAt || input.expiresAt - input.notBefore > 60)
3790
+ throw new Error("compact invocation lifetime must be between one and 60 seconds");
3791
+ return signCompactUcan(input);
3792
+ }
3793
+ async function signCompactUcanRootAuthorization(input) {
3794
+ if (input.notBefore >= input.expiresAt || input.expiresAt - input.notBefore > 31 * 24 * 60 * 60)
3795
+ throw new Error("compact policy root lifetime must be between one second and 31 days");
3796
+ return signCompactUcan({ ...input, proofs: [] });
3797
+ }
3798
+ function createCompactPolicyInvocation(input) {
3799
+ const session = parsePolicySessionUcan(input.sessionAuthorization);
3800
+ if (session.cid !== input.sessionCid || session.aud !== input.recipientDid)
3801
+ throw new Error("policy session does not bind the recipient signer");
3802
+ const principal = input.recipientDid.split("#", 1)[0];
3803
+ const didMaterial = base58btc.decode(principal.slice("did:key:".length));
3804
+ if (didMaterial.length !== 34 || didMaterial[0] !== 237 || didMaterial[1] !== 1)
3805
+ throw new Error("policy invocation signer must be did:key Ed25519");
3806
+ const publicKey = import_ed255192.ed25519.getPublicKey(input.privateKey);
3807
+ if (!equalBytes(publicKey, didMaterial.slice(2)))
3808
+ throw new Error("policy invocation private key does not bind recipient DID");
3809
+ const now = input.now ?? Math.floor(Date.now() / 1e3);
3810
+ const exp = Math.min(now + 60, session.exp);
3811
+ if (exp <= now) throw new Error("policy session has expired");
3812
+ const header = { alg: "EdDSA", jwk: { alg: "EdDSA", crv: "Ed25519", kty: "OKP", x: encodeBase64Url(publicKey) }, typ: "JWT", ucv: "0.10.0" };
3813
+ const payload = {
3814
+ att: { [input.resource]: { [input.action]: [input.caveat ?? {}] } },
3815
+ aud: input.audienceDid,
3816
+ exp,
3817
+ fct: [input.facts ?? { type: "tinycloud.policy.invocation/v1", policyCid: session.fact.policyCid, sessionCid: session.cid }],
3818
+ iss: input.recipientDid.includes("#") ? input.recipientDid : `${principal}#${principal.slice("did:key:".length)}`,
3819
+ nbf: now,
3820
+ nnc: input.nonce ?? encodeBase64Url(crypto.getRandomValues(new Uint8Array(16))),
3821
+ prf: [session.cid]
3822
+ };
3823
+ const protectedSegment = encodeBase64Url(new TextEncoder().encode(jcsCanonicalize(header)));
3824
+ const payloadSegment = encodeBase64Url(new TextEncoder().encode(jcsCanonicalize(payload)));
3825
+ const signingInput = new TextEncoder().encode(`${protectedSegment}.${payloadSegment}`);
3826
+ const signature = import_ed255192.ed25519.sign(signingInput, input.privateKey);
3827
+ return parseCompactUcanAuthorization(`${protectedSegment}.${payloadSegment}.${encodeBase64Url(signature)}`);
3828
+ }
3829
+ function createCompactPolicyDescendant(input) {
3830
+ const parent = parseCompactUcanAuthorization(input.parentAuthorization, input.parentCid);
3831
+ if (parent.payload.aud !== input.issuerDid) throw new Error("policy descendant issuer is not the parent audience");
3832
+ const parentFact = parent.payload.fct[0];
3833
+ const depth = parentFact.remainingRedelegationDepth;
3834
+ if (!Number.isInteger(depth) || depth <= 0) throw new Error("policy descendant depth is exhausted");
3835
+ if (!compactAttenuationContains(parent.payload.att, input.attenuation))
3836
+ throw new Error("policy descendant exceeds the parent attenuation");
3837
+ const principal = input.issuerDid.split("#", 1)[0];
3838
+ const didMaterial = base58btc.decode(principal.slice("did:key:".length));
3839
+ const publicKey = import_ed255192.ed25519.getPublicKey(input.privateKey);
3840
+ if (didMaterial.length !== 34 || !equalBytes(publicKey, didMaterial.slice(2))) throw new Error("policy descendant signer does not bind issuer DID");
3841
+ const now = Math.max(input.now ?? Math.floor(Date.now() / 1e3), parent.payload.nbf + 1);
3842
+ const exp = Math.min(input.expiresAt ?? now + 60, now + 60, parent.payload.exp - 1);
3843
+ if (exp <= now) throw new Error("policy parent has no strictly narrower validity window");
3844
+ const header = { alg: "EdDSA", jwk: { alg: "EdDSA", crv: "Ed25519", kty: "OKP", x: encodeBase64Url(publicKey) }, typ: "JWT", ucv: "0.10.0" };
3845
+ const payload = {
3846
+ att: input.attenuation,
3847
+ aud: input.audienceDid,
3848
+ exp,
3849
+ fct: [{ ...parentFact, remainingRedelegationDepth: depth - 1 }],
3850
+ iss: input.issuerDid.includes("#") ? input.issuerDid : `${principal}#${principal.slice("did:key:".length)}`,
3851
+ nbf: now,
3852
+ nnc: input.nonce ?? encodeBase64Url(crypto.getRandomValues(new Uint8Array(16))),
3853
+ prf: [parent.cid]
3854
+ };
3855
+ const protectedSegment = encodeBase64Url(new TextEncoder().encode(jcsCanonicalize(header)));
3856
+ const payloadSegment = encodeBase64Url(new TextEncoder().encode(jcsCanonicalize(payload)));
3857
+ const signature = import_ed255192.ed25519.sign(new TextEncoder().encode(`${protectedSegment}.${payloadSegment}`), input.privateKey);
3858
+ return parseCompactUcanAuthorization(`${protectedSegment}.${payloadSegment}.${encodeBase64Url(signature)}`);
3859
+ }
3860
+ function compactAttenuationContains(parent, child) {
3861
+ const selector = (value) => {
3862
+ if (value.length !== 1 || !isRecordValue(value[0])) return void 0;
3863
+ const caveat = value[0];
3864
+ if (Object.keys(caveat).length !== 3 || caveat.type !== "xyz.tinycloud.resource/selector" || caveat.kind !== "exact" && caveat.kind !== "prefix" || typeof caveat.value !== "string") return void 0;
3865
+ return { kind: caveat.kind, value: caveat.value };
3866
+ };
3867
+ const equal = (left, right) => jcsCanonicalize(left) === jcsCanonicalize(right);
3868
+ return Object.entries(child).every(
3869
+ ([childResource, childActions]) => Object.entries(childActions).every(
3870
+ ([action, childCaveats]) => Object.entries(parent).some(([parentResource, parentActions]) => {
3871
+ const parentCaveats = parentActions[action];
3872
+ if (parentCaveats === void 0) return false;
3873
+ if (parentResource === childResource && equal(parentCaveats, childCaveats)) return true;
3874
+ const parentSelector = selector(parentCaveats);
3875
+ const childSelector = selector(childCaveats);
3876
+ return parentSelector?.kind === "prefix" && childSelector !== void 0 && parentSelector.value === parentResource && childSelector.value === childResource && (childResource === parentResource || childResource.startsWith(`${parentResource}/`));
3877
+ })
3878
+ )
3879
+ );
3880
+ }
3881
+ function isRecordValue(value) {
3882
+ return value !== null && typeof value === "object" && !Array.isArray(value);
3883
+ }
3884
+ function parseCompactUcanAuthorization(input, expectedCid) {
3885
+ if (typeof input !== "string" || /\s/.test(input))
3886
+ throw new Error("Authorization must be compact UCAN bytes");
3887
+ const segments = input.split(".");
3888
+ if (segments.length !== 3 || segments.some((segment) => segment.length === 0))
3889
+ throw new Error("Authorization must have three compact segments");
3890
+ const [headerSegment, payloadSegment, signatureSegment] = segments;
3891
+ const headerBytes = decodeBase64Url(headerSegment);
3892
+ const payloadBytes = decodeBase64Url(payloadSegment);
3893
+ const signature = decodeBase64Url(signatureSegment);
3894
+ const headerValue = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(headerBytes));
3895
+ const payloadValue = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(payloadBytes));
3896
+ if (jcsCanonicalize(headerValue) !== new TextDecoder().decode(headerBytes) || jcsCanonicalize(payloadValue) !== new TextDecoder().decode(payloadBytes))
3897
+ throw new Error("compact UCAN segments are not canonical JCS");
3898
+ const header = CompactHeaderSchema.parse(headerValue);
3899
+ const payload = CompactPayloadSchema.parse(payloadValue);
3900
+ if (payload.nbf >= payload.exp) throw new Error("compact UCAN validity is empty");
3901
+ const principal = payload.iss.split("#", 1)[0];
3902
+ const didMaterial = principal.startsWith("did:key:") ? base58btc.decode(principal.slice("did:key:".length)) : new Uint8Array();
3903
+ if (didMaterial.length !== 34 || didMaterial[0] !== 237 || didMaterial[1] !== 1)
3904
+ throw new Error("compact UCAN issuer must be did:key Ed25519");
3905
+ const publicKey = didMaterial.slice(2);
3906
+ if (!equalBytes(publicKey, decodeBase64Url(header.jwk.x)))
3907
+ throw new Error("compact UCAN JWK does not bind issuer");
3908
+ if (!import_ed255192.ed25519.verify(signature, new TextEncoder().encode(`${headerSegment}.${payloadSegment}`), publicKey))
3909
+ throw new Error("compact UCAN signature is invalid");
3910
+ const cid = CID.createV1(85, create(30, (0, import_blake3.blake3)(new TextEncoder().encode(input)))).toString();
3911
+ if (expectedCid !== void 0 && cid !== expectedCid)
3912
+ throw new Error("compact UCAN CID does not match exact Authorization bytes");
3913
+ return { authorization: input, cid, header, payload };
3914
+ }
3915
+ function parsePolicySessionUcan(authorization, expectedProofs) {
3916
+ const parsed = parseCompactUcanAuthorization(authorization);
3917
+ const fact = parsed.payload.fct[0];
3918
+ if (parsed.payload.prf.length !== 2 || parsed.payload.prf[0] === parsed.payload.prf[1])
3919
+ throw new Error("policy session UCAN requires two distinct ordered proofs");
3920
+ if (expectedProofs !== void 0 && (parsed.payload.prf[0] !== expectedProofs[0] || parsed.payload.prf[1] !== expectedProofs[1]))
3921
+ throw new Error("policy session UCAN ordered proofs do not match");
3922
+ const factKeys = Object.keys(fact);
3923
+ if (factKeys.length !== POLICY_SESSION_FACT_KEYS.length || factKeys.some((key) => !POLICY_SESSION_FACT_KEYS.includes(key)) || POLICY_SESSION_FACT_KEYS.some((key) => !(key in fact)))
3924
+ throw new Error("policy session UCAN fact is incomplete");
3925
+ if (fact.profile !== POLICY_SESSION_UCAN_V1_PROFILE || typeof fact.remainingRedelegationDepth !== "number" || !Number.isInteger(fact.remainingRedelegationDepth) || fact.remainingRedelegationDepth < 0 || fact.remainingRedelegationDepth > 8 || parsed.payload.exp - parsed.payload.nbf > 60 || parsed.payload.iss.split("#", 1)[0] !== fact.enforcerDid || parsed.payload.aud !== fact.recipientDid)
3926
+ throw new Error("policy session UCAN fact is invalid");
3927
+ return {
3928
+ authorization,
3929
+ cid: parsed.cid,
3930
+ iss: parsed.payload.iss,
3931
+ aud: parsed.payload.aud,
3932
+ prf: parsed.payload.prf,
3933
+ att: parsed.payload.att,
3934
+ nbf: parsed.payload.nbf,
3935
+ exp: parsed.payload.exp,
3936
+ nnc: parsed.payload.nnc,
3937
+ fact
3938
+ };
3939
+ }
3940
+ function decodeBase64Url(value) {
3941
+ if (!/^[A-Za-z0-9_-]+$/.test(value) || value.length % 4 === 1)
3942
+ throw new Error("value is not canonical base64url");
3943
+ const normalized = value.replace(/-/g, "+").replace(/_/g, "/");
3944
+ const binary = typeof atob === "function" ? atob(normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=")) : Buffer.from(normalized, "base64").toString("binary");
3945
+ const bytes = Uint8Array.from(binary, (character) => character.charCodeAt(0));
3946
+ const encoded = typeof btoa === "function" ? btoa(String.fromCharCode(...bytes)).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_") : Buffer.from(bytes).toString("base64url");
3947
+ if (encoded !== value) throw new Error("value is not canonical base64url");
3948
+ return bytes;
3949
+ }
3950
+ function encodeBase64Url(value) {
3951
+ return typeof btoa === "function" ? btoa(String.fromCharCode(...value)).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_") : Buffer.from(value).toString("base64url");
3952
+ }
3953
+ function equalBytes(left, right) {
3954
+ return left.length === right.length && left.every((byte, index) => byte === right[index]);
3955
+ }
3956
+ function hex(bytes) {
3957
+ return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
3958
+ }
3959
+ function base32Lower(bytes) {
3960
+ const alphabet2 = "abcdefghijklmnopqrstuvwxyz234567";
3961
+ let output = "";
3962
+ let buffer = 0;
3963
+ let bits = 0;
3964
+ for (const byte of bytes) {
3965
+ buffer = buffer << 8 | byte;
3966
+ bits += 8;
3967
+ while (bits >= 5) {
3968
+ output += alphabet2[buffer >>> bits - 5 & 31];
3969
+ bits -= 5;
3970
+ }
3971
+ }
3972
+ if (bits > 0) output += alphabet2[buffer << 5 - bits & 31];
3973
+ return output;
3974
+ }
3975
+
3976
+ // src/policy/credential-admission.ts
3977
+ var import_ed255193 = require("@noble/curves/ed25519");
3978
+ var import_sha2562 = require("@noble/hashes/sha256");
3979
+
3980
+ // src/credentials/digest.ts
3981
+ function encodeBase64Url2(bytes) {
3982
+ if (typeof btoa === "function") {
3983
+ let binary = "";
3984
+ for (const byte of bytes) binary += String.fromCharCode(byte);
3985
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3986
+ }
3987
+ return Buffer.from(bytes).toString("base64url");
3988
+ }
3989
+ async function sha256Base64Url(value) {
3990
+ const bytes = typeof value === "string" ? new TextEncoder().encode(value) : value;
3991
+ return encodeBase64Url2(new Uint8Array(await crypto.subtle.digest("SHA-256", bytes)));
3992
+ }
3993
+ async function canonicalDigest(value) {
3994
+ return sha256Base64Url(jcsCanonicalize(value));
3995
+ }
3996
+ function isDigest(value) {
3997
+ return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
3998
+ }
3999
+
4000
+ // src/credentials/errors.ts
4001
+ var RECOVERABLE = /* @__PURE__ */ new Set([
4002
+ "CANCELED",
4003
+ "ISSUER_UNREADY",
4004
+ "OFFLINE",
4005
+ "POPUP_BLOCKED",
4006
+ "REQUEST_EXPIRED",
4007
+ "SIGNATURE_REJECTED",
4008
+ "UNSUPPORTED_PROFILE",
4009
+ "UNSUPPORTED_VERSION",
4010
+ "VERIFIED_NOT_SAVED"
4011
+ ]);
4012
+ var CredentialError = class extends Error {
4013
+ constructor(code2, message, details = {}) {
4014
+ super(message);
4015
+ this.code = code2;
4016
+ this.details = details;
4017
+ this.name = "CredentialError";
4018
+ this.recoverable = RECOVERABLE.has(code2);
4019
+ }
4020
+ };
4021
+
4022
+ // src/credentials/requirement.ts
4023
+ var ID = /^[a-z0-9][a-z0-9._-]{0,127}(?:\/v1)?$/;
4024
+ function validateCredentialRequirement(value) {
4025
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential requirement is invalid");
4026
+ const raw = value;
4027
+ if (Object.keys(raw).some((key) => !["type", "version", "profile", "credentialType", "claims", "maxAgeSeconds"].includes(key)) || raw.type !== "TinyCloudCredentialRequirement" || raw.version !== 1) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential requirement version is unsupported");
4028
+ const pair = (candidate, label) => {
4029
+ if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) throw new CredentialError("UNSUPPORTED_PROFILE", `${label} is invalid`);
4030
+ const item = candidate;
4031
+ if (Object.keys(item).length !== 2 || typeof item.id !== "string" || !ID.test(item.id) || item.version !== 1) throw new CredentialError("UNSUPPORTED_PROFILE", `${label} version is unsupported`);
4032
+ return { id: item.id, version: 1 };
4033
+ };
4034
+ if (typeof raw.claims !== "object" || raw.claims === null || Array.isArray(raw.claims)) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential claims are invalid");
4035
+ const claims = {};
4036
+ for (const [key, value2] of Object.entries(raw.claims).sort(([a], [b]) => a.localeCompare(b))) {
4037
+ if (!ID.test(key) || typeof value2 !== "string" || value2.length === 0 || value2.length > 4096) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential claim is invalid");
4038
+ claims[key] = value2;
4039
+ }
4040
+ if (raw.maxAgeSeconds !== void 0 && (!Number.isSafeInteger(raw.maxAgeSeconds) || raw.maxAgeSeconds < 1)) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential freshness is invalid");
4041
+ return Object.freeze({ type: "TinyCloudCredentialRequirement", version: 1, profile: pair(raw.profile, "profile"), credentialType: pair(raw.credentialType, "credentialType"), claims: Object.freeze(claims), ...raw.maxAgeSeconds === void 0 ? {} : { maxAgeSeconds: raw.maxAgeSeconds } });
4042
+ }
4043
+ async function credentialRequirementDigest(requirement) {
4044
+ return canonicalDigest(validateCredentialRequirement(requirement));
4045
+ }
4046
+
4047
+ // src/policy/credential-admission.ts
4048
+ var POLICY_V2_SCHEMA = "xyz.tinycloud.policy/policy/v2";
4049
+ var POLICY_V2_DOMAIN = "xyz.tinycloud.policy/policy/v2\0";
4050
+ var POLICY_CREDENTIAL_REQUIREMENT_V1_TYPE = "TinyCloudPolicyCredentialRequirement";
4051
+ var POLICY_PRESENTATION_V3_SCHEMA = "xyz.tinycloud.policy/presentation/v3";
4052
+ var POLICY_PRESENTATION_V3_DOMAIN = "xyz.tinycloud.policy/Presentation/v3\0";
4053
+ function record(value, label) {
4054
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
4055
+ throw new Error(`${label} must be an object`);
4056
+ }
4057
+ return value;
4058
+ }
4059
+ function exactKeys2(value, keys, label) {
4060
+ const expected = [...keys].sort();
4061
+ const actual = Object.keys(value).sort();
4062
+ if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) {
4063
+ throw new Error(`${label} contains an unknown or missing field`);
4064
+ }
4065
+ }
4066
+ function nonEmpty(value, label) {
4067
+ if (typeof value !== "string" || value.length === 0) {
4068
+ throw new Error(`${label} must be a non-empty string`);
4069
+ }
4070
+ return value;
4071
+ }
4072
+ function policyNodeOrigin(value) {
4073
+ let url;
4074
+ try {
4075
+ url = new URL(value);
4076
+ } catch {
4077
+ throw new Error("policy node origin is invalid");
4078
+ }
4079
+ if (url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.pathname !== "/" || url.search !== "" || url.hash !== "") {
4080
+ throw new Error("policy node origin is invalid");
4081
+ }
4082
+ return url.origin;
4083
+ }
4084
+ function versionPair(value, label) {
4085
+ const item = record(value, label);
4086
+ exactKeys2(item, ["id", "version"], label);
4087
+ if (item.version !== 1) throw new Error(`${label} version is unsupported`);
4088
+ return Object.freeze({ id: nonEmpty(item.id, `${label}.id`), version: 1 });
4089
+ }
4090
+ function validatePolicyCredentialRequirementV1(value) {
4091
+ const item = record(value, "policy credential requirement");
4092
+ exactKeys2(
4093
+ item,
4094
+ [
4095
+ "type",
4096
+ "version",
4097
+ "requirementDigest",
4098
+ "descriptorDigest",
4099
+ "issuerDid",
4100
+ "issuerKid",
4101
+ "profile",
4102
+ "credentialType"
4103
+ ],
4104
+ "policy credential requirement"
4105
+ );
4106
+ if (item.type !== POLICY_CREDENTIAL_REQUIREMENT_V1_TYPE || item.version !== 1 || !isDigest(item.requirementDigest) || !isDigest(item.descriptorDigest)) {
4107
+ throw new Error("policy credential requirement is invalid");
4108
+ }
4109
+ return Object.freeze({
4110
+ type: POLICY_CREDENTIAL_REQUIREMENT_V1_TYPE,
4111
+ version: 1,
4112
+ requirementDigest: item.requirementDigest,
4113
+ descriptorDigest: item.descriptorDigest,
4114
+ issuerDid: nonEmpty(item.issuerDid, "policy credential issuer"),
4115
+ issuerKid: nonEmpty(item.issuerKid, "policy credential issuer key"),
4116
+ profile: versionPair(item.profile, "policy credential profile"),
4117
+ credentialType: versionPair(
4118
+ item.credentialType,
4119
+ "policy credential type"
4120
+ )
4121
+ });
4122
+ }
4123
+ function hex2(bytes) {
4124
+ return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
4125
+ }
4126
+ function policyV2DigestHex(input) {
4127
+ const canonicalPolicy = {
4128
+ ...input,
4129
+ credentialRequirement: validatePolicyCredentialRequirementV1(
4130
+ input.credentialRequirement
4131
+ ),
4132
+ capabilityCeiling: input.capabilityCeiling.map(
4133
+ normalizeUnifiedPolicyCapability
4134
+ )
4135
+ };
4136
+ return hex2(
4137
+ (0, import_sha2562.sha256)(
4138
+ new TextEncoder().encode(
4139
+ POLICY_V2_DOMAIN + jcsCanonicalize(canonicalPolicy)
4140
+ )
4141
+ )
4142
+ );
4143
+ }
4144
+ function date(value, label) {
4145
+ const text = nonEmpty(value, label);
4146
+ if (!Number.isFinite(Date.parse(text))) throw new Error(`${label} is invalid`);
4147
+ return text;
4148
+ }
4149
+ function rfc3339Seconds(value) {
4150
+ return new Date(Math.floor(value.getTime() / 1e3) * 1e3).toISOString().replace(/\.000Z$/, "Z");
4151
+ }
4152
+ function validateUnifiedPolicyV2(value, expectedPolicyCid) {
4153
+ const item = record(value, "Policy/v2");
4154
+ const allowed = [
4155
+ "schema",
4156
+ "policyId",
4157
+ "ownerDid",
4158
+ "createdAt",
4159
+ "contentSource",
4160
+ "capabilityCeiling",
4161
+ "credentialRequirement",
4162
+ "signature",
4163
+ ...item.expiresAt === void 0 ? [] : ["expiresAt"]
4164
+ ];
4165
+ exactKeys2(item, allowed, "Policy/v2");
4166
+ if (item.schema !== POLICY_V2_SCHEMA || !Array.isArray(item.capabilityCeiling)) {
4167
+ throw new Error("Policy/v2 is invalid");
4168
+ }
4169
+ const ownerDid = nonEmpty(item.ownerDid, "Policy/v2 ownerDid");
4170
+ const signature = record(item.signature, "Policy/v2 signature");
4171
+ exactKeys2(signature, ["suite", "signerDid", "value"], "Policy/v2 signature");
4172
+ if (signature.suite !== "Ed25519" || signature.signerDid !== ownerDid || typeof signature.value !== "string" || signature.value.length === 0) {
4173
+ throw new Error("Policy/v2 signature binding is invalid");
4174
+ }
4175
+ const policy = Object.freeze({
4176
+ schema: POLICY_V2_SCHEMA,
4177
+ policyId: nonEmpty(item.policyId, "Policy/v2 policyId"),
4178
+ ownerDid,
4179
+ createdAt: date(item.createdAt, "Policy/v2 createdAt"),
4180
+ ...item.expiresAt === void 0 ? {} : { expiresAt: date(item.expiresAt, "Policy/v2 expiresAt") },
4181
+ contentSource: item.contentSource,
4182
+ capabilityCeiling: Object.freeze(
4183
+ item.capabilityCeiling.map(normalizeUnifiedPolicyCapability)
4184
+ ),
4185
+ credentialRequirement: validatePolicyCredentialRequirementV1(
4186
+ item.credentialRequirement
4187
+ ),
4188
+ signature: Object.freeze({
4189
+ suite: "Ed25519",
4190
+ signerDid: ownerDid,
4191
+ value: signature.value
4192
+ })
4193
+ });
4194
+ const unsigned = { ...policy };
4195
+ delete unsigned.policyId;
4196
+ delete unsigned.signature;
4197
+ const digestHex = policyV2DigestHex(unsigned);
4198
+ if (policy.policyId !== policyIdForDigestHex(digestHex)) {
4199
+ throw new Error("Policy/v2 policyId binding is invalid");
4200
+ }
4201
+ if (expectedPolicyCid !== void 0) {
4202
+ const cid = policyCidFromCanonicalBytes(
4203
+ new TextEncoder().encode(jcsCanonicalize(policy))
4204
+ );
4205
+ if (cid !== expectedPolicyCid) throw new Error("Policy/v2 CID binding is invalid");
4206
+ }
4207
+ return policy;
4208
+ }
4209
+ function didKeyBytes(did) {
4210
+ const principal = did.split("#", 1)[0];
4211
+ if (!principal.startsWith("did:key:")) throw new Error("holder DID must be did:key");
4212
+ const material = base58btc.decode(principal.slice("did:key:".length));
4213
+ if (material.length !== 34 || material[0] !== 237 || material[1] !== 1) {
4214
+ throw new Error("holder DID must contain an Ed25519 key");
4215
+ }
4216
+ return material.slice(2);
4217
+ }
4218
+ function envelopeFromVerified(verified) {
4219
+ const {
4220
+ verifiedAt: _verifiedAt,
4221
+ credentialDigest: _credentialDigest,
4222
+ statusCheckedAt: _statusCheckedAt,
4223
+ ...envelope
4224
+ } = verified;
4225
+ return envelope;
4226
+ }
4227
+ async function buildPolicyCredentialPresentationV3(input) {
4228
+ const policy = validateUnifiedPolicyV2(input.policy, input.policyCid);
4229
+ const requirement = validateCredentialRequirement(input.requirement);
4230
+ const commitment = policy.credentialRequirement;
4231
+ const requirementDigest = await credentialRequirementDigest(requirement);
4232
+ const credentialDigest = await sha256Base64Url(input.credential.credential);
4233
+ if (requirementDigest !== commitment.requirementDigest || input.credential.descriptorDigest !== commitment.descriptorDigest || input.credential.credentialDigest !== credentialDigest || input.credential.issuerDid !== commitment.issuerDid || input.credential.issuerKid !== commitment.issuerKid || jcsCanonicalize(input.credential.profile) !== jcsCanonicalize(commitment.profile) || jcsCanonicalize(input.credential.credentialType) !== jcsCanonicalize(commitment.credentialType)) {
4234
+ throw new Error("credential does not match the signed Policy/v2 requirement");
4235
+ }
4236
+ const requestedCapabilities = input.requestedCapabilities.map(
4237
+ normalizeUnifiedPolicyCapability
4238
+ );
4239
+ if (requestedCapabilities.length === 0 || requestedCapabilities.some(
4240
+ (requested) => !policy.capabilityCeiling.some(
4241
+ (authority) => unifiedPolicyCapabilityContains(authority, requested)
4242
+ )
4243
+ )) {
4244
+ throw new Error("requested capabilities exceed the signed Policy/v2 ceiling");
4245
+ }
4246
+ const challenge = input.challenge;
4247
+ const holderDid = input.credential.holderDid;
4248
+ if (challenge.policyCid !== input.policyCid || challenge.recipientDid !== holderDid || input.credential.subjectDid !== holderDid || typeof challenge.nodeAudience !== "string" || challenge.nodeAudience.length === 0 || typeof challenge.expiresAt !== "string" || !Number.isFinite(Date.parse(challenge.expiresAt))) {
4249
+ throw new Error("policy challenge binding is invalid");
4250
+ }
4251
+ didKeyBytes(holderDid);
4252
+ const now = input.now ?? /* @__PURE__ */ new Date();
4253
+ const challengeExpiry = Date.parse(challenge.expiresAt);
4254
+ const credentialExpiry = Date.parse(input.credential.expiresAt);
4255
+ const expiresAtMs = Math.min(
4256
+ now.getTime() + 6e4,
4257
+ challengeExpiry,
4258
+ credentialExpiry
4259
+ );
4260
+ if (expiresAtMs <= now.getTime()) throw new Error("policy challenge is expired");
4261
+ const unsigned = Object.freeze({
4262
+ schema: POLICY_PRESENTATION_V3_SCHEMA,
4263
+ jti: input.jti ?? encodeBase64Url2(crypto.getRandomValues(new Uint8Array(16))),
4264
+ challengeId: challenge.challengeId,
4265
+ nonce: challenge.nonce,
4266
+ policyCid: input.policyCid,
4267
+ nodeAudience: challenge.nodeAudience,
4268
+ holderDid,
4269
+ subjectDid: input.credential.subjectDid,
4270
+ credentialSpaceOwnerDid: nonEmpty(
4271
+ input.credentialSpaceOwnerDid,
4272
+ "credential space owner DID"
4273
+ ),
4274
+ credentialDigest,
4275
+ requirementDigest,
4276
+ descriptorDigest: input.credential.descriptorDigest,
4277
+ requestedCapabilities: Object.freeze(requestedCapabilities),
4278
+ issuedAt: rfc3339Seconds(now),
4279
+ expiresAt: rfc3339Seconds(new Date(expiresAtMs))
4280
+ });
4281
+ const digest2 = (0, import_sha2562.sha256)(
4282
+ new TextEncoder().encode(
4283
+ POLICY_PRESENTATION_V3_DOMAIN + jcsCanonicalize(unsigned)
4284
+ )
4285
+ );
4286
+ const signature = await input.sign(digest2);
4287
+ if (signature.length !== 64 || !import_ed255193.ed25519.verify(signature, digest2, didKeyBytes(holderDid))) {
4288
+ throw new Error("policy presentation signature is invalid");
4289
+ }
4290
+ return Object.freeze({
4291
+ ...unsigned,
4292
+ signature: Object.freeze({
4293
+ suite: "Ed25519",
4294
+ signerDid: holderDid,
4295
+ value: encodeBase64Url2(signature)
4296
+ })
4297
+ });
4298
+ }
4299
+ async function admitPolicyCredentialV3(input) {
4300
+ const policy = validateUnifiedPolicyV2(input.policy, input.policyCid);
4301
+ const nodeOrigin = policyNodeOrigin(input.nodeOrigin);
4302
+ const accountAuthorizationCid = nonEmpty(
4303
+ input.accountAuthorizationCid,
4304
+ "account authorization CID"
4305
+ );
4306
+ const credentialSpaceId = nonEmpty(
4307
+ input.credentialSpaceId,
4308
+ "credential space ID"
4309
+ );
4310
+ const fetchFn = input.fetch ?? globalThis.fetch.bind(globalThis);
4311
+ const challenge = await requestPolicyChallengeV3({
4312
+ nodeOrigin,
4313
+ policyCid: input.policyCid,
4314
+ recipientDid: input.credential.holderDid,
4315
+ requestedCapabilities: input.requestedCapabilities,
4316
+ fetch: fetchFn
4317
+ });
4318
+ const presentation = await buildPolicyCredentialPresentationV3({
4319
+ ...input,
4320
+ policy,
4321
+ challenge
4322
+ });
4323
+ const response = await fetchFn(
4324
+ new URL("/share/v3/policy/delegations", nodeOrigin),
4325
+ {
4326
+ method: "POST",
4327
+ redirect: "error",
4328
+ headers: { accept: "application/json", "content-type": "application/json" },
4329
+ body: JSON.stringify({
4330
+ policyCid: input.policyCid,
4331
+ challengeId: challenge.challengeId,
4332
+ nonce: challenge.nonce,
4333
+ requirement: validateCredentialRequirement(input.requirement),
4334
+ credential: envelopeFromVerified(input.credential),
4335
+ accountAuthorizationCid,
4336
+ credentialSpaceId,
4337
+ presentation
4338
+ })
4339
+ }
4340
+ );
4341
+ if (!response.ok) throw new Error(`policy delegation rejected (${response.status})`);
4342
+ const value = record(await response.json(), "policy delegation");
4343
+ if (value.admitted !== true || typeof value.sessionCid !== "string" || typeof value.authorization !== "string") {
4344
+ throw new Error("policy delegation response is invalid");
4345
+ }
4346
+ const session = parsePolicySessionUcan(value.authorization, [
4347
+ input.policyRootCid,
4348
+ input.enforcementRootCid
4349
+ ]);
4350
+ const expectedAttenuation = compactAttenuationForPolicyCapabilities(
4351
+ input.requestedCapabilities
4352
+ );
4353
+ if (session.cid !== value.sessionCid || session.aud !== input.credential.holderDid || session.fact.policyCid !== input.policyCid || session.fact.recipientDid !== input.credential.holderDid || session.fact.policyDelegationCid !== input.policyRootCid || session.fact.enforcementDelegationCid !== input.enforcementRootCid || jcsCanonicalize(session.att) !== jcsCanonicalize(expectedAttenuation)) {
4354
+ throw new Error("policy delegation signed binding is invalid");
4355
+ }
4356
+ return Object.freeze({ challenge, presentation, session });
3259
4357
  }
3260
4358
  //# sourceMappingURL=index.cjs.map