@floegence/redevplugin-contracts 0.7.26 → 1.0.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.
@@ -2,19 +2,11 @@ export const rootDelegationSchemaVersion = "redevplugin.release_root_delegation.
2
2
  export const packageSignatureSchemaVersion = "redevplugin.package_signature.v1";
3
3
  export const releaseMetadataSchemaVersionV8 = "redevplugin.release_metadata.v8";
4
4
  export const releaseMetadataSchemaVersion = releaseMetadataSchemaVersionV8;
5
- export const sourcePolicySchemaVersion = "redevplugin.release_source_policy.v2";
5
+ export const sourcePolicySchemaVersion = "redevplugin.release_source_policy.v3";
6
6
  export const sourcePolicyPointerSchemaVersion = "redevplugin.release_source_policy_pointer.v1";
7
7
  export const revocationSchemaVersion = "redevplugin.release_revocation.v2";
8
8
  export const revocationPointerSchemaVersion = "redevplugin.release_revocation_pointer.v1";
9
- export const releaseSigningLedgerEvidenceSchemaVersion = "redevplugin.release_signing_ledger_evidence.v1";
10
- export const signingSubjectSchemaVersion = "redevplugin.release_signing_subject.v1";
11
- export const signatureEnvelopeSchemaVersion = "redevplugin.release_signature_envelope.v1";
12
- export const signingLedgerSchemaVersion = "redevplugin.release_signing_ledger.v1";
13
- export const signingLedgerEntrySchemaVersion = "redevplugin.release_signing_ledger_entry.v1";
14
- export const signingLedgerLogLeafSchemaVersion = "redevplugin.release_signing_ledger_log_leaf.v1";
15
- export const signingLedgerReceiptSchemaVersion = "redevplugin.release_signing_ledger_receipt.v1";
16
9
  export const signatureAlgorithmEd25519 = "ed25519";
17
- export const genesisPreviousEpoch = "0";
18
10
  export const genesisPreviousDocumentSHA256 = "0".repeat(64);
19
11
  export const signingUsages = {
20
12
  rootDelegation: "redevplugin.release-signing.root-delegation.v1",
@@ -26,9 +18,8 @@ export const signingUsages = {
26
18
  revocationPointer: "redevplugin.release-signing.revocation-pointer.v1",
27
19
  };
28
20
  export const defaultSourcePolicyLimits = Object.freeze({
29
- document_max_lifetime_seconds: 86400,
21
+ document_max_lifetime_seconds: 7776000,
30
22
  future_skew_seconds: 300,
31
- activation_lease_max_seconds: 300,
32
23
  refresh_interval_max_seconds: 60,
33
24
  failure_teardown_deadline_seconds: 30,
34
25
  });
@@ -65,13 +56,10 @@ const signaturePattern = /^[A-Za-z0-9+/]{86}==$/;
65
56
  const delegatedUsageOrder = [
66
57
  "package",
67
58
  "release_metadata",
68
- "host_capability_contract",
69
59
  "revocation_document",
70
60
  "revocation_pointer",
71
61
  "source_policy_document",
72
62
  "source_policy_pointer",
73
- "signing_ledger",
74
- "trusted_time",
75
63
  ];
76
64
  function invalidDocument() {
77
65
  throw new InvalidReleaseDocumentError();
@@ -267,20 +255,6 @@ function validateTimeRange(generatedAt, expiresAt, maximumMilliseconds = 0) {
267
255
  invalidDocument();
268
256
  }
269
257
  }
270
- function validateEpochChain(epoch, previousEpoch, previousDigest) {
271
- if (!matchesPattern(positiveEpochPattern, epoch) || !matchesPattern(epochPattern, previousEpoch) || !matchesPattern(sha256Pattern, previousDigest)) {
272
- invalidDocument();
273
- }
274
- if (BigInt(previousEpoch) + 1n !== BigInt(epoch))
275
- invalidDocument();
276
- if (previousEpoch === genesisPreviousEpoch) {
277
- if (previousDigest !== genesisPreviousDocumentSHA256)
278
- invalidDocument();
279
- }
280
- else if (previousDigest === genesisPreviousDocumentSHA256) {
281
- invalidDocument();
282
- }
283
- }
284
258
  function validateSortedIDs(values, minimum, maximum, lower = true) {
285
259
  if (!Array.isArray(values) || values.length < minimum || values.length > maximum)
286
260
  invalidDocument();
@@ -303,7 +277,8 @@ function validateRootDelegation(value, requireSignature) {
303
277
  closeRootDelegation(value);
304
278
  if (value.schema_version !== rootDelegationSchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.key_id))
305
279
  invalidDocument();
306
- validateEpochChain(value.root_epoch, value.previous_root_epoch, value.previous_delegation_sha256);
280
+ if (!matchesPattern(positiveEpochPattern, value.root_epoch))
281
+ invalidDocument();
307
282
  validateTimeRange(value.generated_at, value.expires_at);
308
283
  if (!Array.isArray(value.delegated_keys) || value.delegated_keys.length < 1 || value.delegated_keys.length > 32)
309
284
  invalidDocument();
@@ -321,11 +296,7 @@ function validateRootDelegation(value, requireSignature) {
321
296
  invalidDocument();
322
297
  previousUsage = rank;
323
298
  }
324
- const sourceWide = key.usages.every((usage) => usage === "signing_ledger" || usage === "trusted_time");
325
- const hasSourceWide = key.usages.some((usage) => usage === "signing_ledger" || usage === "trusted_time");
326
- if (hasSourceWide !== sourceWide)
327
- invalidDocument();
328
- validateSortedIDs(key.channels, sourceWide ? 0 : 1, sourceWide ? 0 : 16);
299
+ validateSortedIDs(key.channels, 1, 16);
329
300
  validateTimeRange(key.valid_from, key.valid_until);
330
301
  if (parseCanonicalTime(key.valid_until) > parseCanonicalTime(value.expires_at))
331
302
  invalidDocument();
@@ -445,13 +416,8 @@ function validReleaseMetadataUIProtocolPair(schemaVersion, uiProtocolVersion) {
445
416
  return schemaVersion === releaseMetadataSchemaVersionV8 && uiProtocolVersion === "plugin-ui-v7";
446
417
  }
447
418
  function validateCapabilityContractRef(value) {
448
- if (![value.publisher_id, value.contract_id, value.signature_key_id].every((item) => matchesPattern(legacyIDPattern, item)) || !matchesPattern(semverPattern, value.contract_version))
449
- invalidDocument();
450
- if (!matchesPattern(epochPattern, value.signature_policy_epoch) || !matchesPattern(epochPattern, value.signature_revocation_epoch))
451
- invalidDocument();
452
- if (![value.artifact_ref, value.manifest_ref, value.signature_ref, value.compatibility_ref, value.generated_client_ref, value.notices_ref].every(validArtifactRef))
453
- invalidDocument();
454
- if (![value.artifact_sha256, value.manifest_sha256, value.signature_sha256, value.compatibility_sha256, value.generated_client_sha256, value.notices_sha256].every((item) => sha256Pattern.test(item)))
419
+ if (![value.publisher_id, value.contract_id].every((item) => matchesPattern(legacyIDPattern, item)) ||
420
+ !matchesPattern(semverPattern, value.contract_version) || !sha256Pattern.test(value.artifact_sha256))
455
421
  invalidDocument();
456
422
  }
457
423
  function validateSourcePolicy(value, requireSignature) {
@@ -459,7 +425,8 @@ function validateSourcePolicy(value, requireSignature) {
459
425
  closeSourcePolicy(value);
460
426
  if (value.schema_version !== sourcePolicySchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.channel) || !matchesPattern(newIDPattern, value.key_id))
461
427
  invalidDocument();
462
- validateEpochChain(value.epoch, value.previous_epoch, value.previous_document_sha256);
428
+ if (!matchesPattern(positiveEpochPattern, value.epoch))
429
+ invalidDocument();
463
430
  if (!matchesPattern(positiveEpochPattern, value.root_epoch) || !matchesPattern(epochPattern, value.minimum_revocation_epoch))
464
431
  invalidDocument();
465
432
  if (value.source_type !== "registry" && value.source_type !== "host_artifact")
@@ -483,17 +450,6 @@ function validateSourcePolicy(value, requireSignature) {
483
450
  value.active_keys.revocation_pointer,
484
451
  ])
485
452
  validateSortedIDs(keys, 1, 16);
486
- validateSortedIDs(value.active_keys.host_capability_contract, 0, 16);
487
- if (!Array.isArray(value.capability_publisher_scopes) || value.capability_publisher_scopes.length !== value.active_keys.host_capability_contract.length)
488
- invalidDocument();
489
- for (let index = 0; index < value.capability_publisher_scopes.length; index += 1) {
490
- const scope = value.capability_publisher_scopes[index];
491
- assertRecord(scope);
492
- exactKeys(scope, ["key_id", "allowed_publishers"]);
493
- if (scope.key_id !== value.active_keys.host_capability_contract[index])
494
- invalidDocument();
495
- validateSortedIDs(scope.allowed_publishers, 1, 1024, false);
496
- }
497
453
  if (!new Set(["allow", "review_required", "block"]).has(value.install_policy))
498
454
  invalidDocument();
499
455
  if (!new Set(["dev_only", "review_required", "block"]).has(value.unsigned_policy))
@@ -502,7 +458,7 @@ function validateSourcePolicy(value, requireSignature) {
502
458
  invalidDocument();
503
459
  if (canonicalJSONString(value.limits) !== canonicalJSONString(defaultSourcePolicyLimits))
504
460
  invalidDocument();
505
- validateTimeRange(value.generated_at, value.expires_at, 24 * 60 * 60 * 1000);
461
+ validateTimeRange(value.generated_at, value.expires_at, 90 * 24 * 60 * 60 * 1000);
506
462
  if (requireSignature)
507
463
  decodeBase64(value.signature, 64);
508
464
  else if (value.signature !== "")
@@ -513,7 +469,8 @@ function validatePointer(value, expectedSchemaVersion, requireSignature) {
513
469
  closePointer(value);
514
470
  if (value.schema_version !== expectedSchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.channel) || !matchesPattern(newIDPattern, value.key_id))
515
471
  invalidDocument();
516
- validateEpochChain(value.epoch, value.previous_epoch, value.previous_document_sha256);
472
+ if (!matchesPattern(positiveEpochPattern, value.epoch))
473
+ invalidDocument();
517
474
  if (!validArtifactRef(value.ref) || !sha256Pattern.test(value.document_sha256) || value.document_sha256 === genesisPreviousDocumentSHA256)
518
475
  invalidDocument();
519
476
  validateTimeRange(value.generated_at, value.expires_at, 24 * 60 * 60 * 1000);
@@ -527,7 +484,8 @@ function validateRevocation(value, requireSignature) {
527
484
  closeRevocation(value);
528
485
  if (value.schema_version !== revocationSchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.channel) || !matchesPattern(newIDPattern, value.key_id))
529
486
  invalidDocument();
530
- validateEpochChain(value.epoch, value.previous_epoch, value.previous_document_sha256);
487
+ if (!matchesPattern(positiveEpochPattern, value.epoch))
488
+ invalidDocument();
531
489
  if (!matchesPattern(positiveEpochPattern, value.root_epoch))
532
490
  invalidDocument();
533
491
  validateTimeRange(value.generated_at, value.expires_at, 24 * 60 * 60 * 1000);
@@ -550,181 +508,6 @@ function validateRevocation(value, requireSignature) {
550
508
  else if (value.signature !== "")
551
509
  invalidDocument();
552
510
  }
553
- function validateSigningLedgerEvidence(value) {
554
- assertRecord(value);
555
- closeSigningLedgerEvidence(value);
556
- if (value.schema_version !== releaseSigningLedgerEvidenceSchemaVersion || !matchesPattern(newIDPattern, value.source_id))
557
- invalidDocument();
558
- if (value.channel !== undefined && !matchesPattern(newIDPattern, value.channel))
559
- invalidDocument();
560
- for (const digest of [
561
- value.subject_identity_sha256,
562
- value.signing_preimage_sha256,
563
- value.signature_envelope_sha256,
564
- value.receipt_sha256,
565
- value.checkpoint_sha256,
566
- value.inclusion_proof_sha256,
567
- value.latest_proof_sha256,
568
- ]) {
569
- if (!sha256Pattern.test(digest))
570
- invalidDocument();
571
- }
572
- for (const reference of [
573
- value.receipt_ref,
574
- value.checkpoint_ref,
575
- value.inclusion_proof_ref,
576
- value.latest_proof_ref,
577
- ]) {
578
- if (!validArtifactRef(reference))
579
- invalidDocument();
580
- }
581
- if ((value.consistency_proof_ref === undefined) !== (value.consistency_proof_sha256 === undefined))
582
- invalidDocument();
583
- if (value.consistency_proof_ref !== undefined && (!validArtifactRef(value.consistency_proof_ref) || !sha256Pattern.test(value.consistency_proof_sha256)))
584
- invalidDocument();
585
- }
586
- function validateSigningSubject(value) {
587
- assertRecord(value);
588
- closeSigningSubject(value);
589
- if (value.schema_version !== signingSubjectSchemaVersion || !matchesPattern(newIDPattern, value.source_id))
590
- invalidDocument();
591
- if (value.usage === "root_delegation") {
592
- if (!matchesPattern(positiveEpochPattern, value.root_epoch))
593
- invalidDocument();
594
- return;
595
- }
596
- if (value.usage === "package" || value.usage === "release_metadata") {
597
- if (!matchesPattern(newIDPattern, value.channel) || !matchesPattern(legacyIDPattern, value.publisher_id) ||
598
- !matchesPattern(legacyIDPattern, value.plugin_id) || !matchesPattern(semverPattern, value.version) ||
599
- !matchesPattern(sha256Pattern, value.artifact_or_metadata_identity_sha256))
600
- invalidDocument();
601
- return;
602
- }
603
- if (["source_policy_document", "source_policy_pointer", "revocation_document", "revocation_pointer"].includes(value.usage)) {
604
- if (!matchesPattern(newIDPattern, value.channel) || !matchesPattern(positiveEpochPattern, value.epoch))
605
- invalidDocument();
606
- return;
607
- }
608
- invalidDocument();
609
- }
610
- function validateSignatureEnvelope(value) {
611
- assertRecord(value);
612
- closeSignatureEnvelope(value);
613
- if (value.schema_version !== signatureEnvelopeSchemaVersion || !matchesPattern(sha256Pattern, value.subject_identity_sha256) ||
614
- !matchesPattern(sha256Pattern, value.signing_preimage_sha256) || value.algorithm !== signatureAlgorithmEd25519 ||
615
- !matchesPattern(newIDPattern, value.key_id))
616
- invalidDocument();
617
- decodeBase64(value.signature, 64);
618
- }
619
- function validateSigningLedgerEntry(value) {
620
- assertRecord(value);
621
- closeSigningLedgerEntry(value);
622
- if (value.schema_version !== signingLedgerEntrySchemaVersion || !matchesPattern(sha256Pattern, value.subject_identity_sha256) ||
623
- !matchesPattern(sha256Pattern, value.signing_preimage_sha256) || value.algorithm !== signatureAlgorithmEd25519 ||
624
- !matchesPattern(newIDPattern, value.key_id) || !Number.isSafeInteger(value.revision) || value.revision < 1)
625
- invalidDocument();
626
- validateSigningSubject(value.subject);
627
- const reservedAt = parseCanonicalTime(value.reserved_at);
628
- if (value.state === "reserved") {
629
- if (value.signature_envelope !== undefined || value.signature_envelope_sha256 !== undefined || value.finalized_at !== undefined ||
630
- value.failure_code !== undefined || value.failed_at !== undefined)
631
- invalidDocument();
632
- return;
633
- }
634
- if (value.state === "finalized") {
635
- if (value.signature_envelope === undefined || !matchesPattern(sha256Pattern, value.signature_envelope_sha256) ||
636
- value.finalized_at === undefined || value.failure_code !== undefined || value.failed_at !== undefined)
637
- invalidDocument();
638
- validateSignatureEnvelope(value.signature_envelope);
639
- if (value.signature_envelope.subject_identity_sha256 !== value.subject_identity_sha256 ||
640
- value.signature_envelope.signing_preimage_sha256 !== value.signing_preimage_sha256 ||
641
- value.signature_envelope.algorithm !== value.algorithm || value.signature_envelope.key_id !== value.key_id ||
642
- parseCanonicalTime(value.finalized_at) < reservedAt)
643
- invalidDocument();
644
- return;
645
- }
646
- if (value.state === "terminal_failed") {
647
- if (value.signature_envelope !== undefined || value.signature_envelope_sha256 !== undefined || value.finalized_at !== undefined ||
648
- value.failure_code === undefined || !["signer_rejected", "subject_conflict", "ledger_rejected"].includes(value.failure_code) ||
649
- value.failed_at === undefined || parseCanonicalTime(value.failed_at) < reservedAt)
650
- invalidDocument();
651
- return;
652
- }
653
- invalidDocument();
654
- }
655
- function validateSigningLedgerLogLeaf(value) {
656
- assertRecord(value);
657
- closeSigningLedgerLogLeaf(value);
658
- if (value.schema_version !== signingLedgerLogLeafSchemaVersion || !matchesPattern(newIDPattern, value.source_id) ||
659
- (value.channel !== undefined && !matchesPattern(newIDPattern, value.channel)) ||
660
- !matchesPattern(sha256Pattern, value.subject_identity_sha256) || !matchesPattern(sha256Pattern, value.signing_preimage_sha256) ||
661
- !matchesPattern(sha256Pattern, value.signature_envelope_sha256) || !Number.isSafeInteger(value.sequence) || value.sequence < 1)
662
- invalidDocument();
663
- }
664
- function validateSigningLedgerCheckpoint(value) {
665
- assertRecord(value);
666
- closeSigningLedgerCheckpoint(value);
667
- if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "checkpoint" || !matchesPattern(newIDPattern, value.log_id) ||
668
- !Number.isSafeInteger(value.tree_size) || value.tree_size < 1 || !matchesPattern(sha256Pattern, value.log_root_hash) ||
669
- !matchesPattern(sha256Pattern, value.latest_map_root_hash) || !matchesPattern(newIDPattern, value.key_id))
670
- invalidDocument();
671
- parseCanonicalTime(value.checkpoint_time);
672
- decodeBase64(value.signature, 64);
673
- }
674
- function validateSigningLedgerReceipt(value) {
675
- assertRecord(value);
676
- closeSigningLedgerReceipt(value);
677
- if (value.schema_version !== signingLedgerReceiptSchemaVersion || !matchesPattern(newIDPattern, value.log_id) ||
678
- !matchesPattern(newIDPattern, value.source_id) || (value.channel !== undefined && !matchesPattern(newIDPattern, value.channel)) ||
679
- !matchesPattern(sha256Pattern, value.subject_identity_sha256) || !matchesPattern(sha256Pattern, value.signing_preimage_sha256) ||
680
- !matchesPattern(sha256Pattern, value.signature_envelope_sha256) || !Number.isSafeInteger(value.sequence) || value.sequence < 1 ||
681
- !Number.isSafeInteger(value.leaf_index) || value.leaf_index !== value.sequence - 1 || !Number.isSafeInteger(value.tree_size) ||
682
- value.tree_size < value.sequence || !matchesPattern(sha256Pattern, value.log_root_hash) ||
683
- !matchesPattern(sha256Pattern, value.latest_map_root_hash) || !matchesPattern(sha256Pattern, value.checkpoint_sha256) ||
684
- !matchesPattern(newIDPattern, value.key_id))
685
- invalidDocument();
686
- parseCanonicalTime(value.checkpoint_time);
687
- decodeBase64(value.signature, 64);
688
- }
689
- function validateLedgerNodes(value, exact) {
690
- if (!Array.isArray(value) || (exact === undefined ? value.length > 64 : value.length !== exact) ||
691
- value.some((node) => !matchesPattern(sha256Pattern, node)))
692
- invalidDocument();
693
- }
694
- function validateSigningLedgerInclusionProof(value) {
695
- assertRecord(value);
696
- closeSigningLedgerInclusionProof(value);
697
- if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "inclusion_proof" || !matchesPattern(newIDPattern, value.log_id) ||
698
- !Number.isSafeInteger(value.leaf_index) || value.leaf_index < 0 || !Number.isSafeInteger(value.tree_size) ||
699
- value.tree_size < 1 || value.leaf_index >= value.tree_size)
700
- invalidDocument();
701
- validateLedgerNodes(value.nodes);
702
- }
703
- function validateSigningLedgerLatestProof(value) {
704
- assertRecord(value);
705
- closeSigningLedgerLatestProof(value);
706
- if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "latest_proof" || !matchesPattern(newIDPattern, value.log_id) ||
707
- !matchesPattern(sha256Pattern, value.subject_identity_sha256) || typeof value.present !== "boolean")
708
- invalidDocument();
709
- validateLedgerNodes(value.siblings, 256);
710
- if (value.present) {
711
- if (!Number.isSafeInteger(value.sequence) || value.sequence < 1 || !matchesPattern(sha256Pattern, value.signing_preimage_sha256) ||
712
- !matchesPattern(sha256Pattern, value.signature_envelope_sha256))
713
- invalidDocument();
714
- }
715
- else if (value.sequence !== undefined || value.signing_preimage_sha256 !== undefined || value.signature_envelope_sha256 !== undefined) {
716
- invalidDocument();
717
- }
718
- }
719
- function validateSigningLedgerConsistencyProof(value) {
720
- assertRecord(value);
721
- closeSigningLedgerConsistencyProof(value);
722
- if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "consistency_proof" || !matchesPattern(newIDPattern, value.log_id) ||
723
- !Number.isSafeInteger(value.old_tree_size) || value.old_tree_size < 1 || !Number.isSafeInteger(value.new_tree_size) ||
724
- value.new_tree_size < value.old_tree_size)
725
- invalidDocument();
726
- validateLedgerNodes(value.nodes);
727
- }
728
511
  function decodeCanonicalDocument(raw, close, validate) {
729
512
  const bytes = typeof raw === "string" ? textEncoder.encode(raw) : raw;
730
513
  if (!(bytes instanceof Uint8Array) || bytes.length < 1 || bytes.length > maximumDocumentBytes)
@@ -751,7 +534,7 @@ function decodeCanonicalDocument(raw, close, validate) {
751
534
  return deepFreeze(cloneJSON(parsed));
752
535
  }
753
536
  function closeRootDelegation(value) {
754
- exactKeys(value, ["schema_version", "source_id", "root_epoch", "previous_root_epoch", "previous_delegation_sha256", "generated_at", "expires_at", "delegated_keys", "key_id", "signature"]);
537
+ exactKeys(value, ["schema_version", "source_id", "root_epoch", "generated_at", "expires_at", "delegated_keys", "key_id", "signature"]);
755
538
  if (!Array.isArray(value.delegated_keys))
756
539
  invalidDocument();
757
540
  for (const item of value.delegated_keys) {
@@ -788,7 +571,7 @@ function closeReleaseMetadata(value) {
788
571
  assertRecord(requirement);
789
572
  exactKeys(requirement, ["capability_id", "capability_version", "contract"]);
790
573
  assertRecord(requirement.contract);
791
- exactKeys(requirement.contract, ["publisher_id", "contract_id", "contract_version", "artifact_ref", "artifact_sha256", "manifest_ref", "manifest_sha256", "signature_ref", "signature_sha256", "signature_key_id", "signature_policy_epoch", "signature_revocation_epoch", "compatibility_ref", "compatibility_sha256", "generated_client_ref", "generated_client_sha256", "notices_ref", "notices_sha256"]);
574
+ exactKeys(requirement.contract, ["publisher_id", "contract_id", "contract_version", "artifact_sha256"]);
792
575
  }
793
576
  }
794
577
  }
@@ -801,17 +584,17 @@ function closeReleaseMetadata(value) {
801
584
  assertRecord(value.metadata);
802
585
  }
803
586
  function closeSourcePolicy(value) {
804
- exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "previous_epoch", "previous_document_sha256", "root_epoch", "source_type", "source_class", "allowed_publishers", "allowed_artifact_hosts", "active_keys", "capability_publisher_scopes", "require_signature", "install_policy", "unsigned_policy", "downgrade_policy", "minimum_revocation_epoch", "limits", "generated_at", "expires_at", "key_id", "signature"]);
587
+ exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "root_epoch", "source_type", "source_class", "allowed_publishers", "allowed_artifact_hosts", "active_keys", "require_signature", "install_policy", "unsigned_policy", "downgrade_policy", "minimum_revocation_epoch", "limits", "generated_at", "expires_at", "key_id", "signature"]);
805
588
  assertRecord(value.active_keys);
806
- exactKeys(value.active_keys, ["package", "release_metadata", "host_capability_contract", "source_policy_pointer", "revocation_document", "revocation_pointer"]);
589
+ exactKeys(value.active_keys, ["package", "release_metadata", "source_policy_pointer", "revocation_document", "revocation_pointer"]);
807
590
  assertRecord(value.limits);
808
- exactKeys(value.limits, ["document_max_lifetime_seconds", "future_skew_seconds", "activation_lease_max_seconds", "refresh_interval_max_seconds", "failure_teardown_deadline_seconds"]);
591
+ exactKeys(value.limits, ["document_max_lifetime_seconds", "future_skew_seconds", "refresh_interval_max_seconds", "failure_teardown_deadline_seconds"]);
809
592
  }
810
593
  function closePointer(value) {
811
- exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "previous_epoch", "previous_document_sha256", "ref", "document_sha256", "generated_at", "expires_at", "key_id", "signature"]);
594
+ exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "ref", "document_sha256", "generated_at", "expires_at", "key_id", "signature"]);
812
595
  }
813
596
  function closeRevocation(value) {
814
- exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "previous_epoch", "previous_document_sha256", "root_epoch", "generated_at", "expires_at", "revoked_key_ids", "revoked_releases", "key_id", "signature"]);
597
+ exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "root_epoch", "generated_at", "expires_at", "revoked_key_ids", "revoked_releases", "key_id", "signature"]);
815
598
  if (!Array.isArray(value.revoked_releases))
816
599
  invalidDocument();
817
600
  for (const item of value.revoked_releases) {
@@ -819,77 +602,6 @@ function closeRevocation(value) {
819
602
  exactKeys(item, ["publisher_id", "plugin_id", "version", "release_metadata_sha256", "revoked_at"]);
820
603
  }
821
604
  }
822
- function closeSigningLedgerEvidence(value) {
823
- exactOptionalKeys(value, [
824
- "schema_version",
825
- "source_id",
826
- "subject_identity_sha256",
827
- "signing_preimage_sha256",
828
- "signature_envelope_sha256",
829
- "receipt_ref",
830
- "receipt_sha256",
831
- "checkpoint_ref",
832
- "checkpoint_sha256",
833
- "inclusion_proof_ref",
834
- "inclusion_proof_sha256",
835
- "latest_proof_ref",
836
- "latest_proof_sha256",
837
- ], ["channel", "consistency_proof_ref", "consistency_proof_sha256"]);
838
- }
839
- function closeSigningSubject(value) {
840
- if (value.usage === "root_delegation") {
841
- exactKeys(value, ["schema_version", "usage", "source_id", "root_epoch"]);
842
- }
843
- else if (value.usage === "package" || value.usage === "release_metadata") {
844
- exactKeys(value, ["schema_version", "usage", "source_id", "channel", "publisher_id", "plugin_id", "version", "artifact_or_metadata_identity_sha256"]);
845
- }
846
- else {
847
- exactKeys(value, ["schema_version", "usage", "source_id", "channel", "epoch"]);
848
- }
849
- }
850
- function closeSignatureEnvelope(value) {
851
- exactKeys(value, ["schema_version", "subject_identity_sha256", "signing_preimage_sha256", "algorithm", "key_id", "signature"]);
852
- }
853
- function closeSigningLedgerEntry(value) {
854
- exactOptionalKeys(value, [
855
- "schema_version", "state", "subject", "subject_identity_sha256", "signing_preimage_sha256",
856
- "algorithm", "key_id", "revision", "reserved_at",
857
- ], ["signature_envelope", "signature_envelope_sha256", "finalized_at", "failure_code", "failed_at"]);
858
- assertRecord(value.subject);
859
- closeSigningSubject(value.subject);
860
- if (value.signature_envelope !== undefined) {
861
- assertRecord(value.signature_envelope);
862
- closeSignatureEnvelope(value.signature_envelope);
863
- }
864
- }
865
- function closeSigningLedgerLogLeaf(value) {
866
- exactOptionalKeys(value, [
867
- "schema_version", "source_id", "subject_identity_sha256", "signing_preimage_sha256", "signature_envelope_sha256", "sequence",
868
- ], ["channel"]);
869
- }
870
- function closeSigningLedgerCheckpoint(value) {
871
- exactKeys(value, [
872
- "schema_version", "kind", "log_id", "tree_size", "log_root_hash", "latest_map_root_hash", "checkpoint_time", "key_id", "signature",
873
- ]);
874
- }
875
- function closeSigningLedgerReceipt(value) {
876
- exactOptionalKeys(value, [
877
- "schema_version", "log_id", "source_id", "subject_identity_sha256", "signing_preimage_sha256",
878
- "signature_envelope_sha256", "sequence", "leaf_index", "tree_size", "log_root_hash", "latest_map_root_hash",
879
- "checkpoint_sha256", "checkpoint_time", "key_id", "signature",
880
- ], ["channel"]);
881
- }
882
- function closeSigningLedgerInclusionProof(value) {
883
- exactKeys(value, ["schema_version", "kind", "log_id", "leaf_index", "tree_size", "nodes"]);
884
- }
885
- function closeSigningLedgerLatestProof(value) {
886
- exactOptionalKeys(value, ["schema_version", "kind", "log_id", "subject_identity_sha256", "present", "siblings"], [
887
- "sequence", "signing_preimage_sha256", "signature_envelope_sha256",
888
- ]);
889
- }
890
- function closeSigningLedgerConsistencyProof(value) {
891
- exactKeys(value, ["schema_version", "kind", "log_id", "old_tree_size", "new_tree_size", "nodes"]);
892
- }
893
605
  export function buildRootDelegation(input, signature) {
894
606
  requireSignatureBytes(signature);
895
607
  const document = {
@@ -1087,61 +799,6 @@ export function decodeRevocation(raw) {
1087
799
  export function decodeRevocationPointer(raw) {
1088
800
  return decodeCanonicalDocument(raw, closePointer, (value) => validatePointer(value, revocationPointerSchemaVersion, true));
1089
801
  }
1090
- export function decodeSigningLedgerEvidence(raw) {
1091
- const bytes = typeof raw === "string" ? textEncoder.encode(raw) : raw;
1092
- if (!(bytes instanceof Uint8Array) || bytes.length > 64 * 1024)
1093
- invalidDocument();
1094
- return decodeCanonicalDocument(bytes, closeSigningLedgerEvidence, validateSigningLedgerEvidence);
1095
- }
1096
- export function canonicalSigningSubject(value) {
1097
- validateSigningSubject(value);
1098
- return canonicalJSON(value);
1099
- }
1100
- export function decodeSigningSubject(raw) {
1101
- return decodeCanonicalDocument(raw, closeSigningSubject, validateSigningSubject);
1102
- }
1103
- export function canonicalSignatureEnvelope(value) {
1104
- validateSignatureEnvelope(value);
1105
- return canonicalJSON(value);
1106
- }
1107
- export function decodeSignatureEnvelope(raw) {
1108
- return decodeCanonicalDocument(raw, closeSignatureEnvelope, validateSignatureEnvelope);
1109
- }
1110
- export function canonicalSigningLedgerEntry(value) {
1111
- validateSigningLedgerEntry(value);
1112
- return canonicalJSON(value);
1113
- }
1114
- export function decodeSigningLedgerEntry(raw) {
1115
- return decodeCanonicalDocument(raw, closeSigningLedgerEntry, validateSigningLedgerEntry);
1116
- }
1117
- export async function verifySigningLedgerEntryBindings(value) {
1118
- validateSigningLedgerEntry(value);
1119
- if (await sha256Hex(canonicalSigningSubject(value.subject)) !== value.subject_identity_sha256)
1120
- invalidDocument();
1121
- if (value.state === "finalized") {
1122
- if (value.signature_envelope === undefined || value.signature_envelope_sha256 === undefined ||
1123
- await sha256Hex(canonicalSignatureEnvelope(value.signature_envelope)) !== value.signature_envelope_sha256)
1124
- invalidDocument();
1125
- }
1126
- }
1127
- export function decodeSigningLedgerLogLeaf(raw) {
1128
- return decodeCanonicalDocument(raw, closeSigningLedgerLogLeaf, validateSigningLedgerLogLeaf);
1129
- }
1130
- export function decodeSigningLedgerCheckpoint(raw) {
1131
- return decodeCanonicalDocument(raw, closeSigningLedgerCheckpoint, validateSigningLedgerCheckpoint);
1132
- }
1133
- export function decodeSigningLedgerReceipt(raw) {
1134
- return decodeCanonicalDocument(raw, closeSigningLedgerReceipt, validateSigningLedgerReceipt);
1135
- }
1136
- export function decodeSigningLedgerInclusionProof(raw) {
1137
- return decodeCanonicalDocument(raw, closeSigningLedgerInclusionProof, validateSigningLedgerInclusionProof);
1138
- }
1139
- export function decodeSigningLedgerLatestProof(raw) {
1140
- return decodeCanonicalDocument(raw, closeSigningLedgerLatestProof, validateSigningLedgerLatestProof);
1141
- }
1142
- export function decodeSigningLedgerConsistencyProof(raw) {
1143
- return decodeCanonicalDocument(raw, closeSigningLedgerConsistencyProof, validateSigningLedgerConsistencyProof);
1144
- }
1145
802
  export function createEd25519Verifier(publicKeys, subtle) {
1146
803
  const selectedSubtle = subtle ?? globalThis.crypto?.subtle;
1147
804
  return async (request) => {
@@ -1190,13 +847,6 @@ async function verifyRaw(usage, keyID, preimage, signature, verifier) {
1190
847
  function toArrayBuffer(value) {
1191
848
  return Uint8Array.from(value).buffer;
1192
849
  }
1193
- async function sha256Hex(value) {
1194
- const subtle = globalThis.crypto?.subtle;
1195
- if (subtle === undefined)
1196
- invalidDocument();
1197
- const digest = new Uint8Array(await subtle.digest("SHA-256", toArrayBuffer(value)));
1198
- return Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("");
1199
- }
1200
850
  function unsignedDocument(value) {
1201
851
  const input = cloneJSON(value);
1202
852
  delete input.schema_version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/redevplugin-contracts",
3
- "version": "0.7.26",
3
+ "version": "1.0.0",
4
4
  "description": "Embedded ReDevPlugin machine contracts and canonical release-signing APIs",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,6 +27,6 @@
27
27
  "scripts": {
28
28
  "build": "tsc -p tsconfig.json",
29
29
  "typecheck": "tsc -p tsconfig.json --noEmit",
30
- "test": "tsc -p tsconfig.test.json && node --test dist-test/test/*.js"
30
+ "test": "node ../../scripts/clean_typescript_test_output.mjs dist-test && tsc -p tsconfig.test.json && node --test dist-test/test/*.js"
31
31
  }
32
32
  }