@serve.zone/interfaces 21.1.0 → 23.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +23 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/appstore/types.d.ts +31 -16
- package/dist_ts/appstore/types.js +208 -11
- package/dist_ts/data/coremail.d.ts +83 -9
- package/dist_ts/data/coremail.js +67 -1
- package/dist_ts/data/coremail.runtime.d.ts +27 -1
- package/dist_ts/data/coremail.runtime.js +800 -36
- package/dist_ts/data/deploymentoperation.js +6 -20
- package/dist_ts/data/deploymentpreflight.d.ts +2 -6
- package/dist_ts/data/deploymentpreflight.js +1 -1
- package/dist_ts/data/hostedapp.d.ts +40 -14
- package/dist_ts/data/hostedapp.js +90 -1
- package/dist_ts/data/immutableimage.d.ts +30 -1
- package/dist_ts/data/immutableimage.js +103 -1
- package/dist_ts/data/index.d.ts +0 -2
- package/dist_ts/data/index.js +1 -3
- package/dist_ts/data/secret.d.ts +186 -13
- package/dist_ts/data/secret.js +543 -45
- package/dist_ts/data/service.d.ts +0 -39
- package/dist_ts/data/service.js +1 -77
- package/dist_ts/data/settings.d.ts +62 -43
- package/dist_ts/data/settings.js +34 -2
- package/dist_ts/platform/storage.d.ts +13 -14
- package/dist_ts/platform/storage.js +1 -1
- package/dist_ts/platform/storagemigration.d.ts +8 -8
- package/dist_ts/platform/storagemigration.golden.d.ts +2 -2
- package/dist_ts/platform/storagemigration.golden.js +19 -88
- package/dist_ts/platform/storagemigration.js +46 -58
- package/dist_ts/platform/types.d.ts +5 -19
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/dist_ts/requests/coremail.d.ts +12 -5
- package/dist_ts/requests/hostedapp.d.ts +12 -9
- package/dist_ts/requests/hostedapp.js +38 -1
- package/dist_ts/requests/index.d.ts +1 -3
- package/dist_ts/requests/index.js +2 -4
- package/dist_ts/requests/platform.d.ts +0 -1
- package/dist_ts/requests/secret.d.ts +23 -17
- package/dist_ts/requests/secret.js +161 -2
- package/dist_ts/requests/service.d.ts +0 -13
- package/dist_ts/requests/settings.d.ts +3 -3
- package/dist_ts/runtime.d.ts +78 -26
- package/dist_ts/runtime.js +219 -19
- package/package.json +2 -1
- package/readme.md +163 -38
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/appstore/types.ts +251 -25
- package/ts/data/coremail.runtime.ts +1212 -38
- package/ts/data/coremail.ts +120 -8
- package/ts/data/deploymentoperation.ts +7 -31
- package/ts/data/deploymentpreflight.ts +2 -5
- package/ts/data/hostedapp.ts +144 -18
- package/ts/data/immutableimage.ts +150 -1
- package/ts/data/index.ts +0 -2
- package/ts/data/secret.ts +775 -53
- package/ts/data/service.ts +0 -118
- package/ts/data/settings.ts +70 -80
- package/ts/platform/storage.ts +15 -16
- package/ts/platform/storagemigration.golden.ts +18 -95
- package/ts/platform/storagemigration.ts +57 -87
- package/ts/platform/types.ts +6 -19
- package/ts/plugins.ts +2 -0
- package/ts/requests/coremail.ts +13 -4
- package/ts/requests/hostedapp.ts +50 -9
- package/ts/requests/index.ts +0 -4
- package/ts/requests/platform.ts +0 -1
- package/ts/requests/secret.ts +204 -9
- package/ts/requests/service.ts +0 -16
- package/ts/requests/settings.ts +3 -3
- package/ts/runtime.ts +314 -41
- package/dist_ts/data/secretbundle.d.ts +0 -57
- package/dist_ts/data/secretbundle.js +0 -2
- package/dist_ts/data/secretgroup.d.ts +0 -52
- package/dist_ts/data/secretgroup.js +0 -2
- package/dist_ts/requests/secretbundle.d.ts +0 -75
- package/dist_ts/requests/secretbundle.js +0 -4
- package/dist_ts/requests/secretgroup.d.ts +0 -52
- package/dist_ts/requests/secretgroup.js +0 -4
- package/ts/data/secretbundle.ts +0 -65
- package/ts/data/secretgroup.ts +0 -58
- package/ts/requests/secretbundle.ts +0 -103
- package/ts/requests/secretgroup.ts +0 -74
|
@@ -67,7 +67,31 @@ export interface ICoreflowRuntimeCapabilities {
|
|
|
67
67
|
/** Coreflow can answer the versioned, node-scoped Corestore inventory probe. */
|
|
68
68
|
corestoreInventoryVersion?: 1;
|
|
69
69
|
/** Coreflow can consume exact, cluster-scoped resolved secret manifests. */
|
|
70
|
-
secretManifestVersion
|
|
70
|
+
secretManifestVersion: 2;
|
|
71
|
+
sealedSecretMaterialVersion: 1;
|
|
72
|
+
secretRecipientEnrollmentVersion: 1;
|
|
73
|
+
workloadInitEnvironmentVersion: 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type TImmutableContainerPlatform = 'linux/amd64' | 'linux/arm64';
|
|
77
|
+
|
|
78
|
+
export interface IImmutableContainerInvocationPlatformEvidenceV1 {
|
|
79
|
+
platform: TImmutableContainerPlatform;
|
|
80
|
+
platformManifestDigest: TSha256Digest;
|
|
81
|
+
imageConfigDigest: TSha256Digest;
|
|
82
|
+
/** Effective non-empty OCI argv after applying the deployment containerArgs. */
|
|
83
|
+
effectiveArgv: string[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface IImmutableContainerInvocationV1 {
|
|
87
|
+
schemaVersion: 1;
|
|
88
|
+
/** Sorted, unique, non-empty and limited to the authoritative platform union. */
|
|
89
|
+
targetPlatforms: TImmutableContainerPlatform[];
|
|
90
|
+
/** The one effective argv shared by every target platform. */
|
|
91
|
+
argv: string[];
|
|
92
|
+
/** Sorted exact one-to-one platform evidence. */
|
|
93
|
+
evidence: IImmutableContainerInvocationPlatformEvidenceV1[];
|
|
94
|
+
digest: TSha256Digest;
|
|
71
95
|
}
|
|
72
96
|
|
|
73
97
|
/**
|
|
@@ -221,6 +245,8 @@ export interface IImmutableImageDeploymentPlan {
|
|
|
221
245
|
requestedDigest: TSha256Digest;
|
|
222
246
|
digestPinnedImageReference: string;
|
|
223
247
|
manifestMediaType: TOciManifestMediaType;
|
|
248
|
+
/** Mandatory immutable command/config evidence for every target platform. */
|
|
249
|
+
containerInvocation: IImmutableContainerInvocationV1;
|
|
224
250
|
createdAt: number;
|
|
225
251
|
mode: TImmutableImageRolloutMode;
|
|
226
252
|
/** Full pre-adoption service configuration fence, required only for adoption. */
|
|
@@ -324,6 +350,122 @@ export interface IImageRolloutStatus {
|
|
|
324
350
|
|
|
325
351
|
const sha256DigestRegex = /^sha256:[a-f0-9]{64}$/;
|
|
326
352
|
|
|
353
|
+
const immutableContainerPlatforms = new Set<TImmutableContainerPlatform>([
|
|
354
|
+
'linux/amd64',
|
|
355
|
+
'linux/arm64',
|
|
356
|
+
]);
|
|
357
|
+
|
|
358
|
+
const validateImmutableArgv = (argvArg: unknown): argvArg is string[] => (
|
|
359
|
+
Array.isArray(argvArg)
|
|
360
|
+
&& argvArg.length > 0
|
|
361
|
+
&& argvArg.length <= 128
|
|
362
|
+
&& argvArg.every((argumentArg) => typeof argumentArg === 'string'
|
|
363
|
+
&& argumentArg.length > 0
|
|
364
|
+
&& !/[\u0000-\u001f\u007f]/.test(argumentArg)
|
|
365
|
+
&& new TextEncoder().encode(argumentArg).byteLength <= 4096)
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
export const createImmutableContainerInvocationDigestInput = (
|
|
369
|
+
invocationArg: Omit<IImmutableContainerInvocationV1, 'digest'> | IImmutableContainerInvocationV1,
|
|
370
|
+
): string => JSON.stringify({
|
|
371
|
+
schemaVersion: invocationArg.schemaVersion,
|
|
372
|
+
targetPlatforms: invocationArg.targetPlatforms,
|
|
373
|
+
argv: invocationArg.argv,
|
|
374
|
+
evidence: invocationArg.evidence.map((entryArg) => ({
|
|
375
|
+
platform: entryArg.platform,
|
|
376
|
+
platformManifestDigest: entryArg.platformManifestDigest,
|
|
377
|
+
imageConfigDigest: entryArg.imageConfigDigest,
|
|
378
|
+
effectiveArgv: entryArg.effectiveArgv,
|
|
379
|
+
})),
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
export const computeImmutableContainerInvocationDigest = async (
|
|
383
|
+
invocationArg: Omit<IImmutableContainerInvocationV1, 'digest'> | IImmutableContainerInvocationV1,
|
|
384
|
+
): Promise<TSha256Digest> => {
|
|
385
|
+
const input = new TextEncoder().encode(createImmutableContainerInvocationDigestInput(invocationArg));
|
|
386
|
+
const digest = new Uint8Array(await globalThis.crypto.subtle.digest(
|
|
387
|
+
'SHA-256',
|
|
388
|
+
input.buffer as ArrayBuffer,
|
|
389
|
+
));
|
|
390
|
+
return `sha256:${[...digest]
|
|
391
|
+
.map((byteArg) => byteArg.toString(16).padStart(2, '0'))
|
|
392
|
+
.join('')}` as TSha256Digest;
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
export const verifyImmutableContainerInvocationDigest = async (
|
|
396
|
+
invocationArg: IImmutableContainerInvocationV1,
|
|
397
|
+
): Promise<boolean> => invocationArg.digest
|
|
398
|
+
=== await computeImmutableContainerInvocationDigest(invocationArg);
|
|
399
|
+
|
|
400
|
+
export const validateImmutableContainerInvocation = (
|
|
401
|
+
invocationArg: unknown,
|
|
402
|
+
): string[] => {
|
|
403
|
+
if (!invocationArg || typeof invocationArg !== 'object' || Array.isArray(invocationArg)) {
|
|
404
|
+
return ['containerInvocation must be an object'];
|
|
405
|
+
}
|
|
406
|
+
const invocation = invocationArg as Record<string, unknown>;
|
|
407
|
+
const errors: string[] = [];
|
|
408
|
+
if (JSON.stringify(Object.keys(invocation).sort()) !== JSON.stringify([
|
|
409
|
+
'argv',
|
|
410
|
+
'digest',
|
|
411
|
+
'evidence',
|
|
412
|
+
'schemaVersion',
|
|
413
|
+
'targetPlatforms',
|
|
414
|
+
])) {
|
|
415
|
+
errors.push('containerInvocation must use its exact schema');
|
|
416
|
+
}
|
|
417
|
+
if (invocation.schemaVersion !== 1) errors.push('containerInvocation schemaVersion must be 1');
|
|
418
|
+
const platforms = Array.isArray(invocation.targetPlatforms)
|
|
419
|
+
? invocation.targetPlatforms
|
|
420
|
+
: [];
|
|
421
|
+
if (platforms.length === 0
|
|
422
|
+
|| platforms.some((platformArg) => typeof platformArg !== 'string'
|
|
423
|
+
|| !immutableContainerPlatforms.has(platformArg as TImmutableContainerPlatform))
|
|
424
|
+
|| new Set(platforms).size !== platforms.length
|
|
425
|
+
|| JSON.stringify(platforms) !== JSON.stringify([...platforms].sort())) {
|
|
426
|
+
errors.push('containerInvocation targetPlatforms must be sorted unique supported platforms');
|
|
427
|
+
}
|
|
428
|
+
if (!validateImmutableArgv(invocation.argv)) {
|
|
429
|
+
errors.push('containerInvocation argv must be a non-empty canonical argument vector');
|
|
430
|
+
}
|
|
431
|
+
const evidence = Array.isArray(invocation.evidence) ? invocation.evidence : [];
|
|
432
|
+
const evidencePlatforms: unknown[] = [];
|
|
433
|
+
for (const [index, entryArg] of evidence.entries()) {
|
|
434
|
+
if (!entryArg || typeof entryArg !== 'object' || Array.isArray(entryArg)) {
|
|
435
|
+
errors.push(`containerInvocation evidence[${index}] must be an object`);
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
const entry = entryArg as Record<string, unknown>;
|
|
439
|
+
if (JSON.stringify(Object.keys(entry).sort()) !== JSON.stringify([
|
|
440
|
+
'effectiveArgv',
|
|
441
|
+
'imageConfigDigest',
|
|
442
|
+
'platform',
|
|
443
|
+
'platformManifestDigest',
|
|
444
|
+
])) {
|
|
445
|
+
errors.push(`containerInvocation evidence[${index}] must use its exact schema`);
|
|
446
|
+
}
|
|
447
|
+
evidencePlatforms.push(entry.platform);
|
|
448
|
+
if (!immutableContainerPlatforms.has(entry.platform as TImmutableContainerPlatform)) {
|
|
449
|
+
errors.push(`containerInvocation evidence[${index}].platform is unsupported`);
|
|
450
|
+
}
|
|
451
|
+
if (!isSha256Digest(entry.platformManifestDigest as string)
|
|
452
|
+
|| !isSha256Digest(entry.imageConfigDigest as string)) {
|
|
453
|
+
errors.push(`containerInvocation evidence[${index}] digests must be canonical`);
|
|
454
|
+
}
|
|
455
|
+
if (!validateImmutableArgv(entry.effectiveArgv)
|
|
456
|
+
|| JSON.stringify(entry.effectiveArgv) !== JSON.stringify(invocation.argv)) {
|
|
457
|
+
errors.push(`containerInvocation evidence[${index}] effective argv must match`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (JSON.stringify(evidencePlatforms) !== JSON.stringify(platforms)) {
|
|
461
|
+
errors.push('containerInvocation evidence must exactly cover targetPlatforms in order');
|
|
462
|
+
}
|
|
463
|
+
if (typeof invocation.digest !== 'string' || !isSha256Digest(invocation.digest)) {
|
|
464
|
+
errors.push('containerInvocation digest must be canonical');
|
|
465
|
+
}
|
|
466
|
+
return errors;
|
|
467
|
+
};
|
|
468
|
+
|
|
327
469
|
export const normalizeSha256Digest = (digest: unknown): TSha256Digest | undefined => {
|
|
328
470
|
if (typeof digest !== 'string') return undefined;
|
|
329
471
|
const normalizedDigest = digest.trim().toLowerCase();
|
|
@@ -396,6 +538,7 @@ export const validateImmutableImageDeploymentPlan = (
|
|
|
396
538
|
].includes(planArg.manifestMediaType)) {
|
|
397
539
|
errors.push('immutable rollout root must be an OCI image index');
|
|
398
540
|
}
|
|
541
|
+
errors.push(...validateImmutableContainerInvocation(planArg.containerInvocation));
|
|
399
542
|
let expectedReference: string | undefined;
|
|
400
543
|
try {
|
|
401
544
|
expectedReference = buildDigestPinnedImageReference(
|
|
@@ -443,6 +586,12 @@ export const validateImmutableImageDeploymentPlan = (
|
|
|
443
586
|
return errors;
|
|
444
587
|
};
|
|
445
588
|
|
|
589
|
+
/** Coreflow uses this async verifier before resolving or opening secret material. */
|
|
590
|
+
export const verifyImmutableImageDeploymentPlan = async (
|
|
591
|
+
planArg: IImmutableImageDeploymentPlan,
|
|
592
|
+
): Promise<boolean> => validateImmutableImageDeploymentPlan(planArg).length === 0
|
|
593
|
+
&& await verifyImmutableContainerInvocationDigest(planArg.containerInvocation);
|
|
594
|
+
|
|
446
595
|
export const validateImageRolloutStatus = (statusArg: IImageRolloutStatus): string[] => {
|
|
447
596
|
const errors: string[] = [];
|
|
448
597
|
if (!isImmutableIdentifier(statusArg.rolloutId)) {
|
package/ts/data/index.ts
CHANGED
|
@@ -22,8 +22,6 @@ export * from './isolatedrestore.golden.js';
|
|
|
22
22
|
export * from './mail.js';
|
|
23
23
|
export * from './registry.js';
|
|
24
24
|
export * from './secret.js';
|
|
25
|
-
export * from './secretbundle.js';
|
|
26
|
-
export * from './secretgroup.js';
|
|
27
25
|
export * from './baremetal.js';
|
|
28
26
|
export * from './baseos.js';
|
|
29
27
|
export * from './backup.js';
|