@serve.zone/interfaces 22.0.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.
Files changed (75) hide show
  1. package/changelog.md +12 -0
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/appstore/types.d.ts +31 -16
  4. package/dist_ts/appstore/types.js +208 -11
  5. package/dist_ts/data/deploymentoperation.js +6 -20
  6. package/dist_ts/data/deploymentpreflight.d.ts +2 -6
  7. package/dist_ts/data/deploymentpreflight.js +1 -1
  8. package/dist_ts/data/hostedapp.d.ts +40 -14
  9. package/dist_ts/data/hostedapp.js +90 -1
  10. package/dist_ts/data/immutableimage.d.ts +30 -1
  11. package/dist_ts/data/immutableimage.js +103 -1
  12. package/dist_ts/data/index.d.ts +0 -2
  13. package/dist_ts/data/index.js +1 -3
  14. package/dist_ts/data/secret.d.ts +186 -13
  15. package/dist_ts/data/secret.js +543 -45
  16. package/dist_ts/data/service.d.ts +0 -39
  17. package/dist_ts/data/service.js +1 -77
  18. package/dist_ts/data/settings.d.ts +62 -43
  19. package/dist_ts/data/settings.js +34 -2
  20. package/dist_ts/platform/storage.d.ts +13 -14
  21. package/dist_ts/platform/storage.js +1 -1
  22. package/dist_ts/platform/storagemigration.d.ts +8 -8
  23. package/dist_ts/platform/storagemigration.golden.d.ts +2 -2
  24. package/dist_ts/platform/storagemigration.golden.js +19 -88
  25. package/dist_ts/platform/storagemigration.js +46 -58
  26. package/dist_ts/platform/types.d.ts +5 -19
  27. package/dist_ts/plugins.d.ts +2 -1
  28. package/dist_ts/plugins.js +3 -2
  29. package/dist_ts/requests/hostedapp.d.ts +12 -9
  30. package/dist_ts/requests/hostedapp.js +38 -1
  31. package/dist_ts/requests/index.d.ts +1 -3
  32. package/dist_ts/requests/index.js +2 -4
  33. package/dist_ts/requests/platform.d.ts +0 -1
  34. package/dist_ts/requests/secret.d.ts +23 -17
  35. package/dist_ts/requests/secret.js +161 -2
  36. package/dist_ts/requests/service.d.ts +0 -13
  37. package/dist_ts/requests/settings.d.ts +3 -3
  38. package/dist_ts/runtime.d.ts +78 -26
  39. package/dist_ts/runtime.js +219 -19
  40. package/package.json +2 -1
  41. package/readme.md +106 -28
  42. package/ts/00_commitinfo_data.ts +1 -1
  43. package/ts/appstore/types.ts +251 -25
  44. package/ts/data/deploymentoperation.ts +7 -31
  45. package/ts/data/deploymentpreflight.ts +2 -5
  46. package/ts/data/hostedapp.ts +144 -18
  47. package/ts/data/immutableimage.ts +150 -1
  48. package/ts/data/index.ts +0 -2
  49. package/ts/data/secret.ts +775 -53
  50. package/ts/data/service.ts +0 -118
  51. package/ts/data/settings.ts +70 -80
  52. package/ts/platform/storage.ts +15 -16
  53. package/ts/platform/storagemigration.golden.ts +18 -95
  54. package/ts/platform/storagemigration.ts +57 -87
  55. package/ts/platform/types.ts +6 -19
  56. package/ts/plugins.ts +2 -0
  57. package/ts/requests/hostedapp.ts +50 -9
  58. package/ts/requests/index.ts +0 -4
  59. package/ts/requests/platform.ts +0 -1
  60. package/ts/requests/secret.ts +204 -9
  61. package/ts/requests/service.ts +0 -16
  62. package/ts/requests/settings.ts +3 -3
  63. package/ts/runtime.ts +314 -41
  64. package/dist_ts/data/secretbundle.d.ts +0 -57
  65. package/dist_ts/data/secretbundle.js +0 -2
  66. package/dist_ts/data/secretgroup.d.ts +0 -52
  67. package/dist_ts/data/secretgroup.js +0 -2
  68. package/dist_ts/requests/secretbundle.d.ts +0 -75
  69. package/dist_ts/requests/secretbundle.js +0 -4
  70. package/dist_ts/requests/secretgroup.d.ts +0 -52
  71. package/dist_ts/requests/secretgroup.js +0 -4
  72. package/ts/data/secretbundle.ts +0 -65
  73. package/ts/data/secretgroup.ts +0 -58
  74. package/ts/requests/secretbundle.ts +0 -103
  75. package/ts/requests/secretgroup.ts +0 -74
@@ -1,41 +1,93 @@
1
- import type * as plugins from './plugins.js';
2
- import type { IIdentityCredential, IResolvedSecretManifest, TSha256Digest } from './data/index.js';
3
- /**
4
- * Runtime-only material. This module is exported only under the Node condition
5
- * and is intentionally unreachable from the universal/browser-facing barrel.
6
- */
7
- export interface IResolvedSecretMaterialValue {
1
+ import * as plugins from './plugins.js';
2
+ import type { IIdentityCredential, IResolvedSecretManifest, TSha256Digest, TSecretRecipientMetadata } from './data/index.js';
3
+ import { validateSecretRecipientMetadata } from './data/secret.js';
4
+ export interface ISealedResolvedSecretMaterialEntry {
8
5
  secretVersionId: string;
9
- value: string;
6
+ envelope: plugins.smartcrypto.IX25519EnvelopeV1;
10
7
  }
11
- export interface IResolvedSecretMaterial {
8
+ /** Runtime-only material. No plaintext value is represented in this DTO. */
9
+ export interface ISealedResolvedSecretMaterial {
12
10
  schemaVersion: 1;
13
- /** Full value-free manifest so the runtime can verify its canonical digest. */
11
+ /** Full schema-v2 value-free manifest used for digest and rollout verification. */
14
12
  manifest: IResolvedSecretManifest;
15
- /** Plaintext values keyed only by the exact version IDs pinned by the manifest. */
16
- values: IResolvedSecretMaterialValue[];
13
+ /** Sorted exact coverage of the manifest's pinned versions. */
14
+ entries: ISealedResolvedSecretMaterialEntry[];
15
+ }
16
+ export interface ISecretMaterialRequestFence {
17
+ serviceId: string;
18
+ imageRolloutId: string;
19
+ imageRolloutGeneration: number;
20
+ requestedImageDigest: TSha256Digest;
21
+ secretRolloutId: string;
22
+ secretRolloutGeneration: number;
23
+ manifestId: string;
24
+ manifestDigest: TSha256Digest;
25
+ expectedRecipientKeyId: string;
26
+ }
27
+ /** Request fence plus trusted local scope derived from the verified cluster identity. */
28
+ export interface ISecretMaterialExpectation extends ISecretMaterialRequestFence {
29
+ organizationId: string;
30
+ clusterId: string;
17
31
  }
18
32
  /**
19
- * Verifies the immutable manifest and requires exactly one material value for
20
- * every pinned version. Callers separately compare the verified manifest
21
- * reference to the request and their authenticated cluster scope.
22
- */
23
- export declare const verifyResolvedSecretMaterial: (materialArg: unknown) => Promise<boolean>;
24
- /**
25
- * Cluster and organization are derived from the verified JWT. A caller cannot
26
- * select either scope through request fields.
33
+ * Parses every envelope with SmartCrypto, verifies its bound context digest,
34
+ * and checks sorted exact version coverage. It never receives a private key
35
+ * and never decrypts material.
27
36
  */
37
+ export declare const verifySealedResolvedSecretMaterial: (materialArg: unknown, expectedArg: ISecretMaterialExpectation) => Promise<boolean>;
38
+ /** Organization and cluster are derived exclusively from the verified cluster JWT. */
28
39
  export interface IReq_GetResolvedSecretMaterial extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetResolvedSecretMaterial> {
29
40
  method: 'getResolvedSecretMaterial';
41
+ request: ISecretMaterialRequestFence & {
42
+ identity: IIdentityCredential;
43
+ };
44
+ response: {
45
+ material: ISealedResolvedSecretMaterial;
46
+ };
47
+ }
48
+ export interface ISecretRecipientEnrollmentChallengeV1 {
49
+ schemaVersion: 1;
50
+ enrollmentId: string;
51
+ clusterId: string;
52
+ recipientKeyId: string;
53
+ publicKey: string;
54
+ generation: number;
55
+ expiresAt: number;
56
+ /** Sealed random 32-byte challenge; plaintext is never persisted or returned. */
57
+ envelope: plugins.smartcrypto.IX25519EnvelopeV1;
58
+ }
59
+ /**
60
+ * Cluster scope is derived from the JWT. The server persists only a one-time
61
+ * challenge hash plus expiry and consumes it with generation CAS; reuse,
62
+ * expiry, mismatch, and replay are rejected. Private keys and challenge
63
+ * plaintext have no persistence DTO.
64
+ */
65
+ export interface IReq_BeginSecretRecipientEnrollment extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_BeginSecretRecipientEnrollment> {
66
+ method: 'beginSecretRecipientEnrollment';
67
+ request: {
68
+ identity: IIdentityCredential;
69
+ proposedRecipientKeyId: string;
70
+ proposedPublicKey: string;
71
+ expectedGeneration: number;
72
+ };
73
+ response: {
74
+ challenge: ISecretRecipientEnrollmentChallengeV1;
75
+ };
76
+ }
77
+ export interface IReq_CompleteSecretRecipientEnrollment extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CompleteSecretRecipientEnrollment> {
78
+ method: 'completeSecretRecipientEnrollment';
30
79
  request: {
31
80
  identity: IIdentityCredential;
32
- serviceId: string;
33
- secretRolloutId: string;
34
- secretRolloutGeneration: number;
35
- manifestId: string;
36
- manifestDigest: TSha256Digest;
81
+ enrollmentId: string;
82
+ expectedGeneration: number;
83
+ /** Canonical unpadded base64url response containing exactly 32 bytes. */
84
+ response: string;
37
85
  };
38
86
  response: {
39
- material: IResolvedSecretMaterial;
87
+ recipient: TSecretRecipientMetadata;
40
88
  };
41
89
  }
90
+ export declare const validateBeginSecretRecipientEnrollmentRequest: (requestArg: unknown) => string[];
91
+ export declare const validateSecretRecipientEnrollmentChallenge: (challengeArg: unknown) => Promise<string[]>;
92
+ export declare const validateCompleteSecretRecipientEnrollmentRequest: (requestArg: unknown) => string[];
93
+ export { validateSecretRecipientMetadata };
@@ -1,33 +1,233 @@
1
- import { validateResolvedSecretManifest, verifyResolvedSecretManifestDigest, } from './data/secret.js';
1
+ import * as plugins from './plugins.js';
2
+ import { createResolvedSecretMaterialEnvelopeContext, createSecretRecipientEnrollmentChallengeContext, validateResolvedSecretManifest, validateSecretRecipientMetadata, verifySecretEnvelopeContext, verifyResolvedSecretManifestDigest, } from './data/secret.js';
2
3
  /**
3
- * Verifies the immutable manifest and requires exactly one material value for
4
- * every pinned version. Callers separately compare the verified manifest
5
- * reference to the request and their authenticated cluster scope.
4
+ * Parses every envelope with SmartCrypto, verifies its bound context digest,
5
+ * and checks sorted exact version coverage. It never receives a private key
6
+ * and never decrypts material.
6
7
  */
7
- export const verifyResolvedSecretMaterial = async (materialArg) => {
8
+ export const verifySealedResolvedSecretMaterial = async (materialArg, expectedArg) => {
8
9
  if (!materialArg || typeof materialArg !== 'object' || Array.isArray(materialArg))
9
10
  return false;
10
11
  const material = materialArg;
11
- if (!material.manifest || !Array.isArray(material.values))
12
+ if (JSON.stringify(Object.keys(material).sort()) !== JSON.stringify([
13
+ 'entries',
14
+ 'manifest',
15
+ 'schemaVersion',
16
+ ])) {
12
17
  return false;
13
- if (material.schemaVersion !== 1)
18
+ }
19
+ if (material.schemaVersion !== 1 || !material.manifest || !Array.isArray(material.entries)) {
14
20
  return false;
15
- if (validateResolvedSecretManifest(material.manifest).length > 0)
21
+ }
22
+ if (validateResolvedSecretManifest(material.manifest).length > 0
23
+ || !await verifyResolvedSecretManifestDigest(material.manifest)) {
16
24
  return false;
17
- if (!await verifyResolvedSecretManifestDigest(material.manifest))
25
+ }
26
+ if (material.manifest.organizationId !== expectedArg.organizationId
27
+ || material.manifest.clusterId !== expectedArg.clusterId
28
+ || material.manifest.serviceId !== expectedArg.serviceId
29
+ || material.manifest.imageRolloutId !== expectedArg.imageRolloutId
30
+ || material.manifest.imageRolloutGeneration !== expectedArg.imageRolloutGeneration
31
+ || material.manifest.requestedImageDigest !== expectedArg.requestedImageDigest
32
+ || material.manifest.secretRolloutId !== expectedArg.secretRolloutId
33
+ || material.manifest.secretRolloutGeneration !== expectedArg.secretRolloutGeneration
34
+ || material.manifest.id !== expectedArg.manifestId
35
+ || material.manifest.digest !== expectedArg.manifestDigest) {
18
36
  return false;
19
- if (!material.values.every((valueArg) => (Boolean(valueArg)
20
- && typeof valueArg === 'object'
21
- && typeof valueArg.secretVersionId === 'string'
22
- && typeof valueArg.value === 'string')))
37
+ }
38
+ if (material.entries.length > 256
39
+ || material.entries.length !== material.manifest.entries.length) {
23
40
  return false;
41
+ }
24
42
  const expectedVersionIds = material.manifest.entries
25
43
  .map((entryArg) => entryArg.secretVersionId)
26
44
  .sort();
27
- const actualVersionIds = material.values
28
- .map((valueArg) => valueArg.secretVersionId)
29
- .sort();
30
- return new Set(actualVersionIds).size === actualVersionIds.length
31
- && JSON.stringify(actualVersionIds) === JSON.stringify(expectedVersionIds);
45
+ const actualVersionIds = material.entries.map((entryArg) => entryArg.secretVersionId);
46
+ if (new Set(actualVersionIds).size !== actualVersionIds.length
47
+ || JSON.stringify(actualVersionIds) !== JSON.stringify(expectedVersionIds)) {
48
+ return false;
49
+ }
50
+ const manifestEntriesByVersion = new Map(material.manifest.entries.map((entryArg) => [
51
+ entryArg.secretVersionId,
52
+ entryArg,
53
+ ]));
54
+ for (const entry of material.entries) {
55
+ if (!entry || typeof entry !== 'object' || typeof entry.secretVersionId !== 'string')
56
+ return false;
57
+ if (JSON.stringify(Object.keys(entry).sort()) !== JSON.stringify([
58
+ 'envelope',
59
+ 'secretVersionId',
60
+ ])) {
61
+ return false;
62
+ }
63
+ const manifestEntry = manifestEntriesByVersion.get(entry.secretVersionId);
64
+ if (!manifestEntry)
65
+ return false;
66
+ let envelope;
67
+ try {
68
+ envelope = plugins.smartcrypto.parseX25519Envelope(entry.envelope);
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ if (envelope.recipientKeyId !== expectedArg.expectedRecipientKeyId)
74
+ return false;
75
+ const context = createResolvedSecretMaterialEnvelopeContext({
76
+ recipientKeyId: expectedArg.expectedRecipientKeyId,
77
+ organizationId: material.manifest.organizationId,
78
+ clusterId: material.manifest.clusterId,
79
+ serviceId: material.manifest.serviceId,
80
+ imageRolloutId: material.manifest.imageRolloutId,
81
+ imageRolloutGeneration: material.manifest.imageRolloutGeneration,
82
+ requestedImageDigest: material.manifest.requestedImageDigest,
83
+ secretRolloutId: material.manifest.secretRolloutId,
84
+ secretRolloutGeneration: material.manifest.secretRolloutGeneration,
85
+ manifestId: material.manifest.id,
86
+ manifestDigest: material.manifest.digest,
87
+ secretId: manifestEntry.secretId,
88
+ secretVersionId: manifestEntry.secretVersionId,
89
+ });
90
+ if (!await verifySecretEnvelopeContext(envelope, context))
91
+ return false;
92
+ }
93
+ return true;
94
+ };
95
+ const canonicalIdentifierRegex = /^[A-Za-z0-9][A-Za-z0-9:._-]{0,199}$/;
96
+ const raw32ByteBase64UrlRegex = /^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/;
97
+ export const validateBeginSecretRecipientEnrollmentRequest = (requestArg) => {
98
+ if (!requestArg || typeof requestArg !== 'object' || Array.isArray(requestArg)) {
99
+ return ['enrollment request must be an object'];
100
+ }
101
+ const request = requestArg;
102
+ const errors = [];
103
+ if (JSON.stringify(Object.keys(request).sort()) !== JSON.stringify([
104
+ 'expectedGeneration',
105
+ 'identity',
106
+ 'proposedPublicKey',
107
+ 'proposedRecipientKeyId',
108
+ ])) {
109
+ errors.push('enrollment request must use its exact schema');
110
+ }
111
+ if (!request.identity || typeof request.identity !== 'object'
112
+ || typeof request.identity.jwt !== 'string') {
113
+ errors.push('enrollment identity must be a JWT credential');
114
+ }
115
+ if (typeof request.proposedRecipientKeyId !== 'string'
116
+ || !canonicalIdentifierRegex.test(request.proposedRecipientKeyId)) {
117
+ errors.push('proposed recipient key id must be canonical');
118
+ }
119
+ if (typeof request.proposedPublicKey !== 'string'
120
+ || !raw32ByteBase64UrlRegex.test(request.proposedPublicKey)) {
121
+ errors.push('proposed public key must be canonical base64url raw X25519 material');
122
+ }
123
+ if (!Number.isSafeInteger(request.expectedGeneration)
124
+ || request.expectedGeneration < 0) {
125
+ errors.push('expected generation must be a non-negative integer');
126
+ }
127
+ if ('clusterId' in request || 'organizationId' in request) {
128
+ errors.push('enrollment request must not select cluster or organization scope');
129
+ }
130
+ return errors;
131
+ };
132
+ export const validateSecretRecipientEnrollmentChallenge = async (challengeArg) => {
133
+ if (!challengeArg || typeof challengeArg !== 'object' || Array.isArray(challengeArg)) {
134
+ return ['enrollment challenge must be an object'];
135
+ }
136
+ const challenge = challengeArg;
137
+ const errors = [];
138
+ if (JSON.stringify(Object.keys(challenge).sort()) !== JSON.stringify([
139
+ 'clusterId',
140
+ 'enrollmentId',
141
+ 'envelope',
142
+ 'expiresAt',
143
+ 'generation',
144
+ 'publicKey',
145
+ 'recipientKeyId',
146
+ 'schemaVersion',
147
+ ])) {
148
+ errors.push('enrollment challenge must use its exact schema');
149
+ }
150
+ for (const field of ['enrollmentId', 'clusterId', 'recipientKeyId']) {
151
+ if (typeof challenge[field] !== 'string'
152
+ || !canonicalIdentifierRegex.test(challenge[field])) {
153
+ errors.push(`enrollment challenge ${field} must be canonical`);
154
+ }
155
+ }
156
+ if (challenge.schemaVersion !== 1)
157
+ errors.push('enrollment challenge schemaVersion must be 1');
158
+ if (typeof challenge.publicKey !== 'string'
159
+ || !raw32ByteBase64UrlRegex.test(challenge.publicKey)) {
160
+ errors.push('enrollment challenge public key must be canonical');
161
+ }
162
+ if (!Number.isSafeInteger(challenge.generation) || challenge.generation < 1) {
163
+ errors.push('enrollment challenge generation must be positive');
164
+ }
165
+ if (!Number.isSafeInteger(challenge.expiresAt) || challenge.expiresAt < 1) {
166
+ errors.push('enrollment challenge expiry must be positive');
167
+ }
168
+ let envelope;
169
+ try {
170
+ envelope = plugins.smartcrypto.parseX25519Envelope(challenge.envelope);
171
+ }
172
+ catch {
173
+ errors.push('enrollment challenge envelope must be strict');
174
+ }
175
+ if (envelope) {
176
+ if (envelope.recipientKeyId !== challenge.recipientKeyId) {
177
+ errors.push('enrollment challenge recipient does not match');
178
+ }
179
+ if (!raw32ByteBase64UrlRegex.test(envelope.ciphertext)) {
180
+ errors.push('enrollment challenge ciphertext must contain exactly 32 bytes');
181
+ }
182
+ if (errors.length === 0) {
183
+ const context = createSecretRecipientEnrollmentChallengeContext({
184
+ enrollmentId: challenge.enrollmentId,
185
+ clusterId: challenge.clusterId,
186
+ recipientKeyId: challenge.recipientKeyId,
187
+ publicKey: challenge.publicKey,
188
+ generation: challenge.generation,
189
+ expiresAt: challenge.expiresAt,
190
+ });
191
+ if (!await verifySecretEnvelopeContext(envelope, context)) {
192
+ errors.push('enrollment challenge context does not match');
193
+ }
194
+ }
195
+ }
196
+ return errors;
197
+ };
198
+ export const validateCompleteSecretRecipientEnrollmentRequest = (requestArg) => {
199
+ if (!requestArg || typeof requestArg !== 'object' || Array.isArray(requestArg)) {
200
+ return ['enrollment completion must be an object'];
201
+ }
202
+ const request = requestArg;
203
+ const errors = [];
204
+ if (JSON.stringify(Object.keys(request).sort()) !== JSON.stringify([
205
+ 'enrollmentId',
206
+ 'expectedGeneration',
207
+ 'identity',
208
+ 'response',
209
+ ])) {
210
+ errors.push('enrollment completion must use its exact schema');
211
+ }
212
+ if (!request.identity || typeof request.identity !== 'object'
213
+ || typeof request.identity.jwt !== 'string') {
214
+ errors.push('enrollment identity must be a JWT credential');
215
+ }
216
+ if (typeof request.enrollmentId !== 'string'
217
+ || !canonicalIdentifierRegex.test(request.enrollmentId)) {
218
+ errors.push('enrollment id must be canonical');
219
+ }
220
+ if (!Number.isSafeInteger(request.expectedGeneration)
221
+ || request.expectedGeneration < 0) {
222
+ errors.push('expected generation must be a non-negative integer');
223
+ }
224
+ if (typeof request.response !== 'string' || !raw32ByteBase64UrlRegex.test(request.response)) {
225
+ errors.push('enrollment response must be canonical base64url containing exactly 32 bytes');
226
+ }
227
+ if ('clusterId' in request || 'organizationId' in request) {
228
+ errors.push('enrollment completion must not select cluster or organization scope');
229
+ }
230
+ return errors;
32
231
  };
33
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3J1bnRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTUEsT0FBTyxFQUNMLDhCQUE4QixFQUM5QixrQ0FBa0MsR0FDbkMsTUFBTSxrQkFBa0IsQ0FBQztBQW1CMUI7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixHQUFHLEtBQUssRUFDL0MsV0FBb0IsRUFDRixFQUFFO0lBQ3BCLElBQUksQ0FBQyxXQUFXLElBQUksT0FBTyxXQUFXLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDaEcsTUFBTSxRQUFRLEdBQUcsV0FBK0MsQ0FBQztJQUNqRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hFLElBQUksUUFBUSxDQUFDLGFBQWEsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDL0MsSUFBSSw4QkFBOEIsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMvRSxJQUFJLENBQUMsTUFBTSxrQ0FBa0MsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDL0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUN2QyxPQUFPLENBQUMsUUFBUSxDQUFDO1dBQ2QsT0FBTyxRQUFRLEtBQUssUUFBUTtXQUM1QixPQUFPLFFBQVEsQ0FBQyxlQUFlLEtBQUssUUFBUTtXQUM1QyxPQUFPLFFBQVEsQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUN0QyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDakIsTUFBTSxrQkFBa0IsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU87U0FDakQsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDO1NBQzNDLElBQUksRUFBRSxDQUFDO0lBQ1YsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsTUFBTTtTQUNyQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7U0FDM0MsSUFBSSxFQUFFLENBQUM7SUFDVixPQUFPLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFDLE1BQU07V0FDNUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUMvRSxDQUFDLENBQUMifQ==
232
+ export { validateSecretRecipientMetadata };
233
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3J1bnRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFPeEMsT0FBTyxFQUNMLDJDQUEyQyxFQUMzQywrQ0FBK0MsRUFDL0MsOEJBQThCLEVBQzlCLCtCQUErQixFQUMvQiwyQkFBMkIsRUFDM0Isa0NBQWtDLEdBQ25DLE1BQU0sa0JBQWtCLENBQUM7QUFtQzFCOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxLQUFLLEVBQ3JELFdBQW9CLEVBQ3BCLFdBQXVDLEVBQ3JCLEVBQUU7SUFDcEIsSUFBSSxDQUFDLFdBQVcsSUFBSSxPQUFPLFdBQVcsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNoRyxNQUFNLFFBQVEsR0FBRyxXQUFxRCxDQUFDO0lBQ3ZFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNsRSxTQUFTO1FBQ1QsVUFBVTtRQUNWLGVBQWU7S0FDaEIsQ0FBQyxFQUFFLENBQUM7UUFDSCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxhQUFhLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDM0YsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsSUFBSSw4QkFBOEIsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUM7V0FDM0QsQ0FBQyxNQUFNLGtDQUFrQyxDQUFDLFFB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serve.zone/interfaces",
3
- "version": "22.0.0",
3
+ "version": "23.0.0",
4
4
  "private": false,
5
5
  "description": "Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.",
6
6
  "exports": {
@@ -18,6 +18,7 @@
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
20
  "@api.global/typedrequest-interfaces": "^4.0.0",
21
+ "@push.rocks/smartcrypto": "^2.2.0",
21
22
  "@push.rocks/smartlog-interfaces": "^3.0.2",
22
23
  "@tsclass/tsclass": "^9.5.1"
23
24
  },
package/readme.md CHANGED
@@ -30,6 +30,43 @@ import { appstore, data, platform, platformservice, requests } from '@serve.zone
30
30
 
31
31
  This package intentionally has no service implementation logic. It is a stable vocabulary for services that need to agree on payload shape, method names, and response types.
32
32
 
33
+ ## Secrets v23 Pre-Cutover Contract
34
+
35
+ Version 23 removes the old grouped/bundled secret DTOs and plaintext runtime
36
+ material API. Secret values enter Cloudly only as strict SmartCrypto X25519
37
+ envelopes or an explicit bounded server-generation request. Coreflow receives a
38
+ full digest-verified schema-v2 manifest plus one sealed envelope per pinned
39
+ SecretVersion through the Node-only runtime export.
40
+
41
+ This is a contract release before consumer cutover. It does **not** claim that
42
+ clean-v2 migration, backup verification, historical secret erasure, or storage
43
+ cleanup has completed. Those operations remain separately gated and must be
44
+ proven by their owning services before destructive cleanup.
45
+
46
+ Breaking removals include:
47
+
48
+ - The SecretGroup and SecretBundle data/request modules and request namespaces.
49
+ - `getServiceSecretBundlesAsFlatObject` and every service/preflight field tied
50
+ to bundled flattening or aggregate runtime files.
51
+ - Plaintext resolved runtime values, generic platform config/credential maps,
52
+ credential-bearing Cloudly settings, and serialized object-storage
53
+ credential references.
54
+ - Hosted-app control-token identities and credential-bearing bootstrap actions.
55
+
56
+ Primary v23 additions include:
57
+
58
+ - `TSecretValueInput`, `TSecretIngressRecipient`, the
59
+ `requests.secret.IReq_GetSecretIngressRecipient` contract with method
60
+ `getSecretIngressRecipient`, and fixed-order create/rotate/App Store context
61
+ builders.
62
+ - Schema-v2 `IResolvedSecretManifest` contracts, stable Docker resource naming,
63
+ WorkloadInit map/wrapper helpers, and `ISealedResolvedSecretMaterial` under
64
+ `@serve.zone/interfaces/runtime`.
65
+ - Two-step Coreflow X25519 recipient enrollment and exact recipient lifecycle
66
+ validators.
67
+ - Mandatory `IImmutableContainerInvocationV1` evidence on immutable image
68
+ deployment plans.
69
+
33
70
  ## Portable Storage Contracts
34
71
 
35
72
  App Store templates can declare logical, template-local `storageClasses` and
@@ -82,18 +119,21 @@ const storageConfig: appstore.IAppStoreVersionConfig = {
82
119
  capacity: { request: '100GiB', limit: '1TiB' },
83
120
  reclaimPolicy: 'retain',
84
121
  delivery: {
85
- type: 'secretFile',
122
+ type: 'file',
86
123
  targetPath: '/run/secrets/backup-archive.json',
87
124
  format: 'servezone-object-storage-v1',
125
+ uid: 1000,
126
+ gid: 1000,
127
+ mode: 0o400,
88
128
  },
89
129
  protection: { versioning: 'required', retentionDays: 30 },
90
130
  },
91
131
  ],
92
132
  requiresFeatures: [
93
- appstore.appStoreStorageFeatureIds.bindingsV1,
133
+ appstore.appStoreStorageFeatureIds.bindingsV2,
94
134
  appstore.appStoreStorageFeatureIds.filesystemV1,
95
- appstore.appStoreStorageFeatureIds.objectStorageV1,
96
- appstore.appStoreStorageFeatureIds.objectStorageSecretFileV1,
135
+ appstore.appStoreStorageFeatureIds.objectStorageV2,
136
+ appstore.appStoreStorageFeatureIds.objectStorageFileV2,
97
137
  ],
98
138
  };
99
139
  ```
@@ -104,13 +144,15 @@ express requirements and preferences only; Onebox and Cloudly map them to
104
144
  operator policy independently.
105
145
 
106
146
  An app may declare multiple `objectStorage` requests. Each request resolves to
107
- its own endpoint, bucket, and credential reference. Environment delivery uses
108
- an explicit key map and secret-file delivery uses a unique target path, so two
147
+ its own endpoint, bucket, and value-free credential management scope. Launcher
148
+ environment delivery uses an explicit key map and file delivery uses one
149
+ managed JSON Secret at a unique target path, so two
109
150
  bindings cannot share credential destinations accidentally.
110
151
 
111
152
  `platform.storage` contains separate capability advertisements and resolved
112
153
  binding/status contracts. Resolved object-storage bindings expose connection
113
- metadata plus credential references, never credential values. Filesystem
154
+ metadata plus a service-owned credential management scope and delivery policy,
155
+ never credential references or values. Filesystem
114
156
  bindings expose the container mount and access mode, never a host path.
115
157
 
116
158
  Portable manifests and resolved bindings intentionally have no fields for
@@ -310,14 +352,15 @@ Common data contracts include:
310
352
  - `IDomain`, `IDnsEntry`, and traffic contracts for routing and DNS management.
311
353
  - Traffic and gateway route contracts including `ICoretrafficPortRouteConfig`, routing `portRoutes`, and `IGatewayClientRoute` client-owned route views. Gateway route intent supports optional match `domains`, `transport`, and `remoteIngress`, plus explicit route `priority` and `managedRouteKind`. Ownership can combine `hostname` with `routeRef` so a normal route and a path-specific managed route for the same hostname reconcile independently.
312
354
  - Value-free `ISecretMetadata`, `ISecretVersionMetadata`, and `ISecretSetMetadata`
313
- contracts for operator views, plus exact-version `IResolvedSecretManifest`
314
- contracts for cluster delivery. Manifest helpers enforce canonical shared
315
- digests, globally unique environment/file delivery targets, and per-cluster
316
- desired/applied/previous-accepted rollout state. `ISecretBundle` and
317
- `ISecretGroup` remain legacy compatibility contracts during the versioned
318
- migration.
355
+ contracts for operator views, plus schema-v2 exact-version
356
+ `IResolvedSecretManifest` contracts for cluster delivery. Manifest helpers
357
+ bind immutable image rollout and invocation evidence, enforce canonical
358
+ digests and globally unique launcher/file targets, and track per-cluster
359
+ desired/applied/previous-accepted rollout state. Platform-provider and system
360
+ owners are valid metadata owners but are rejected from workload manifests.
319
361
  `listSecrets` exposes the dedicated `targetSecretsRevision` CAS fence;
320
- `createSecret` consumes and returns that fence, while
362
+ every create, rotate, and lifecycle mutation consumes and returns that
363
+ aggregate owner fence, while
321
364
  `setServiceSecretSetAttachments` returns the independent
322
365
  `secretConfigurationRevision`. Generic service writes own neither revision.
323
366
  - Mail gateway contracts for domain authorities, address bindings, WorkApp bindings, managed SMTP/API credentials, spool items, delivery journals, and inbound/outbound message payloads.
@@ -368,7 +411,7 @@ const config: appstore.IAppStoreVersionConfig = {
368
411
  };
369
412
  ```
370
413
 
371
- `redirectPath` is a canonical callback path on the app's HTTPS origin. Registration validation also requires that canonical app origin explicitly and rejects cross-origin, normalized, query-bearing, fragment-bearing, or duplicate callback URLs. The five environment values are environment-key names, not credentials embedded in the manifest. A host injects the generated client secret through its secret environment path and injects the other registration values only while OIDC is enabled.
414
+ `redirectPath` is a canonical callback path on the app's HTTPS origin. Registration validation also requires that canonical app origin explicitly and rejects cross-origin, normalized, query-bearing, fragment-bearing, or duplicate callback URLs. The five environment values are environment-key names, not credentials embedded in the manifest. A host injects the generated client secret through launcher environment delivery and injects the other registration values only while OIDC is enabled.
372
415
 
373
416
  `data.IHostedAppRoleAssignment` binds a stable user subject to an immutable `appInstanceId`. That same app instance is the OIDC `client_id`, the ID-token `aud`, and the `servezone_app_instance_id` claim. Tokens include only the assigned roles for that audience; `preferred_username` is display metadata and must not be treated as identity authority.
374
417
 
@@ -380,6 +423,16 @@ Validate untrusted manifests, registrations, and claims with:
380
423
  - `appstore.validateAppStorePlatformOidcCapability`
381
424
  - `appstore.validateAppStoreVersionPlatformOidc`
382
425
 
426
+ Hosted lifecycle RPCs accept only `IIdentityCredential`. After JWT
427
+ verification, handlers validate `IHostedAppMachineClaims` and derive the exact
428
+ app instance and service from `servezone_app_instance_id` and
429
+ `servezone_service_id`; callers cannot submit those selectors. Bootstrap
430
+ actions are either a canonical same-origin `setupRoute` path or a nonsecret
431
+ `message`. Control tokens, usernames, passwords, and token URLs are not part of
432
+ the lifecycle contract. Each server action carries a CAS revision; completion
433
+ requires its exact ID, current revision, and `ready` status so a delayed request
434
+ cannot complete a replacement action.
435
+
383
436
  ## TypedRequest Contracts
384
437
 
385
438
  Use `requests` when registering handlers with `@api.global/typedrequest` or when creating typed requests through a TypedSocket client.
@@ -619,8 +672,6 @@ Request groups are exported by product area:
619
672
  - `requests.platform`
620
673
  - `requests.routing`
621
674
  - `requests.secret`
622
- - `requests.secretbundle`
623
- - `requests.secretgroup`
624
675
  - `requests.server`
625
676
  - `requests.service`
626
677
  - `requests.settings`
@@ -630,28 +681,53 @@ Request groups are exported by product area:
630
681
  - `requests.webpush`
631
682
 
632
683
  Secret material response contracts are not exported from the universal
633
- browser-facing entrypoint. Node runtimes import the isolated subpath:
684
+ browser-facing entrypoint.
685
+
686
+ The root entrypoint does use `@push.rocks/smartcrypto` to parse and validate
687
+ strict ingress envelopes. Browser consumers that import the root contract can
688
+ therefore include SmartCrypto and its browser-compatible crypto dependencies in
689
+ their bundle. This package never opens private keys; sealed runtime material
690
+ contracts remain isolated to the Node-only `/runtime` subpath.
691
+
692
+ Node runtimes import the isolated subpath:
634
693
 
635
694
  ```typescript
636
695
  import {
637
- verifyResolvedSecretMaterial,
696
+ verifySealedResolvedSecretMaterial,
638
697
  } from '@serve.zone/interfaces/runtime';
639
698
  import type {
640
699
  IReq_GetResolvedSecretMaterial,
641
- IResolvedSecretMaterial,
700
+ ISecretMaterialExpectation,
701
+ ISealedResolvedSecretMaterial,
642
702
  } from '@serve.zone/interfaces/runtime';
643
703
 
644
- async function acceptMaterial(material: IResolvedSecretMaterial) {
645
- if (!await verifyResolvedSecretMaterial(material)) {
704
+ async function acceptMaterial(
705
+ material: ISealedResolvedSecretMaterial,
706
+ expectation: ISecretMaterialExpectation,
707
+ ) {
708
+ if (!await verifySealedResolvedSecretMaterial(material, expectation)) {
646
709
  throw new Error('secret material does not match its immutable manifest');
647
710
  }
648
711
  }
649
712
  ```
650
713
 
651
- Runtime material is shaped as `{ manifest, values }`. The helper verifies the
652
- canonical manifest digest and exact one-to-one version-ID coverage before
653
- plaintext use. The runtime must separately compare the verified manifest
654
- reference and cluster to its request and authenticated deployment scope.
714
+ Runtime material is shaped as `{ schemaVersion: 1, manifest, entries }`, where
715
+ each entry contains only `secretVersionId` and a strict X25519 envelope. The
716
+ helper verifies the canonical schema-v2 manifest digest, envelope context
717
+ digests, active recipient key, sorted exact one-to-one version coverage, every
718
+ request fence, and the trusted local organization/cluster expectation. It never
719
+ decrypts. Organization and cluster are derived from the verified cluster JWT
720
+ and cannot be selected by request fields.
721
+
722
+ Launcher environment delivery uses stable `szsv-<base32-sha256>` Docker
723
+ resource names and `/run/serve.zone/secrets/<resource>` source paths. The
724
+ nonsecret map is written to `/run/serve.zone/workloadinit-map-v1.json` with mode
725
+ 0444. Runtime assets under `/opt/serve.zone/runtime-assets` are read-only, and
726
+ the wrapper executes
727
+ `workloadinit run --map /run/serve.zone/workloadinit-map-v1.json -- <argv...>`
728
+ without a shell, symlink, or aggregate value file. Resources and maps remain
729
+ retained while any desired, applied, or previous-accepted manifest references
730
+ them and are deleted only after Docker confirms rollout or service removal.
655
731
 
656
732
  ## Platform Contracts
657
733
 
@@ -675,7 +751,9 @@ Available platform modules:
675
751
  - `platform.ai`, `platform.database`, `platform.objectstorage`, `platform.logging`, `platform.backup`, and `platform.sip` for infrastructure and application capabilities.
676
752
  - `platform.storage` for provider-neutral storage classes, requests, capabilities, and resolved bindings.
677
753
  - `platform.storagemigration` for fenced object-storage migration intent, status, consumer acknowledgements, canonical digests, and strict normalizers.
678
- - `platform.types` plus root re-exports for shared capability, provider, binding, credential, and endpoint metadata.
754
+ - `platform.types` provider and binding metadata is value-free. Provider-specific
755
+ operational config stays adapter-internal, while public DTOs expose typed
756
+ endpoints and optional credential management scopes only.
679
757
 
680
758
  ## Legacy Platformservice Contracts
681
759
 
@@ -714,7 +792,7 @@ pnpm test
714
792
  pnpm run buildDocs
715
793
  ```
716
794
 
717
- The package is authored as ESM TypeScript and built with `tsbuild tsfolders --allowimplicitany`.
795
+ The package is authored as ESM TypeScript and built with `tsbuild tsfolders`.
718
796
 
719
797
  ## License and Legal Information
720
798
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/interfaces',
6
- version: '22.0.0',
6
+ version: '23.0.0',
7
7
  description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
8
8
  }