@serve.zone/interfaces 32.28.0 → 32.29.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.
@@ -5,12 +5,29 @@ export function requireNetwork(value) { if (!value)
5
5
  failNetwork(); }
6
6
  export const networkCanonical = (value) => canonicalizeStrictJson(value, failNetwork);
7
7
  export const networkEqual = (left, right) => networkCanonical(left) === networkCanonical(right);
8
- export const networkSafe = (operation) => { try {
9
- return operation();
8
+ /**
9
+ * A plan refused for a structure rule the contract names, rather than with the contract's generic
10
+ * rejection. It is the one error `networkSafe` lets through, so a caller can tell an administrator
11
+ * which list to fix; its message names the field and the rule and quotes nothing from the plan.
12
+ */
13
+ export class RuntimeNetworkAddressPlanStructureError extends Error {
14
+ violation;
15
+ constructor(violationArg) {
16
+ super(`Runtime network address plan rejected: ${violationArg.field} breaks the ${violationArg.rule} rule.`);
17
+ this.name = 'RuntimeNetworkAddressPlanStructureError';
18
+ this.violation = { field: violationArg.field, rule: violationArg.rule };
19
+ }
10
20
  }
11
- catch {
12
- return failNetwork();
13
- } };
21
+ export const networkSafe = (operation) => {
22
+ try {
23
+ return operation();
24
+ }
25
+ catch (error) {
26
+ if (error instanceof RuntimeNetworkAddressPlanStructureError)
27
+ throw error;
28
+ return failNetwork();
29
+ }
30
+ };
14
31
  /** Bound decoded transport input before canonicalization; never execute getters/toJSON. */
15
32
  export const captureNetwork = (value) => networkSafe(() => {
16
33
  const encoder = new TextEncoder(), ancestors = new Set();
@@ -216,4 +233,4 @@ export const networkOverlaps = (left, right) => {
216
233
  const [a, b] = networkPrefixBounds(left), [c, d] = networkPrefixBounds(right);
217
234
  return a <= d && c <= b;
218
235
  };
219
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29ya2NvbnRyYWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvcHJpdmF0ZS9uZXR3b3JrY29udHJhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLHNCQUFzQixFQUFFLDRCQUE0QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXRELE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxHQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUcsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFjLElBQW1CLElBQUksQ0FBQyxLQUFLO0lBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBYyxFQUFVLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDdkcsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBVyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDM0gsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLENBQUksU0FBa0IsRUFBSyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQUMsT0FBTyxTQUFTLEVBQUUsQ0FBQztBQUFDLENBQUM7QUFBQyxNQUFNLENBQUM7SUFBQyxPQUFPLFdBQVcsRUFBRSxDQUFDO0FBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUV6SCwyRkFBMkY7QUFDM0YsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLENBQUMsS0FBYyxFQUFXLEVBQUUsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFO0lBQzFFLE1BQU0sT0FBTyxHQUFH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
236
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29ya2NvbnRyYWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvcHJpdmF0ZS9uZXR3b3JrY29udHJhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLHNCQUFzQixFQUFFLDRCQUE0QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXRELE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxHQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUcsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUFjLElBQW1CLElBQUksQ0FBQyxLQUFLO0lBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzVGLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBYyxFQUFVLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDdkcsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBYSxFQUFFLEtBQWMsRUFBVyxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUssZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7QUFjM0g7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyx1Q0FBd0MsU0FBUSxLQUFLO0lBQ2hELFNBQVMsQ0FBK0M7SUFFeEUsWUFBbUIsWUFBMEQ7UUFDM0UsS0FBSyxDQUFDLDBDQUEwQyxZQUFZLENBQUMsS0FBSyxlQUFlLFlBQVksQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDO1FBQzVHLElBQUksQ0FBQyxJQUFJLEdBQUcseUNBQXlDLENBQUM7UUFDdEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxZQUFZLENBQUMsSUFB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
@@ -139,7 +139,8 @@ export interface IRequest_Any_Cloudly_GetNetworkNodes {
139
139
  * validates the plan with `snapshotRuntimeNetworkAddressPlan`, decides the change with
140
140
  * `admitRuntimeNetworkAddressPlanChange`, refuses the change while a resolver or platform endpoint
141
141
  * it removes or changes is still referenced, and answers with the stored plan: at its new revision,
142
- * or unchanged.
142
+ * or unchanged. A list stated out of its canonical order (see `IRuntimeNetworkAddressPlan`) is
143
+ * refused `plan-unsorted`, naming the list as the refusal's reference; the plan is never reordered.
143
144
  */
144
145
  export interface IReq_Any_Cloudly_SetRuntimeNetworkAddressPlan extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_SetRuntimeNetworkAddressPlan> {
145
146
  method: 'setRuntimeNetworkAddressPlan';
@@ -1,6 +1,7 @@
1
1
  import * as plugins from '../plugins.js';
2
- import type { ICloudlySettings } from '../data/settings.js';
3
- import type { IIdentity } from '../data/user.js';
2
+ import type { IActiveSecretRecipientMetadata } from '../data/secret.js';
3
+ import type { ICloudlySettings, IExternalGatewayEnrollmentState } from '../data/settings.js';
4
+ import type { IIdentity, IIdentityCredential } from '../data/user.js';
4
5
  export interface IRequest_GetSettings extends plugins.typedrequestInterfaces.ITypedRequest {
5
6
  method: 'getSettings';
6
7
  request: {
@@ -54,3 +55,56 @@ export interface IRequest_GetSetting extends plugins.typedrequestInterfaces.ITyp
54
55
  value: ICloudlySettings[keyof ICloudlySettings] | undefined;
55
56
  };
56
57
  }
58
+ /** A dcrouter admin bootstrap token, sealed to Cloudly's active secret ingress recipient. */
59
+ export interface IExternalGatewayBootstrapTokenInput {
60
+ mode: 'sealed';
61
+ /** Sealed under `data.createGatewayBootstrapEnvelopeContext` for the request's expected target. */
62
+ envelope: plugins.smartcrypto.IX25519EnvelopeV1;
63
+ }
64
+ /**
65
+ * Enrolls Cloudly as its dcrouter gateway client with a dcrouter admin token an administrator
66
+ * hands in once.
67
+ *
68
+ * Cloudly opens the token, checks the target the request names against its own settings, asks
69
+ * dcrouter whether the token is an admin token, and provisions, finalizes and stores its own
70
+ * least-privilege gateway-client credential with it — under the policy its settings and the runtime
71
+ * network address plan state now. The admin token is used for this one call and never stored; the
72
+ * administrator revokes it at dcrouter afterwards. A refusal leaves the credential Cloudly already
73
+ * holds unchanged and is answered with one of `data.externalGatewayBootstrapRefusals`.
74
+ *
75
+ * This is the one way a gateway credential enters Cloudly, for a first enrollment and for the
76
+ * re-bootstrap a changed address plan or gateway setting asks for (`admin-bootstrap-required`).
77
+ */
78
+ export interface IReq_Any_Cloudly_BootstrapExternalGatewayCredential extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_BootstrapExternalGatewayCredential> {
79
+ method: 'bootstrapExternalGatewayCredential';
80
+ request: {
81
+ identity: IIdentityCredential;
82
+ /** The `dcrouterGatewayUrl` the administrator read from Cloudly's settings. */
83
+ expectedGatewayUrl: string;
84
+ /** The `dcrouterGatewayClientId` the administrator read from Cloudly's settings. */
85
+ expectedGatewayClientId: string;
86
+ bootstrapToken: IExternalGatewayBootstrapTokenInput;
87
+ };
88
+ response: {
89
+ /** The enrollment after the bootstrap: `ready` when the new credential is Cloudly's runtime authority. */
90
+ state: IExternalGatewayEnrollmentState;
91
+ };
92
+ }
93
+ /** Cloudly's gateway-client enrollment state, for an administrator; it never carries a credential. */
94
+ export interface IReq_Any_Cloudly_GetExternalGatewayEnrollmentState extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_GetExternalGatewayEnrollmentState> {
95
+ method: 'getExternalGatewayEnrollmentState';
96
+ request: {
97
+ identity: IIdentityCredential;
98
+ };
99
+ response: {
100
+ state: IExternalGatewayEnrollmentState;
101
+ };
102
+ }
103
+ /**
104
+ * Checks a bootstrap request against its schema and the active ingress recipient, without opening
105
+ * the envelope: the recipient, the context digest of the named target and the ciphertext bound of
106
+ * `data.externalGatewayBootstrapContract.maximumTokenBytes`. Every problem is named.
107
+ */
108
+ export declare const validateBootstrapExternalGatewayCredentialRequest: (requestArg: unknown, activeIngressRecipientArg: IActiveSecretRecipientMetadata) => Promise<string[]>;
109
+ /** Checks an enrollment state read; every problem is named. */
110
+ export declare const validateGetExternalGatewayEnrollmentStateRequest: (requestArg: unknown) => string[];
@@ -1,2 +1,92 @@
1
1
  import * as plugins from '../plugins.js';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9yZXF1ZXN0cy9zZXR0aW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQyJ9
2
+ import * as secretData from '../data/secret.js';
3
+ import * as settingsData from '../data/settings.js';
4
+ import { readDataProperties, hasExactKeys } from '../private/dataproperties.js';
5
+ const hasJwtIdentity = (valueArg) => {
6
+ const identity = readDataProperties(valueArg);
7
+ return identity !== null && typeof identity.jwt === 'string' && identity.jwt.length > 0;
8
+ };
9
+ /** Structural check of the target a bootstrap request names; empty when both are well formed. */
10
+ const validateExpectedGatewayTarget = (urlArg, clientIdArg) => {
11
+ const errors = [];
12
+ let url;
13
+ if (typeof urlArg === 'string'
14
+ && urlArg.length > 0
15
+ && urlArg.length <= settingsData.externalGatewayBootstrapContract.maximumGatewayUrlLength) {
16
+ try {
17
+ url = new URL(urlArg);
18
+ }
19
+ catch {
20
+ url = undefined;
21
+ }
22
+ }
23
+ if (!url
24
+ || url.protocol !== 'https:'
25
+ || url.username !== ''
26
+ || url.password !== ''
27
+ || url.search !== ''
28
+ || url.hash !== '') {
29
+ errors.push('bootstrap expectedGatewayUrl must be an HTTPS URL without credentials, query or fragment');
30
+ }
31
+ if (typeof clientIdArg !== 'string'
32
+ || clientIdArg.length === 0
33
+ || clientIdArg.length > settingsData.externalGatewayBootstrapContract.maximumGatewayClientIdLength
34
+ || !/^[\x21-\x7e]+$/.test(clientIdArg)) {
35
+ errors.push('bootstrap expectedGatewayClientId must be a bounded identifier without whitespace');
36
+ }
37
+ return errors;
38
+ };
39
+ /**
40
+ * Checks a bootstrap request against its schema and the active ingress recipient, without opening
41
+ * the envelope: the recipient, the context digest of the named target and the ciphertext bound of
42
+ * `data.externalGatewayBootstrapContract.maximumTokenBytes`. Every problem is named.
43
+ */
44
+ export const validateBootstrapExternalGatewayCredentialRequest = async (requestArg, activeIngressRecipientArg) => {
45
+ const request = readDataProperties(requestArg);
46
+ if (request === null)
47
+ return ['bootstrap request must be a plain record'];
48
+ const errors = [];
49
+ if (!hasExactKeys(request, ['identity', 'expectedGatewayUrl', 'expectedGatewayClientId', 'bootstrapToken'])) {
50
+ errors.push('bootstrap request contains fields outside its schema');
51
+ }
52
+ if (!hasJwtIdentity(request.identity)) {
53
+ errors.push('bootstrap identity must be a JWT credential');
54
+ }
55
+ const targetErrors = validateExpectedGatewayTarget(request.expectedGatewayUrl, request.expectedGatewayClientId);
56
+ errors.push(...targetErrors);
57
+ const tokenInput = readDataProperties(request.bootstrapToken);
58
+ if (tokenInput === null || tokenInput.mode !== 'sealed') {
59
+ errors.push('bootstrap token must be a sealed input');
60
+ return errors;
61
+ }
62
+ const expectedContext = targetErrors.length === 0
63
+ ? secretData.createGatewayBootstrapEnvelopeContext({
64
+ gatewayUrl: request.expectedGatewayUrl,
65
+ gatewayClientId: request.expectedGatewayClientId,
66
+ })
67
+ : new Uint8Array();
68
+ errors.push(...await secretData.validateSecretValueInputForRecipient(tokenInput, activeIngressRecipientArg, expectedContext));
69
+ const envelope = readDataProperties(tokenInput.envelope);
70
+ if (envelope !== null
71
+ && typeof envelope.ciphertext === 'string'
72
+ && envelope.ciphertext.length
73
+ > Math.ceil(settingsData.externalGatewayBootstrapContract.maximumTokenBytes * 4 / 3)) {
74
+ errors.push(`bootstrap token must not exceed ${settingsData.externalGatewayBootstrapContract.maximumTokenBytes} bytes`);
75
+ }
76
+ return errors;
77
+ };
78
+ /** Checks an enrollment state read; every problem is named. */
79
+ export const validateGetExternalGatewayEnrollmentStateRequest = (requestArg) => {
80
+ const request = readDataProperties(requestArg);
81
+ if (request === null)
82
+ return ['enrollment state request must be a plain record'];
83
+ const errors = [];
84
+ if (!hasExactKeys(request, ['identity'])) {
85
+ errors.push('enrollment state request contains fields outside its schema');
86
+ }
87
+ if (!hasJwtIdentity(request.identity)) {
88
+ errors.push('enrollment state identity must be a JWT credential');
89
+ }
90
+ return errors;
91
+ };
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9yZXF1ZXN0cy9zZXR0aW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssVUFBVSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxZQUFZLE1BQU0scUJBQXFCLENBQUM7QUFJcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBeUhoRixNQUFNLGNBQWMsR0FBRyxDQUFDLFFBQWlCLEVBQVcsRUFBRTtJQUNwRCxNQUFNLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5QyxPQUFPLFFBQVEsS0FBSyxJQUFJLElBQUksT0FBTyxRQUFRLENBQUMsR0FBRyxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDMUYsQ0FBQyxDQUFDO0FBRUYsaUdBQWlHO0FBQ2pHLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxNQUFlLEVBQUUsV0FBb0IsRUFBWSxFQUFFO0lBQ3hGLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUM1QixJQUFJLEdBQW9CLENBQUM7SUFDekIsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRO1dBQ3pCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQztXQUNqQixNQUFNLENBQUMsTUFBTSxJQUFJLFlBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQzVGLElBQUksQ0FBQztZQUNILEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsR0FBRyxHQUFHLFNBQVMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksQ0FBQyxHQUFHO1dBQ0gs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serve.zone/interfaces",
3
- "version": "32.28.0",
3
+ "version": "32.29.0",
4
4
  "private": false,
5
5
  "description": "Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.",
6
6
  "exports": {
package/readme.md CHANGED
@@ -829,6 +829,27 @@ because the private-range rule already keeps it at /8 or longer.
829
829
  `data.runtimeNetworkVpnControlPrefix(value)` is that reader on its own, exported because a
830
830
  cluster's VPN network repeats the prefix its hub binds and has to read it exactly as the plan does.
831
831
 
832
+ Every list of a plan is stated in one canonical order, and a plan is never reordered for its
833
+ writer: `prefixes` strictly ascending by the prefix text, and `pools`, `resolvers` and
834
+ `platformEndpoints` strictly ascending by `id`. Both compare as strings, so the order is
835
+ lexicographic, not numeric — `100.64.0.0/10` comes before `20.0.0.0/8`, and `resolver-10` before
836
+ `resolver-9` — and a value stated twice breaks it as well. A list out of order is the one plan
837
+ refusal the contract names: `snapshotRuntimeNetworkAddressPlan` (and
838
+ `admitRuntimeNetworkAddressPlanChange` through it) throws
839
+ `data.RuntimeNetworkAddressPlanStructureError`, whose `violation` is
840
+ `{ field: 'prefixes' | 'pools' | 'resolvers' | 'platformEndpoints', rule: 'order' }` and whose
841
+ message quotes nothing from the plan. Every other refusal stays the contract's generic rejection.
842
+
843
+ ```typescript
844
+ try {
845
+ data.snapshotRuntimeNetworkAddressPlan(plan);
846
+ } catch (error) {
847
+ if (error instanceof data.RuntimeNetworkAddressPlanStructureError) {
848
+ error.violation; // { field: 'prefixes', rule: 'order' }
849
+ }
850
+ }
851
+ ```
852
+
832
853
  `data.IRuntimeNetworkVpnHub { clusterId, address, quicPort }` is one cluster's hub as its relay
833
854
  bound it. `runtimeNetworkVpnHubEndpoints(hub)` is the one derivation of what it contributes:
834
855
  `<clusterId>:quic` on `udp`, one endpoint per row of
@@ -868,7 +889,9 @@ outlive a plan revision, so it answers:
868
889
  reference check as removing it.
869
890
 
870
891
  `TRuntimeNetworkAddressPlanRefusal` adds `plan-resolver-referenced` and `plan-endpoint-referenced`,
871
- which only Cloudly can decide against live references, so every plan refusal has one type.
892
+ which only Cloudly can decide against live references, and `plan-unsorted`, which Cloudly answers
893
+ for a `RuntimeNetworkAddressPlanStructureError` with the list as its reference, so every plan
894
+ refusal has one type.
872
895
  `requests.network` carries `setRuntimeNetworkAddressPlan { identity, expectedRevision, plan }`
873
896
  (`expectedRevision: null` when no plan exists yet) and `getRuntimeNetworkAddressPlan`, which answers
874
897
  `null` until the first plan is set.
@@ -2319,9 +2342,13 @@ with `clusterRelayCertificateDomainName(relay)`, which returns the origin's host
2319
2342
  Cloudly issues the certificate for and owns the A record for. An origin naming an address literal
2320
2343
  therefore has no issuable certificate.
2321
2344
 
2322
- `data.clusterRelayUndispatchedRefusals` names the four registration refusals that end a relay's
2323
- custody — `relay-cluster-not-enabled`, `relay-node-foreign`, `relay-sequence-not-advancing` and
2324
- `relay-credential-generation-stale` — with `data.TClusterRelayUndispatchedRefusal` as their union.
2345
+ `data.clusterRelayUndispatchedRefusals` names the five registration refusals that end a relay's
2346
+ custody — `relay-cluster-not-enabled`, `relay-node-foreign`, `relay-node-unknown`,
2347
+ `relay-sequence-not-advancing` and `relay-credential-generation-stale` — with
2348
+ `data.TClusterRelayUndispatchedRefusal` as their union. `relay-node-foreign` names a node of another
2349
+ cluster; `relay-node-unknown` names a node Cloudly does not hold at all, because no Spark
2350
+ enrollment has created it yet, so the node a relay's `COREFLOW_NODE_ID` names is enrolled before
2351
+ the relay registers.
2325
2352
  Each is Cloudly reading its own records and stating that it does not dispatch to this relay, so a
2326
2353
  relay that hears one drops what it holds for its nodes instead of waiting. A refusal that only
2327
2354
  says Cloudly could not verify the relay states nothing about dispatch and is deliberately not in
@@ -2941,7 +2968,62 @@ const provisioning: requests.gateway.IReq_ProvisionGatewayClientCredential['requ
2941
2968
  };
2942
2969
  ```
2943
2970
 
2944
- `getGatewayClientContext` returns effective live policy. A `gatewayClient` role necessarily includes the credential ID, bound client ID/type, and `policyGeneration`; consumers should reject admin/operator or mismatched contexts rather than falling back to a caller-supplied owner ID. `getGatewayClientMailOverview` provides an owner-scoped domain and recent-message summary. `getGatewayClientMailDomainCount` derives ownership exclusively from the authenticating gateway credential and returns `{ count: number }` for its distinct configured mail domains. Cloudly therefore uses only `dcrouterGatewayApiToken`; the former `dcrouterOpsApiToken` setting is not part of `data.ICloudlySettings`.
2971
+ `getGatewayClientContext` returns effective live policy. A `gatewayClient` role necessarily includes the credential ID, bound client ID/type, and `policyGeneration`; consumers should reject admin/operator or mismatched contexts rather than falling back to a caller-supplied owner ID. `getGatewayClientMailOverview` provides an owner-scoped domain and recent-message summary. `getGatewayClientMailDomainCount` derives ownership exclusively from the authenticating gateway credential and returns `{ count: number }` for its distinct configured mail domains. Cloudly therefore holds only its gateway-client credential, as the system secret `DCROUTER_GATEWAY_API_TOKEN` (see Cloudly Gateway Credential Bootstrap below); neither it nor the former `dcrouterOpsApiToken` is part of `data.ICloudlySettings`.
2972
+
2973
+ ### Cloudly Gateway Credential Bootstrap
2974
+
2975
+ Cloudly enrolls itself at dcrouter as one least-privilege gateway client. The only way a gateway
2976
+ credential enters Cloudly is a dcrouter admin token an administrator hands in once, for the first
2977
+ enrollment and for every re-bootstrap a stale policy asks for — a changed gateway setting, or a
2978
+ runtime network address plan whose DNS record allowance moved.
2979
+
2980
+ - `requests.settings.IReq_Any_Cloudly_BootstrapExternalGatewayCredential`
2981
+ (`bootstrapExternalGatewayCredential`): `{ identity, expectedGatewayUrl, expectedGatewayClientId,
2982
+ bootstrapToken: { mode: 'sealed', envelope } }` → `{ state }`. The token is sealed to Cloudly's
2983
+ active secret ingress recipient (`requests.secret.IReq_GetSecretIngressRecipient`) under
2984
+ `data.createGatewayBootstrapEnvelopeContext({ gatewayUrl, gatewayClientId })`, so it opens only
2985
+ for a request naming the same dcrouter URL (HTTPS only, since an admin token is on the wire) and
2986
+ client id, and Cloudly compares both with its own
2987
+ settings before the token leaves it. Cloudly asks dcrouter whether the token is an admin token,
2988
+ provisions, finalizes and stores its own gateway-client credential with it, and answers the
2989
+ enrollment that results. The admin token is used for that one call and never stored; revoke it at
2990
+ dcrouter afterwards. A refusal leaves the held credential unchanged and is one of
2991
+ `data.externalGatewayBootstrapRefusals`: `gateway-unconfigured`, `gateway-target-mismatch`,
2992
+ `bootstrap-token-invalid`, `bootstrap-token-rejected`, `bootstrap-token-not-admin`,
2993
+ `bootstrap-candidate-pending`, `gateway-unreachable` and `bootstrap-provisioning-refused`.
2994
+ - `requests.settings.IReq_Any_Cloudly_GetExternalGatewayEnrollmentState`
2995
+ (`getExternalGatewayEnrollmentState`): `{ identity }` → `{ state }`.
2996
+
2997
+ `data.IExternalGatewayEnrollmentState { status, reason?, lastCheckedAt?, nextRetryAt?,
2998
+ cachedValidationProof, finalizationPending }` never carries a credential. `status` is one of
2999
+ `data.externalGatewayEnrollmentStatuses`: `unconfigured`, `checking`, `ready`, `degraded` (dcrouter
3000
+ unreachable; Cloudly retries) and `admin-bootstrap-required`. Both sides judge values with
3001
+ `requests.settings.validateBootstrapExternalGatewayCredentialRequest(request, recipient)` (schema,
3002
+ recipient, context digest and the ciphertext bound, without opening anything),
3003
+ `requests.settings.validateGetExternalGatewayEnrollmentStateRequest`,
3004
+ `data.validateExternalGatewayEnrollmentState` and `data.isExternalGatewayBootstrapToken(bytes)`,
3005
+ which accepts 1 to 1024 bytes of visible ASCII (`data.externalGatewayBootstrapContract`).
3006
+
3007
+ ```typescript
3008
+ import * as smartcrypto from '@push.rocks/smartcrypto';
3009
+ import { data, requests } from '@serve.zone/interfaces';
3010
+
3011
+ const target = { gatewayUrl: 'https://gateway.example.com', gatewayClientId: 'cloudly.example.com' };
3012
+ const request: requests.settings.IReq_Any_Cloudly_BootstrapExternalGatewayCredential['request'] = {
3013
+ identity: { jwt: adminJwt },
3014
+ expectedGatewayUrl: target.gatewayUrl,
3015
+ expectedGatewayClientId: target.gatewayClientId,
3016
+ bootstrapToken: {
3017
+ mode: 'sealed',
3018
+ envelope: await smartcrypto.sealX25519Envelope({
3019
+ plaintext: adminTokenBytes,
3020
+ recipientPublicKey: ingressPublicKey,
3021
+ recipientKeyId: ingressRecipient.recipientKeyId,
3022
+ context: data.createGatewayBootstrapEnvelopeContext(target),
3023
+ }),
3024
+ },
3025
+ };
3026
+ ```
2945
3027
 
2946
3028
  ### Gateway Client Hostname Records and Certificates
2947
3029
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/interfaces',
6
- version: '32.28.0',
6
+ version: '32.29.0',
7
7
  description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
8
8
  }
@@ -175,6 +175,11 @@ export const clusterRelayUndispatchedRefusals = Object.freeze([
175
175
  'relay-cluster-not-enabled',
176
176
  /** The node the relay names belongs to another cluster than the one its identity names. */
177
177
  'relay-node-foreign',
178
+ /**
179
+ * The node the relay names does not exist: no Spark enrollment has created it yet. The relay's
180
+ * `COREFLOW_NODE_ID` must name a node Cloudly already holds, so the node is enrolled first.
181
+ */
182
+ 'relay-node-unknown',
178
183
  /** A registration of this relay identity at the same or a higher sequence is already recorded. */
179
184
  'relay-sequence-not-advancing',
180
185
  /**
@@ -4,7 +4,15 @@ import { computeRuntimeNetworkProtectedAuthorityDigest, runtimeNetworkAuthorityC
4
4
  snapshotRuntimeNetworkProtectedAuthority } from './networkauthority.js';
5
5
  import { captureNetwork, failNetwork, networkContains, networkCounter, networkEqual, networkId, networkIpv4, networkList,
6
6
  networkOverlaps, networkPrefix, networkPrefixBounds, networkPrivatePrefix, networkRecord, networkSafe,
7
- requireNetwork } from '../private/networkcontract.js';
7
+ requireNetwork, RuntimeNetworkAddressPlanStructureError, type TRuntimeNetworkAddressPlanOrderedField,
8
+ } from '../private/networkcontract.js';
9
+
10
+ export { RuntimeNetworkAddressPlanStructureError } from '../private/networkcontract.js';
11
+ export type {
12
+ IRuntimeNetworkAddressPlanStructureViolation,
13
+ TRuntimeNetworkAddressPlanOrderedField,
14
+ TRuntimeNetworkAddressPlanStructureRule,
15
+ } from '../private/networkcontract.js';
8
16
 
9
17
  /**
10
18
  * The address space an administrator gives the runtime network, and the one input the protected
@@ -15,11 +23,25 @@ export interface IRuntimeNetworkAddressPlan {
15
23
  id: 'address-plan';
16
24
  /** Compare-and-swap counter; every accepted change advances it by one. */
17
25
  revision: number;
18
- /** Every protected prefix: they cover the pools, resolvers, platform endpoints and the VPN. */
26
+ /**
27
+ * Every protected prefix: they cover the pools, resolvers, platform endpoints and the VPN.
28
+ *
29
+ * Stated in strictly ascending string order of the prefix text. The order is lexicographic, not
30
+ * numeric: `10.10.0.0/16` comes before `10.2.0.0/16`, and `100.64.0.0/10` before `20.0.0.0/8`.
31
+ * A list out of that order, or one naming a prefix twice, is refused with
32
+ * `RuntimeNetworkAddressPlanStructureError` `{ field: 'prefixes', rule: 'order' }`.
33
+ */
19
34
  prefixes: string[];
35
+ /** Stated in strictly ascending string order of `id`; otherwise `{ field: 'pools', rule: 'order' }`. */
20
36
  pools: IRuntimeNetworkProtectedAuthority['pools'];
37
+ /** Stated in strictly ascending string order of `id`; otherwise `{ field: 'resolvers', rule: 'order' }`. */
21
38
  resolvers: IRuntimeNetworkProtectedAuthority['resolvers'];
22
- /** Without the cluster hubs, which the composed authority adds from the hubs it is given. */
39
+ /**
40
+ * Without the cluster hubs, which the composed authority adds from the hubs it is given.
41
+ *
42
+ * Stated in strictly ascending string order of `id`; otherwise
43
+ * `{ field: 'platformEndpoints', rule: 'order' }`.
44
+ */
23
45
  platformEndpoints: IRuntimeNetworkProtectedAuthority['platformEndpoints'];
24
46
  vpn: {
25
47
  /** The private prefix VPN control addresses are allocated from. */
@@ -63,7 +85,12 @@ export type TRuntimeNetworkAddressPlanChangeRefusal = 'plan-vpn-immutable' | 'pl
63
85
  * platform endpoint the change removes or changes while a router selection or a service still names it.
64
86
  */
65
87
  export type TRuntimeNetworkAddressPlanRefusal =
66
- | TRuntimeNetworkAddressPlanChangeRefusal | 'plan-resolver-referenced' | 'plan-endpoint-referenced';
88
+ | TRuntimeNetworkAddressPlanChangeRefusal | 'plan-resolver-referenced' | 'plan-endpoint-referenced'
89
+ /**
90
+ * A list of the plan is not in its canonical order; `RuntimeNetworkAddressPlanStructureError`
91
+ * names which one, and a refusal carries that field as its reference.
92
+ */
93
+ | 'plan-unsorted';
67
94
 
68
95
  export type TRuntimeNetworkAddressPlanChange =
69
96
  | { status: 'unchanged' }
@@ -180,14 +207,49 @@ const requireVpnProtected = (authority: IRuntimeNetworkProtectedAuthority, vpn:
180
207
  && !networkOverlaps(vpn.controlPrefix, vpn.hubPrefix));
181
208
  };
182
209
 
210
+ /** The key each ordered list of a plan is sorted by, or `undefined` for an entry no key can be read from. */
211
+ const planOrderKeys: Record<TRuntimeNetworkAddressPlanOrderedField, (entry: unknown) => string | undefined> = {
212
+ prefixes: entry => typeof entry === 'string' ? entry : undefined,
213
+ pools: entry => entryId(entry),
214
+ resolvers: entry => entryId(entry),
215
+ platformEndpoints: entry => entryId(entry),
216
+ };
217
+
218
+ function entryId(entry: unknown): string | undefined {
219
+ if (entry === null || typeof entry !== 'object' || Array.isArray(entry)) return undefined;
220
+ const id = (entry as Record<string, unknown>).id;
221
+ return typeof id === 'string' ? id : undefined;
222
+ }
223
+
224
+ /**
225
+ * Refuses a plan list out of its canonical order by name: strictly ascending by the list's key, in
226
+ * JavaScript string order, which is the order the protected authority contract reads it in. A list
227
+ * whose keys cannot all be read is left to the structural check, which refuses it without a name.
228
+ */
229
+ const requirePlanOrder = (item: Record<string, unknown>): void => {
230
+ for (const field of ['prefixes', 'pools', 'resolvers', 'platformEndpoints'] as const) {
231
+ const list = item[field];
232
+ if (!Array.isArray(list)) continue;
233
+ const keys = list.map(planOrderKeys[field]);
234
+ if (keys.some(key => key === undefined)) continue;
235
+ if (!keys.every((key, index) => index === 0 || (keys[index - 1] as string) < (key as string))) {
236
+ throw new RuntimeNetworkAddressPlanStructureError({ field, rule: 'order' });
237
+ }
238
+ }
239
+ };
240
+
183
241
  /**
184
242
  * Structural snapshot for exact persistence and for a plan write. The plan's own sets pass the
185
243
  * protected authority's own validator, so no plan can describe an authority that contract refuses,
186
244
  * and both VPN prefixes are reserved inside the protected space the plan states.
245
+ *
246
+ * A list out of its canonical order is refused with `RuntimeNetworkAddressPlanStructureError`,
247
+ * which names the list; every other refusal is the contract's generic rejection.
187
248
  */
188
249
  export const snapshotRuntimeNetworkAddressPlan = (value: unknown): IRuntimeNetworkAddressPlan => networkSafe(() => {
189
250
  const item = networkRecord(captureNetwork(value), ['id', 'revision', 'prefixes', 'pools', 'resolvers', 'platformEndpoints', 'vpn']);
190
251
  requireNetwork(item.id === runtimeNetworkAddressPlanContract.id);
252
+ requirePlanOrder(item);
191
253
  const own = authorityOf({ prefixes: item.prefixes, pools: item.pools, resolvers: item.resolvers,
192
254
  platformEndpoints: item.platformEndpoints }, validationFrame);
193
255
  const plan: IRuntimeNetworkAddressPlan = { id: runtimeNetworkAddressPlanContract.id, revision: networkCounter(item.revision),
package/ts/data/secret.ts CHANGED
@@ -1893,6 +1893,22 @@ export const createAppStoreInstallSecretEnvelopeContext = (contextArg: {
1893
1893
  : null,
1894
1894
  });
1895
1895
 
1896
+ /**
1897
+ * The context a dcrouter admin bootstrap token is sealed under for `bootstrapExternalGatewayCredential`.
1898
+ *
1899
+ * It binds the envelope to the dcrouter URL and the gateway client id the administrator named, so a
1900
+ * sealed token opens only for a request that states the same target, and Cloudly hands it only to
1901
+ * a gateway its own settings name.
1902
+ */
1903
+ export const createGatewayBootstrapEnvelopeContext = (contextArg: {
1904
+ gatewayUrl: string;
1905
+ gatewayClientId: string;
1906
+ }): Uint8Array => contextBytes({
1907
+ purpose: 'serve.zone/gateway-bootstrap',
1908
+ gatewayUrl: contextArg.gatewayUrl,
1909
+ gatewayClientId: contextArg.gatewayClientId,
1910
+ });
1911
+
1896
1912
  export const createResolvedSecretMaterialEnvelopeContext = (contextArg: {
1897
1913
  recipientKeyId: string;
1898
1914
  organizationId: string;