@serve.zone/interfaces 23.0.4 → 23.2.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/readme.md CHANGED
@@ -67,6 +67,53 @@ Primary v23 additions include:
67
67
  - Mandatory `IImmutableContainerInvocationV1` evidence on immutable image
68
68
  deployment plans.
69
69
 
70
+ ### Secrets v23.1 Runtime Registration And Reporting
71
+
72
+ The Node-only `@serve.zone/interfaces/runtime` export adds the live contract
73
+ that Cloudly must validate before publishing secret-bearing desired state to a
74
+ Coreflow connection:
75
+
76
+ - `getSecretRecipientEnrollmentState` returns either an exact generation-zero
77
+ empty state or the complete valid recipient set for the cluster derived from
78
+ the verified JWT.
79
+ - `getCoreflowSecretRuntimeRegistrationExpectation` returns the authoritative
80
+ live reporter session, target-node set, active recipient, and approved
81
+ WorkloadInit artifacts for the cluster derived from the verified JWT.
82
+ - `coreflowSecretRuntimeRegistrationTagId` is the sole dedicated TypedSocket
83
+ tag identifier. Its payload is exactly
84
+ `ICoreflowSecretRuntimeRegistrationV1`; cluster scope comes from the verified
85
+ connection identity rather than the tag.
86
+ - `ICoreflowSecretRuntimeRegistrationV1` binds a reporter session to the exact
87
+ authoritative schedulable target-node set, required secret capabilities,
88
+ active recipient, approved WorkloadInit OCI index, and exact per-platform
89
+ manifest and installed-executable digests.
90
+ - `validateCoreflowSecretRuntimeRegistration` compares the registration with a
91
+ trusted expectation built by Cloudly, including the live reporter session.
92
+ Missing, extra, duplicate, reordered, or mismatched node evidence fails
93
+ closed. Consumers must discard the registration on transport disconnect, tag
94
+ removal or replacement, or any live session, placement, artifact, or
95
+ recipient expectation change before publishing more secret-bearing state.
96
+ - `reportSecretDeploymentState` reports only `applying`, `applied`, `drifted`,
97
+ or `failed` for the manifest and plan revision selected by Cloudly. The
98
+ validator receives the trusted cluster ID after JWT verification and the
99
+ trusted live reporter session. Wire-provided manifest scope is checked
100
+ against, and never replaces, that trusted authority.
101
+
102
+ The package validates report shape, digest, trusted cluster, and trusted live
103
+ session; it does not persist replay state or mutate deployment plans. Deployment
104
+ report consumers must persist an atomic receipt keyed by the verified cluster,
105
+ reporter session, service, and positive sequence. The report digest uses
106
+ fixed-order JSON and excludes only the JWT identity and `reportDigest`. The
107
+ consumer accepts the exact next sequence once, returns the prior response for a
108
+ same-digest replay, rejects a different-digest replay, and ensures a plan
109
+ revision CAS failure consumes neither the sequence nor a receipt. Timestamps
110
+ are informational and never replace live session, placement, artifact,
111
+ recipient, sequence, or plan-revision fences.
112
+
113
+ `createWorkloadInitEnvironmentMap` now rejects manifests without any
114
+ `launcher-environment` delivery. Consumers must bypass WorkloadInit for
115
+ file-only manifests.
116
+
70
117
  ## Portable Storage Contracts
71
118
 
72
119
  App Store templates can declare logical, template-local `storageClasses` and
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/interfaces',
6
- version: '23.0.4',
6
+ version: '23.2.0',
7
7
  description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
8
8
  }
@@ -71,6 +71,8 @@ export interface ICoreflowRuntimeCapabilities {
71
71
  sealedSecretMaterialVersion: 1;
72
72
  secretRecipientEnrollmentVersion: 1;
73
73
  workloadInitEnvironmentVersion: 1;
74
+ /** Coreflow can submit replay-safe schema-v1 secret deployment reports. */
75
+ secretDeploymentReportVersion?: 1;
74
76
  }
75
77
 
76
78
  export type TImmutableContainerPlatform = 'linux/amd64' | 'linux/arm64';
package/ts/data/secret.ts CHANGED
@@ -922,7 +922,7 @@ export const validateResolvedSecretManifest = (
922
922
  return errors;
923
923
  };
924
924
 
925
- const validateResolvedSecretManifestReference = (
925
+ const validateResolvedSecretManifestReferenceAtPath = (
926
926
  referenceArg: unknown,
927
927
  expectedClusterIdArg: string,
928
928
  pathArg: string,
@@ -958,6 +958,25 @@ const validateResolvedSecretManifestReference = (
958
958
  return [];
959
959
  };
960
960
 
961
+ /** Strict public validator for a cluster-scoped resolved manifest reference. */
962
+ export const validateResolvedSecretManifestReference = (
963
+ referenceArg: unknown,
964
+ expectedClusterIdArg: string,
965
+ ): string[] => {
966
+ try {
967
+ if (!isSecretIdentifier(expectedClusterIdArg)) {
968
+ return ['expected cluster id must be canonical'];
969
+ }
970
+ return validateResolvedSecretManifestReferenceAtPath(
971
+ referenceArg,
972
+ expectedClusterIdArg,
973
+ 'resolved secret manifest reference',
974
+ );
975
+ } catch {
976
+ return ['resolved secret manifest reference must be safely inspectable'];
977
+ }
978
+ };
979
+
961
980
  export const validateServiceSecretDeploymentPlan = (
962
981
  planArg: unknown,
963
982
  expectedTargetClusterIdsArg?: string[],
@@ -992,7 +1011,7 @@ export const validateServiceSecretDeploymentPlan = (
992
1011
  expectedClusterIdArg: string,
993
1012
  pathArg: string,
994
1013
  ): void => {
995
- const referenceErrors = validateResolvedSecretManifestReference(
1014
+ const referenceErrors = validateResolvedSecretManifestReferenceAtPath(
996
1015
  referenceArg,
997
1016
  expectedClusterIdArg,
998
1017
  pathArg,
@@ -1183,6 +1202,9 @@ export const createWorkloadInitEnvironmentMap = async (
1183
1202
  source: createLauncherSecretSourcePath(resource),
1184
1203
  };
1185
1204
  }));
1205
+ if (entries.length === 0) {
1206
+ throw new Error('workload init map requires at least one launcher-environment delivery');
1207
+ }
1186
1208
  entries.sort((leftArg, rightArg) => (
1187
1209
  leftArg.variableName < rightArg.variableName
1188
1210
  ? -1