@serve.zone/interfaces 31.7.0 → 31.9.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 (59) hide show
  1. package/changelog.md +77 -0
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/data/clusterruntime.d.ts +39 -0
  4. package/dist_ts/data/clusterruntime.js +11 -0
  5. package/dist_ts/data/index.d.ts +5 -0
  6. package/dist_ts/data/index.js +6 -1
  7. package/dist_ts/data/networkaddressplan.d.ts +78 -0
  8. package/dist_ts/data/networkaddressplan.js +114 -0
  9. package/dist_ts/data/networkauthority.js +5 -17
  10. package/dist_ts/data/networkcredential.d.ts +10 -4
  11. package/dist_ts/data/networkcredential.js +14 -8
  12. package/dist_ts/data/networkdelivery.d.ts +21 -0
  13. package/dist_ts/data/networkdelivery.js +35 -7
  14. package/dist_ts/data/networklease.d.ts +110 -0
  15. package/dist_ts/data/networklease.js +159 -0
  16. package/dist_ts/data/networknode.d.ts +37 -0
  17. package/dist_ts/data/networknode.js +6 -0
  18. package/dist_ts/data/networkprojection.d.ts +10 -5
  19. package/dist_ts/data/networkprojection.js +15 -22
  20. package/dist_ts/data/networksigning.js +5 -4
  21. package/dist_ts/data/runtimeconfig.js +14 -77
  22. package/dist_ts/data/serviceruntime.d.ts +128 -0
  23. package/dist_ts/data/serviceruntime.js +92 -0
  24. package/dist_ts/private/networkcontract.d.ts +20 -0
  25. package/dist_ts/private/networkcontract.js +45 -1
  26. package/dist_ts/private/producercontract.d.ts +11 -0
  27. package/dist_ts/private/producercontract.js +21 -0
  28. package/dist_ts/private/runtimepolicy.d.ts +31 -0
  29. package/dist_ts/private/runtimepolicy.js +90 -0
  30. package/dist_ts/requests/cluster.d.ts +53 -0
  31. package/dist_ts/requests/cluster.js +1 -1
  32. package/dist_ts/requests/network.d.ts +57 -1
  33. package/dist_ts/requests/runtimesession.d.ts +14 -0
  34. package/dist_ts/requests/service.d.ts +60 -0
  35. package/dist_ts/runtime.networkprojection.d.ts +14 -0
  36. package/dist_ts/runtime.networkprojection.js +68 -19
  37. package/package.json +2 -2
  38. package/readme.md +251 -3
  39. package/ts/00_commitinfo_data.ts +1 -1
  40. package/ts/data/clusterruntime.ts +45 -0
  41. package/ts/data/index.ts +5 -0
  42. package/ts/data/networkaddressplan.ts +175 -0
  43. package/ts/data/networkauthority.ts +4 -16
  44. package/ts/data/networkcredential.ts +19 -9
  45. package/ts/data/networkdelivery.ts +49 -6
  46. package/ts/data/networklease.ts +229 -0
  47. package/ts/data/networknode.ts +37 -0
  48. package/ts/data/networkprojection.ts +28 -26
  49. package/ts/data/networksigning.ts +5 -4
  50. package/ts/data/runtimeconfig.ts +17 -76
  51. package/ts/data/serviceruntime.ts +208 -0
  52. package/ts/private/networkcontract.ts +48 -0
  53. package/ts/private/producercontract.ts +19 -0
  54. package/ts/private/runtimepolicy.ts +105 -0
  55. package/ts/requests/cluster.ts +65 -0
  56. package/ts/requests/network.ts +50 -1
  57. package/ts/requests/runtimesession.ts +17 -0
  58. package/ts/requests/service.ts +81 -0
  59. package/ts/runtime.networkprojection.ts +87 -20
@@ -1,5 +1,7 @@
1
1
  import * as plugins from '../plugins.js';
2
- import type { IIdentityCredential } from '../data/user.js';
2
+ import type { IIdentity, IIdentityCredential } from '../data/user.js';
3
+ import type { IRuntimeNetworkAddressPlan, TRuntimeNetworkAddressPlanWritableData } from '../data/networkaddressplan.js';
4
+ import type { IRuntimeNetworkNodeReadiness, IRuntimeRouterIncarnation } from '../data/networknode.js';
3
5
  import type {
4
6
  IPrivateNetworkV1, IServicePrivateNetworksV1, ISetServicePrivateNetworksV1,
5
7
  TPrivateNetworkMutationV1,
@@ -98,3 +100,50 @@ export interface IRequest_Any_Cloudly_GetNetworkNodes {
98
100
  networkNodes: plugins.tsclass.network.INetworkNode[];
99
101
  };
100
102
  }
103
+
104
+ /**
105
+ * Writes the runtime network's address plan.
106
+ *
107
+ * `expectedRevision` is the revision the caller read, or `null` when no plan exists yet. Cloudly
108
+ * validates the plan with `snapshotRuntimeNetworkAddressPlan`, decides the change with
109
+ * `admitRuntimeNetworkAddressPlanChange`, refuses the change while a resolver or platform endpoint
110
+ * it removes or changes is still referenced, and answers with the stored plan: at its new revision,
111
+ * or unchanged.
112
+ */
113
+ export interface IReq_Any_Cloudly_SetRuntimeNetworkAddressPlan extends plugins.typedrequestInterfaces.implementsTR<
114
+ plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_SetRuntimeNetworkAddressPlan
115
+ > {
116
+ method: 'setRuntimeNetworkAddressPlan';
117
+ request: { identity: IIdentity; expectedRevision: number | null; plan: TRuntimeNetworkAddressPlanWritableData };
118
+ response: { plan: IRuntimeNetworkAddressPlan };
119
+ }
120
+
121
+ /** `null` until an administrator sets the first plan; the runtime network stays unconfigured until then. */
122
+ export interface IReq_Any_Cloudly_GetRuntimeNetworkAddressPlan extends plugins.typedrequestInterfaces.implementsTR<
123
+ plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_GetRuntimeNetworkAddressPlan
124
+ > {
125
+ method: 'getRuntimeNetworkAddressPlan';
126
+ request: { identity: IIdentity };
127
+ response: { plan: IRuntimeNetworkAddressPlan | null };
128
+ }
129
+
130
+ /** Whether one node's runtime network is ready for workloads, and every condition still missing. */
131
+ export interface IReq_Any_Cloudly_GetRuntimeNetworkNodeReadiness extends plugins.typedrequestInterfaces.implementsTR<
132
+ plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_GetRuntimeNetworkNodeReadiness
133
+ > {
134
+ method: 'getRuntimeNetworkNodeReadiness';
135
+ request: { identity: IIdentity; nodeId: string };
136
+ response: IRuntimeNetworkNodeReadiness;
137
+ }
138
+
139
+ /**
140
+ * Advances one node's router incarnation, so the node producer reserves the router a fresh handoff.
141
+ * `expectedIncarnation` is the incarnation the caller read; any other refuses the request.
142
+ */
143
+ export interface IReq_Any_Cloudly_ReincarnateRuntimeNetworkRouter extends plugins.typedrequestInterfaces.implementsTR<
144
+ plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_ReincarnateRuntimeNetworkRouter
145
+ > {
146
+ method: 'reincarnateRuntimeNetworkRouter';
147
+ request: { identity: IIdentity; nodeId: string; expectedIncarnation: number };
148
+ response: { incarnation: IRuntimeRouterIncarnation };
149
+ }
@@ -41,6 +41,23 @@ export interface IReq_Controller_Pallet_ApplyRuntimeNetworkProjectionV1 extends
41
41
  response: network.IApplyRuntimeNetworkAuthorityResponseV1;
42
42
  }
43
43
 
44
+ /**
45
+ * A fresh DNS window for the node's exact admitted projection; an ACK asserts admission only.
46
+ *
47
+ * The controller sends it while it is reachable. A cluster relay sends the renewals it holds
48
+ * while it has no controller session, under the binding the node obtained itself, which is why
49
+ * a node admits it from whoever holds its current connection and trusts only the signature.
50
+ * Either sender delivers a window once its slot has opened and never before, because a node
51
+ * refuses a renewal it could not use at once; delivering it again once the slot opens is enough.
52
+ */
53
+ export interface IReq_Controller_Pallet_ApplyRuntimeNetworkDnsLeaseRenewal extends plugins.typedrequestInterfaces.implementsTR<
54
+ plugins.typedrequestInterfaces.ITypedRequest, IReq_Controller_Pallet_ApplyRuntimeNetworkDnsLeaseRenewal
55
+ > {
56
+ method: 'applyRuntimeNetworkDnsLeaseRenewal';
57
+ request: network.IApplyRuntimeNetworkDnsLeaseRenewalRequest;
58
+ response: network.IApplyRuntimeNetworkDnsLeaseRenewalResponse;
59
+ }
60
+
44
61
  /**
45
62
  * WSS-only Pallet bootstrap. Derive physical peer/idempotency server-side; the registering
46
63
  * node process is named by `request.nodeInstanceNonce`, because one relay socket may carry
@@ -16,6 +16,12 @@ import type {
16
16
  IServiceDeploymentStatus,
17
17
  } from '../data/deploymentoperation.js';
18
18
  import type { TSha256Digest } from '../data/immutableimage.js';
19
+ import type {
20
+ IServiceRuntimeAssignmentView,
21
+ IServiceRuntimeSpec,
22
+ IServiceRuntimeStatus,
23
+ TServiceRuntimeSpecWritableData,
24
+ } from '../data/serviceruntime.js';
19
25
  import type {
20
26
  IServiceDeploymentAdoptionInput,
21
27
  IServiceDeploymentAdoptionImagePromotionInput,
@@ -370,3 +376,78 @@ extends plugins.typedrequestInterfaces.implementsTR<
370
376
  success: boolean;
371
377
  };
372
378
  }
379
+
380
+ /**
381
+ * Writes the complete runtime spec of one service.
382
+ *
383
+ * `expectedRevision` is the revision the caller read, or `null` when the service has never had a
384
+ * spec; any other stored revision refuses the write. Cloudly copies the organization from the
385
+ * service and answers with the stored spec at its new revision.
386
+ */
387
+ export interface IRequest_Any_Cloudly_SetServiceRuntimeSpec
388
+ extends plugins.typedrequestInterfaces.implementsTR<
389
+ plugins.typedrequestInterfaces.ITypedRequest,
390
+ IRequest_Any_Cloudly_SetServiceRuntimeSpec
391
+ > {
392
+ method: 'setServiceRuntimeSpec';
393
+ request: {
394
+ identity: IIdentity;
395
+ serviceId: string;
396
+ expectedRevision: number | null;
397
+ spec: TServiceRuntimeSpecWritableData;
398
+ };
399
+ response: {
400
+ spec: IServiceRuntimeSpec;
401
+ };
402
+ }
403
+
404
+ /**
405
+ * A service's runtime spec and the producer's verdict on it. Both are `null` before the first spec;
406
+ * a spec's status is `null` until the producer first decides it.
407
+ */
408
+ export interface IRequest_Any_Cloudly_GetServiceRuntimeSpec
409
+ extends plugins.typedrequestInterfaces.implementsTR<
410
+ plugins.typedrequestInterfaces.ITypedRequest,
411
+ IRequest_Any_Cloudly_GetServiceRuntimeSpec
412
+ > {
413
+ method: 'getServiceRuntimeSpec';
414
+ request: {
415
+ identity: IIdentity;
416
+ serviceId: string;
417
+ };
418
+ response:
419
+ | { spec: null; status: null }
420
+ | { spec: IServiceRuntimeSpec; status: IServiceRuntimeStatus | null };
421
+ }
422
+
423
+ /** Every current runtime assignment of one service, one per replica slot. */
424
+ export interface IRequest_Any_Cloudly_GetServiceRuntimeAssignments
425
+ extends plugins.typedrequestInterfaces.implementsTR<
426
+ plugins.typedrequestInterfaces.ITypedRequest,
427
+ IRequest_Any_Cloudly_GetServiceRuntimeAssignments
428
+ > {
429
+ method: 'getServiceRuntimeAssignments';
430
+ request: {
431
+ identity: IIdentity;
432
+ serviceId: string;
433
+ };
434
+ response: {
435
+ assignments: IServiceRuntimeAssignmentView[];
436
+ };
437
+ }
438
+
439
+ /**
440
+ * Cloudly -> admin UIs: a service's runtime spec, status or assignments changed. It carries no
441
+ * state, so a late or repeated push can never overwrite a newer read; the UI reads the views again.
442
+ */
443
+ export interface IReq_Cloudly_Any_PushServiceRuntimeChanged
444
+ extends plugins.typedrequestInterfaces.implementsTR<
445
+ plugins.typedrequestInterfaces.ITypedRequest,
446
+ IReq_Cloudly_Any_PushServiceRuntimeChanged
447
+ > {
448
+ method: 'pushServiceRuntimeChanged';
449
+ request: {
450
+ serviceId: string;
451
+ };
452
+ response: Record<string, never>;
453
+ }
@@ -1,11 +1,15 @@
1
1
  import * as plugins from './plugins.runtime.js';
2
- import type { IRuntimeAuthorityReferenceV1 } from './data/runtimeassignment.js';
2
+ import type { IRuntimeAuthorityReferenceV1, IRuntimeControllerV1 } from './data/runtimeassignment.js';
3
3
  import type { IRuntimeNetworkProjectionV1 } from './data/networkprojection.js';
4
4
  import { snapshotRuntimeNetworkNodeScopeV1, snapshotRuntimeNetworkProjectionV1, validateRuntimeNetworkProjectionV1 } from './data/networkprojection.js';
5
5
  import type { IRuntimeNetworkSigningAuthorityV1, ISignedRuntimeNetworkProjectionV1 } from './data/networksigning.js';
6
6
  import { computeRuntimeNetworkSigningAuthorityV1Digest, runtimeNetworkSigningV1Contract,
7
7
  snapshotRuntimeNetworkSigningAuthorityV1, snapshotSignedRuntimeNetworkProjectionV1 } from './data/networksigning.js';
8
- import { failNetwork, networkCanonical, networkEqual, networkReferenceOf, requireNetwork } from './private/networkcontract.js';
8
+ import type { IRuntimeNetworkDnsLeaseRenewal, ISignedRuntimeNetworkDnsLeaseRenewal } from './data/networklease.js';
9
+ import { runtimeNetworkDnsLeaseRenewalContract, snapshotRuntimeNetworkDnsLeaseRenewal,
10
+ snapshotSignedRuntimeNetworkDnsLeaseRenewal, validateRuntimeNetworkDnsLeaseRenewal } from './data/networklease.js';
11
+ import { captureNetwork, failNetwork, networkCanonical, networkEqual, networkReference, networkReferenceOf,
12
+ networkSameScope, requireNetwork } from './private/networkcontract.js';
9
13
 
10
14
  /** The private KeyObject is process-local. Persist only through the controller's encrypted secret store. */
11
15
  export const createRuntimeNetworkSigningKeyV1 = (): { publicKey: string; privateKey: plugins.crypto.KeyObject } => {
@@ -15,11 +19,47 @@ export const createRuntimeNetworkSigningKeyV1 = (): { publicKey: string; private
15
19
  return { publicKey: Buffer.from(jwk.x, 'base64url').toString('hex'), privateKey: pair.privateKey };
16
20
  };
17
21
 
18
- const signatureBytes = (authority: IRuntimeAuthorityReferenceV1, projection: IRuntimeNetworkProjectionV1): Uint8Array =>
19
- new TextEncoder().encode(networkCanonical({ domain: runtimeNetworkSigningV1Contract.signatureDomain, schemaVersion: 1, authority, projection }));
20
- const validateAuthority = async (authority: IRuntimeNetworkSigningAuthorityV1, projection: IRuntimeNetworkProjectionV1): Promise<void> => {
21
- requireNetwork(authority.publicKey !== null && networkEqual(authority.controller, projection.controller)
22
+ /** What every signed network statement carries besides its content. */
23
+ interface IAuthoritySignature {
24
+ authority: IRuntimeAuthorityReferenceV1;
25
+ signature: string;
26
+ }
27
+
28
+ const projectionEnvelope = (authority: IRuntimeAuthorityReferenceV1, projection: IRuntimeNetworkProjectionV1) =>
29
+ ({ domain: runtimeNetworkSigningV1Contract.signatureDomain, schemaVersion: 1, authority, projection });
30
+ const renewalEnvelope = (authority: IRuntimeAuthorityReferenceV1, renewal: IRuntimeNetworkDnsLeaseRenewal) =>
31
+ ({ domain: runtimeNetworkDnsLeaseRenewalContract.signatureDomain, authority, renewal });
32
+ const envelopeBytes = (envelope: object): Uint8Array => new TextEncoder().encode(networkCanonical(envelope));
33
+
34
+ /** A revoked revision has no key; any other must be intact and belong to the controller that owns the content. */
35
+ const liveKeyOf = async (authority: IRuntimeNetworkSigningAuthorityV1, contentController: IRuntimeControllerV1): Promise<string> => {
36
+ const { publicKey } = authority;
37
+ requireNetwork(publicKey !== null && networkEqual(authority.controller, contentController)
22
38
  && authority.digest === await computeRuntimeNetworkSigningAuthorityV1Digest(authority));
39
+ return publicKey;
40
+ };
41
+
42
+ /** Sign as the authority's revision, and only with the private half of its live key. */
43
+ const signAs = async (
44
+ authority: IRuntimeNetworkSigningAuthorityV1, privateKey: plugins.crypto.KeyObject, contentController: IRuntimeControllerV1,
45
+ envelopeOf: (reference: IRuntimeAuthorityReferenceV1) => object,
46
+ ): Promise<IAuthoritySignature> => {
47
+ requireNetwork(privateKey instanceof plugins.crypto.KeyObject && privateKey.type === 'private' && privateKey.asymmetricKeyType === 'ed25519');
48
+ const derived = plugins.crypto.createPublicKey(privateKey).export({ format: 'jwk' });
49
+ const publicKey = await liveKeyOf(authority, contentController);
50
+ requireNetwork(typeof derived.x === 'string' && Buffer.from(derived.x, 'base64url').toString('hex') === publicKey);
51
+ const reference = networkReferenceOf(authority);
52
+ return { authority: reference, signature: plugins.crypto.sign(null, envelopeBytes(envelopeOf(reference)), privateKey).toString('hex') };
53
+ };
54
+
55
+ /** The receiver's own trusted revision decides; the envelope only names which revision it claims. */
56
+ const requireSignedBy = async (
57
+ trusted: IRuntimeNetworkSigningAuthorityV1, signed: IAuthoritySignature, contentController: IRuntimeControllerV1, envelope: object,
58
+ ): Promise<void> => {
59
+ requireNetwork(networkEqual(signed.authority, networkReferenceOf(trusted)));
60
+ const key = plugins.crypto.createPublicKey({ format: 'jwk', key: { kty: 'OKP', crv: 'Ed25519',
61
+ x: Buffer.from(await liveKeyOf(trusted, contentController), 'hex').toString('base64url') } });
62
+ requireNetwork(plugins.crypto.verify(null, envelopeBytes(envelope), key, Buffer.from(signed.signature, 'hex')));
23
63
  };
24
64
 
25
65
  /** Sign only validated complete state and a matching dedicated private key. */
@@ -28,14 +68,9 @@ export const signRuntimeNetworkProjectionV1 = async (
28
68
  ): Promise<ISignedRuntimeNetworkProjectionV1> => {
29
69
  try {
30
70
  const input = snapshotRuntimeNetworkProjectionV1(projectionValue), authority = snapshotRuntimeNetworkSigningAuthorityV1(authorityValue);
31
- requireNetwork(privateKey instanceof plugins.crypto.KeyObject && privateKey.type === 'private' && privateKey.asymmetricKeyType === 'ed25519');
32
- const publicKey = plugins.crypto.createPublicKey(privateKey).export({ format: 'jwk' });
33
- requireNetwork(typeof publicKey.x === 'string' && Buffer.from(publicKey.x, 'base64url').toString('hex') === authority.publicKey);
34
71
  const projection = await validateRuntimeNetworkProjectionV1(input);
35
- await validateAuthority(authority, projection);
36
- const reference = networkReferenceOf(authority);
37
- const signature = plugins.crypto.sign(null, signatureBytes(reference, projection), privateKey).toString('hex');
38
- return { schemaVersion: 1, authority: reference, projection, signature };
72
+ const signed = await signAs(authority, privateKey, projection.controller, reference => projectionEnvelope(reference, projection));
73
+ return { schemaVersion: 1, authority: signed.authority, projection, signature: signed.signature };
39
74
  } catch { return failNetwork(); }
40
75
  };
41
76
 
@@ -51,14 +86,46 @@ export const verifyRuntimeNetworkProjectionV1 = async (
51
86
  const signed = snapshotSignedRuntimeNetworkProjectionV1(value);
52
87
  const authority = snapshotRuntimeNetworkSigningAuthorityV1(trustedAuthorityValue);
53
88
  const trusted = snapshotRuntimeNetworkNodeScopeV1(trustedScopeValue);
54
- requireNetwork(networkEqual(signed.authority, networkReferenceOf(authority))
55
- && signed.projection.nodeId === trusted.nodeId && signed.projection.runtimeNamespace === trusted.runtimeNamespace
56
- && networkEqual(signed.projection.controller, trusted.controller));
57
- await validateAuthority(authority, signed.projection);
58
- const key = plugins.crypto.createPublicKey({ format: 'jwk', key: { kty: 'OKP', crv: 'Ed25519',
59
- x: Buffer.from(authority.publicKey!, 'hex').toString('base64url') } });
60
- requireNetwork(plugins.crypto.verify(null, signatureBytes(signed.authority, signed.projection), key, Buffer.from(signed.signature, 'hex')));
89
+ requireNetwork(networkSameScope(signed.projection, trusted));
90
+ await requireSignedBy(authority, signed, signed.projection.controller, projectionEnvelope(signed.authority, signed.projection));
61
91
  await validateRuntimeNetworkProjectionV1(signed.projection);
62
92
  return signed;
63
93
  } catch { return failNetwork(); }
64
94
  };
95
+
96
+ /** Sign only a validated renewal, with the same authority and key that sign this controller's projections. */
97
+ export const signRuntimeNetworkDnsLeaseRenewal = async (
98
+ renewalValue: unknown, authorityValue: unknown, privateKey: plugins.crypto.KeyObject,
99
+ ): Promise<ISignedRuntimeNetworkDnsLeaseRenewal> => {
100
+ try {
101
+ const input = snapshotRuntimeNetworkDnsLeaseRenewal(renewalValue), authority = snapshotRuntimeNetworkSigningAuthorityV1(authorityValue);
102
+ const renewal = await validateRuntimeNetworkDnsLeaseRenewal(input);
103
+ const signed = await signAs(authority, privateKey, renewal.controller, reference => renewalEnvelope(reference, renewal));
104
+ return { authority: signed.authority, renewal, signature: signed.signature };
105
+ } catch { return failNetwork(); }
106
+ };
107
+
108
+ /**
109
+ * trustedAuthorityValue is receiver-owned persisted trust, NEVER envelope material, and a relay
110
+ * that delivers the renewal adds no trust to it. projectionAuthorityValue is the authority
111
+ * reference that signed the projection this renewal extends, which the receiver kept when it
112
+ * admitted that projection: a renewal is only ever valid under the exact revision that signed its
113
+ * projection, so a rotated key renews nothing and DNS still waits for a newly signed projection.
114
+ * This verifies content, scope and signature only: the owner still admits it against its own
115
+ * admitted projection with `admitRuntimeNetworkDnsLeaseRenewal`, fences the live session and
116
+ * converts the window with a qualified clock.
117
+ */
118
+ export const verifyRuntimeNetworkDnsLeaseRenewal = async (
119
+ value: unknown, trustedAuthorityValue: unknown, trustedScopeValue: unknown, projectionAuthorityValue: unknown,
120
+ ): Promise<ISignedRuntimeNetworkDnsLeaseRenewal> => {
121
+ try {
122
+ const signed = snapshotSignedRuntimeNetworkDnsLeaseRenewal(value);
123
+ const authority = snapshotRuntimeNetworkSigningAuthorityV1(trustedAuthorityValue);
124
+ const trusted = snapshotRuntimeNetworkNodeScopeV1(trustedScopeValue);
125
+ const projectionAuthority = networkReference(captureNetwork(projectionAuthorityValue));
126
+ requireNetwork(networkSameScope(signed.renewal, trusted) && networkEqual(signed.authority, projectionAuthority));
127
+ await requireSignedBy(authority, signed, signed.renewal.controller, renewalEnvelope(signed.authority, signed.renewal));
128
+ await validateRuntimeNetworkDnsLeaseRenewal(signed.renewal);
129
+ return signed;
130
+ } catch { return failNetwork(); }
131
+ };