@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.
- package/changelog.md +32 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/cluster.d.ts +1 -1
- package/dist_ts/data/cluster.js +6 -1
- package/dist_ts/data/networkaddressplan.d.ts +27 -3
- package/dist_ts/data/networkaddressplan.js +38 -2
- package/dist_ts/data/secret.d.ts +11 -0
- package/dist_ts/data/secret.js +13 -1
- package/dist_ts/data/settings.d.ts +51 -0
- package/dist_ts/data/settings.js +83 -1
- package/dist_ts/private/networkcontract.d.ts +18 -0
- package/dist_ts/private/networkcontract.js +23 -6
- package/dist_ts/requests/network.d.ts +2 -1
- package/dist_ts/requests/settings.d.ts +56 -2
- package/dist_ts/requests/settings.js +91 -1
- package/package.json +1 -1
- package/readme.md +87 -5
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/cluster.ts +5 -0
- package/ts/data/networkaddressplan.ts +66 -4
- package/ts/data/secret.ts +16 -0
- package/ts/data/settings.ts +127 -0
- package/ts/private/networkcontract.ts +36 -1
- package/ts/requests/network.ts +2 -1
- package/ts/requests/settings.ts +162 -2
|
@@ -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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
12
|
-
|
|
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 {
|
|
3
|
-
import type {
|
|
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
|
-
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9yZXF1ZXN0cy9zZXR0aW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssVUFBVSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxZQUFZLE1BQU0scUJBQXFCLENBQUM7QUFJcEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBeUhoRixNQUFNLGNBQWMsR0FBRyxDQUFDLFFBQWlCLEVBQVcsRUFBRTtJQUNwRCxNQUFNLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5QyxPQUFPLFFBQVEsS0FBSyxJQUFJLElBQUksT0FBTyxRQUFRLENBQUMsR0FBRyxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7QUFDMUYsQ0FBQyxDQUFDO0FBRUYsaUdBQWlHO0FBQ2pHLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxNQUFlLEVBQUUsV0FBb0IsRUFBWSxFQUFFO0lBQ3hGLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUM1QixJQUFJLEdBQW9CLENBQUM7SUFDekIsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRO1dBQ3pCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQztXQUNqQixNQUFNLENBQUMsTUFBTSxJQUFJLFlBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQzVGLElBQUksQ0FBQztZQUNILEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsR0FBRyxHQUFHLFNBQVMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksQ0FBQyxHQUFHO1dBQ0gsR0FBRyxDQUFDLFFBQVEsS0FBSyxRQUFRO1dBQ3pCLEdBQUcsQ0FBQyxRQUFRLEtBQUssRUFBRTtXQUNuQixHQUFHLENBQUMsUUFBUSxLQUFLLEVBQUU7V0FDbkIsR0FBRyxDQUFDLE1BQU0sS0FBSyxFQUFFO1dBQ2pCLEdBQUcsQ0FBQyxJQUFJLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDckIsTUFBTSxDQUFDLElBQUksQ0FBQywwRkFBMEYsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFDRCxJQUFJLE9BQU8sV0FBVyxLQUFLLFFBQVE7V0FDOUIsV0FBVyxDQUFDLE1BQU0sS0FBSyxDQUFDO1dBQ3hCLFdBQVcsQ0FBQyxNQUFNLEdBQUcsWUFBWSxDQUFDLGdDQUFnQyxDQUFDLDRCQUE0QjtXQUMvRixDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUZBQW1GLENBQUMsQ0FBQztJQUNuRyxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlEQUFpRCxHQUFHLEtBQUssRUFDcEUsVUFBbUIsRUFDbkIseUJBQXlELEVBQ3RDLEVBQUU7SUFDckIsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDL0MsSUFBSSxPQUFPLEtBQUssSUFBSTtRQUFFLE9BQU8sQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0lBQzFFLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDLFVBQVUsRUFBRSxvQkFBb0IsRUFBRSx5QkFBeUIsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM1RyxNQUFNLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUNELElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFDRCxNQUFNLFlBQVksR0FBRyw2QkFBNkIsQ0FDaEQsT0FBTyxDQUFDLGtCQUFrQixFQUMxQixPQUFPLENBQUMsdUJBQXVCLENBQ2hDLENBQUM7SUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUM7SUFDN0IsTUFBTSxVQUFVLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzlELElBQUksVUFBVSxLQUFLLElBQUksSUFBSSxVQUFVLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3hELE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLENBQUMsQ0FBQztRQUN0RCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBQ0QsTUFBTSxlQUFlLEdBQUcsWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxVQUFVLENBQUMscUNBQXFDLENBQUM7WUFDL0MsVUFBVSxFQUFFLE9BQU8sQ0FBQyxrQkFBNEI7WUFDaEQsZUFBZSxFQUFFLE9BQU8sQ0FBQyx1QkFBaUM7U0FDM0QsQ0FBQztRQUNKLENBQUMsQ0FBQyxJQUFJLFVBQVUsRUFBRSxDQUFDO0lBQ3JCLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLFVBQVUsQ0FBQyxvQ0FBb0MsQ0FDbEUsVUFBVSxFQUNWLHlCQUF5QixFQUN6QixlQUFlLENBQ2hCLENBQUMsQ0FBQztJQUNILE1BQU0sUUFBUSxHQUFHLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN6RCxJQUFJLFFBQVEsS0FBSyxJQUFJO1dBQ2hCLE9BQU8sUUFBUSxDQUFDLFVBQVUsS0FBSyxRQUFRO1dBQ3ZDLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTTtjQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN6RixNQUFNLENBQUMsSUFBSSxDQUNULG1DQUFtQyxZQUFZLENBQUMsZ0NBQWdDLENBQUMsaUJBQWlCLFFBQVEsQ0FDM0csQ0FBQztJQUNKLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDLENBQUM7QUFFRiwrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sZ0RBQWdELEdBQUcsQ0FBQyxVQUFtQixFQUFZLEVBQUU7SUFDaEcsTUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDL0MsSUFBSSxPQUFPLEtBQUssSUFBSTtRQUFFLE9BQU8sQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO0lBQ2pGLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN6QyxNQUFNLENBQUMsSUFBSSxDQUFDLDZEQUE2RCxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUNELElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDLENBQUMifQ==
|
package/package.json
CHANGED
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,
|
|
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
|
|
2323
|
-
custody — `relay-cluster-not-enabled`, `relay-node-foreign`, `relay-
|
|
2324
|
-
`relay-credential-generation-stale` — with
|
|
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
|
|
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
|
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/data/cluster.ts
CHANGED
|
@@ -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
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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;
|