@uns-kit/core 3.0.26 → 3.0.28
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/MIGRATIONS.md +57 -0
- package/dist/runtime/compatibility/energenti-authorization-v1.d.ts +95 -0
- package/dist/runtime/compatibility/energenti-authorization-v1.d.ts.map +1 -0
- package/dist/runtime/compatibility/energenti-authorization-v1.js +315 -0
- package/dist/runtime/compatibility/energenti-authorization-v1.js.map +1 -0
- package/dist/runtime/compatibility/energenti-descriptor-v1.d.ts +10 -0
- package/dist/runtime/compatibility/energenti-descriptor-v1.d.ts.map +1 -0
- package/dist/runtime/compatibility/energenti-descriptor-v1.js +18 -0
- package/dist/runtime/compatibility/energenti-descriptor-v1.js.map +1 -0
- package/dist/runtime/process-group-authorization.d.ts +111 -0
- package/dist/runtime/process-group-authorization.d.ts.map +1 -0
- package/dist/runtime/process-group-authorization.js +370 -0
- package/dist/runtime/process-group-authorization.js.map +1 -0
- package/dist/runtime/process-group-contract.d.ts +65 -0
- package/dist/runtime/process-group-contract.d.ts.map +1 -0
- package/dist/runtime/process-group-contract.js +171 -0
- package/dist/runtime/process-group-contract.js.map +1 -0
- package/dist/runtime/process-group-control-contract.d.ts +56 -0
- package/dist/runtime/process-group-control-contract.d.ts.map +1 -0
- package/dist/runtime/process-group-control-contract.js +37 -0
- package/dist/runtime/process-group-control-contract.js.map +1 -0
- package/dist/runtime/process-group-inspection.d.ts +22 -0
- package/dist/runtime/process-group-inspection.d.ts.map +1 -0
- package/dist/runtime/process-group-inspection.js +185 -0
- package/dist/runtime/process-group-inspection.js.map +1 -0
- package/dist/runtime/process-group-launch-environment.d.ts +3 -0
- package/dist/runtime/process-group-launch-environment.d.ts.map +1 -0
- package/dist/runtime/process-group-launch-environment.js +12 -0
- package/dist/runtime/process-group-launch-environment.js.map +1 -0
- package/dist/runtime/process-group-legacy-start.d.ts +2 -0
- package/dist/runtime/process-group-legacy-start.d.ts.map +1 -0
- package/dist/runtime/process-group-legacy-start.js +16 -0
- package/dist/runtime/process-group-legacy-start.js.map +1 -0
- package/dist/runtime/process-group-resources.d.ts +8 -0
- package/dist/runtime/process-group-resources.d.ts.map +1 -0
- package/dist/runtime/process-group-resources.js +96 -0
- package/dist/runtime/process-group-resources.js.map +1 -0
- package/dist/runtime/process-group-snapshot.mjs +199 -0
- package/dist/runtime/process-group-staging.d.ts +5 -0
- package/dist/runtime/process-group-staging.d.ts.map +1 -0
- package/dist/runtime/process-group-staging.js +63 -0
- package/dist/runtime/process-group-staging.js.map +1 -0
- package/dist/runtime/process-group-supervision.d.ts +13 -0
- package/dist/runtime/process-group-supervision.d.ts.map +1 -0
- package/dist/runtime/process-group-supervision.js +35 -0
- package/dist/runtime/process-group-supervision.js.map +1 -0
- package/dist/runtime/process-group-upgrade.d.ts +125 -0
- package/dist/runtime/process-group-upgrade.d.ts.map +1 -0
- package/dist/runtime/process-group-upgrade.js +256 -0
- package/dist/runtime/process-group-upgrade.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import * as legacy from "./compatibility/energenti-authorization-v1.js";
|
|
3
|
+
export { configurationAuthorizationHash, groupArtifactHash, groupChannelsHash } from "./process-group-resources.js";
|
|
4
|
+
export declare const hasProcessGroupAuthorization: typeof legacy.hasProcessGroupAuthorization;
|
|
5
|
+
export declare const processGroupAuthorizationSchema: z.ZodObject<{
|
|
6
|
+
schemaVersion: z.ZodLiteral<3>;
|
|
7
|
+
kind: z.ZodLiteral<"uns-process-group-runtime-authorization">;
|
|
8
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
9
|
+
packageName: z.ZodString;
|
|
10
|
+
namespace: z.ZodString;
|
|
11
|
+
groupId: z.ZodString;
|
|
12
|
+
descriptorSha256: z.ZodString;
|
|
13
|
+
controllerName: z.ZodString;
|
|
14
|
+
packageRoot: z.ZodString;
|
|
15
|
+
artifactSha256: z.ZodString;
|
|
16
|
+
groupManifestSha256: z.ZodString;
|
|
17
|
+
channelsSha256: z.ZodString;
|
|
18
|
+
stateRoot: z.ZodString;
|
|
19
|
+
directory: z.ZodString;
|
|
20
|
+
journalId: z.ZodNullable<z.ZodString>;
|
|
21
|
+
placements: z.ZodArray<z.ZodObject<{
|
|
22
|
+
instanceId: z.ZodString;
|
|
23
|
+
processName: z.ZodString;
|
|
24
|
+
role: z.ZodEnum<{
|
|
25
|
+
source: "source";
|
|
26
|
+
target: "target";
|
|
27
|
+
receiver: "receiver";
|
|
28
|
+
}>;
|
|
29
|
+
configurationSha256: z.ZodString;
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
export type ProcessGroupAuthorizationPolicy = z.infer<typeof processGroupAuthorizationSchema>;
|
|
33
|
+
export declare const processGroupManifestSchema: z.ZodObject<{
|
|
34
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
35
|
+
id: z.ZodString;
|
|
36
|
+
inputTopic: z.ZodString;
|
|
37
|
+
processName: z.ZodString;
|
|
38
|
+
profiles: z.ZodArray<z.ZodObject<{
|
|
39
|
+
id: z.ZodString;
|
|
40
|
+
processName: z.ZodString;
|
|
41
|
+
mappingFile: z.ZodString;
|
|
42
|
+
mappingSha256: z.ZodString;
|
|
43
|
+
dataGroup: z.ZodString;
|
|
44
|
+
}, z.core.$strict>>;
|
|
45
|
+
}, z.core.$strict>;
|
|
46
|
+
interface GenericAuthorization {
|
|
47
|
+
readonly sha256: string;
|
|
48
|
+
readonly file: string;
|
|
49
|
+
readonly directory: string;
|
|
50
|
+
readonly journalId: string | null;
|
|
51
|
+
readonly role: "source" | "target" | "receiver";
|
|
52
|
+
readonly groupId: string;
|
|
53
|
+
readonly groupProcessName: string;
|
|
54
|
+
readonly namespace: string;
|
|
55
|
+
}
|
|
56
|
+
export type ProcessGroupAuthorization = legacy.HvAuthorization | GenericAuthorization;
|
|
57
|
+
export type HvAuthorization = ProcessGroupAuthorization;
|
|
58
|
+
export type HvAuthorizationPolicy = legacy.HvAuthorizationPolicy;
|
|
59
|
+
export declare const hvAuthorizationSchema: z.ZodObject<{
|
|
60
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
61
|
+
kind: z.ZodLiteral<"energenti-hv-runtime-authorization">;
|
|
62
|
+
controllerName: z.ZodString;
|
|
63
|
+
packageRoot: z.ZodString;
|
|
64
|
+
artifactSha256: z.ZodString;
|
|
65
|
+
groupManifestSha256: z.ZodString;
|
|
66
|
+
channelsSha256: z.ZodString;
|
|
67
|
+
stateRoot: z.ZodString;
|
|
68
|
+
directory: z.ZodString;
|
|
69
|
+
journalId: z.ZodNullable<z.ZodString>;
|
|
70
|
+
placements: z.ZodArray<z.ZodObject<{
|
|
71
|
+
instanceId: z.ZodString;
|
|
72
|
+
processName: z.ZodEnum<{
|
|
73
|
+
[x: string]: string;
|
|
74
|
+
}>;
|
|
75
|
+
role: z.ZodEnum<{
|
|
76
|
+
source: "source";
|
|
77
|
+
target: "target";
|
|
78
|
+
receiver: "receiver";
|
|
79
|
+
}>;
|
|
80
|
+
configurationSha256: z.ZodString;
|
|
81
|
+
}, z.core.$strict>>;
|
|
82
|
+
}, z.core.$strict>;
|
|
83
|
+
export declare const productionGroupIds: readonly ["hv", "vv", "jek"];
|
|
84
|
+
/** Bounded private registry enumeration; retained state without its policy fails closed.
|
|
85
|
+
* New groups are operator-owned data and never a release-time enum in the Controller.
|
|
86
|
+
*/
|
|
87
|
+
export declare function configuredGroupProcessNames(): Set<string>;
|
|
88
|
+
export interface ProcessGroupAuthorizationContext {
|
|
89
|
+
packageRoot: string;
|
|
90
|
+
instanceDirectory: string;
|
|
91
|
+
rawConfiguration: Record<string, unknown>;
|
|
92
|
+
channels: unknown[];
|
|
93
|
+
controllerName: string;
|
|
94
|
+
file?: string;
|
|
95
|
+
stateRoot?: string;
|
|
96
|
+
initialize?: boolean;
|
|
97
|
+
}
|
|
98
|
+
/** Live authority always comes from the current canonical private policy. */
|
|
99
|
+
export declare function authorizeProcessGroupRuntime(context: ProcessGroupAuthorizationContext): ProcessGroupAuthorization;
|
|
100
|
+
/** Review only: never issues an authorization accepted by runtime/launch checks. */
|
|
101
|
+
export declare function validateProcessGroupPolicyCandidate(context: ProcessGroupAuthorizationContext, bytes: Buffer): void;
|
|
102
|
+
export declare function processGroupAuthorizationFile(context: ProcessGroupAuthorizationContext): string;
|
|
103
|
+
export declare const authorizeHvRuntime: typeof authorizeProcessGroupRuntime;
|
|
104
|
+
export declare function authorizeConfiguredProcessGroupRuntime(pkg: string, dir: string, raw: Record<string, unknown>, controllerName: string, initialize?: boolean): ProcessGroupAuthorization;
|
|
105
|
+
export declare function assertProcessGroupJournalAuthorization(value: ProcessGroupAuthorization | undefined, directory: string, journalId: string | undefined): void;
|
|
106
|
+
export declare const assertHvJournalAuthorization: typeof assertProcessGroupJournalAuthorization;
|
|
107
|
+
export declare function assertProcessGroupStateMount(value: ProcessGroupAuthorization, root: string): void;
|
|
108
|
+
export declare const assertHvStateMount: typeof assertProcessGroupStateMount;
|
|
109
|
+
export declare function assertProcessGroupTargetLaunch(value: ProcessGroupAuthorization, dir: string, operationId: string | undefined, launchId: string | undefined): void;
|
|
110
|
+
export declare const assertHvTargetLaunch: typeof assertProcessGroupTargetLaunch;
|
|
111
|
+
//# sourceMappingURL=process-group-authorization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-group-authorization.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-authorization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import * as legacy from "./compatibility/energenti-authorization-v1.js";
|
|
5
|
+
import { normalizeProcessGroupConfiguration, processGroupDescriptor, resolvedProcessGroupChannels, } from "./process-group-contract.js";
|
|
6
|
+
import { configurationAuthorizationHash, groupArtifactHash, groupChannelsHash, readProcessGroupResource as read, sha256 as sha, } from "./process-group-resources.js";
|
|
7
|
+
export { configurationAuthorizationHash, groupArtifactHash, groupChannelsHash } from "./process-group-resources.js";
|
|
8
|
+
export const hasProcessGroupAuthorization = legacy.hasProcessGroupAuthorization;
|
|
9
|
+
const digest = z.string().regex(/^[a-f0-9]{64}$/), id = z.string().regex(/^[a-z][a-z0-9-]{0,99}$/);
|
|
10
|
+
const absolute = z
|
|
11
|
+
.string()
|
|
12
|
+
.max(512)
|
|
13
|
+
.refine((v) => path.isAbsolute(v) && path.resolve(v) === v);
|
|
14
|
+
const placement = z.strictObject({
|
|
15
|
+
instanceId: z.string().regex(/^[a-zA-Z0-9-]{1,100}$/),
|
|
16
|
+
processName: id,
|
|
17
|
+
role: z.enum(["source", "target", "receiver"]),
|
|
18
|
+
configurationSha256: digest,
|
|
19
|
+
});
|
|
20
|
+
export const processGroupAuthorizationSchema = z.strictObject({
|
|
21
|
+
schemaVersion: z.literal(3),
|
|
22
|
+
kind: z.literal("uns-process-group-runtime-authorization"),
|
|
23
|
+
protocolVersion: z.literal(1),
|
|
24
|
+
packageName: z.string().min(1).max(214),
|
|
25
|
+
namespace: id,
|
|
26
|
+
groupId: id,
|
|
27
|
+
descriptorSha256: digest,
|
|
28
|
+
controllerName: z.string().min(1).max(100),
|
|
29
|
+
packageRoot: absolute,
|
|
30
|
+
artifactSha256: digest,
|
|
31
|
+
groupManifestSha256: digest,
|
|
32
|
+
channelsSha256: digest,
|
|
33
|
+
stateRoot: absolute,
|
|
34
|
+
directory: absolute,
|
|
35
|
+
journalId: z.string().uuid().nullable(),
|
|
36
|
+
placements: z.array(placement).min(4).max(18),
|
|
37
|
+
});
|
|
38
|
+
export const processGroupManifestSchema = z.strictObject({
|
|
39
|
+
schemaVersion: z.literal(1),
|
|
40
|
+
id,
|
|
41
|
+
inputTopic: z
|
|
42
|
+
.string()
|
|
43
|
+
.min(1)
|
|
44
|
+
.max(512)
|
|
45
|
+
.regex(/^[^#+\0]+$/),
|
|
46
|
+
processName: id,
|
|
47
|
+
profiles: z
|
|
48
|
+
.array(z.strictObject({ id, processName: id, mappingFile: z.string().min(1).max(512), mappingSha256: digest, dataGroup: id }))
|
|
49
|
+
.min(2)
|
|
50
|
+
.max(16),
|
|
51
|
+
});
|
|
52
|
+
export const hvAuthorizationSchema = legacy.hvAuthorizationSchema;
|
|
53
|
+
export const productionGroupIds = legacy.productionGroupIds;
|
|
54
|
+
const issued = new WeakSet();
|
|
55
|
+
function privateDirectory(dir) {
|
|
56
|
+
for (let p = dir; p !== path.dirname(p); p = path.dirname(p))
|
|
57
|
+
if (fs.lstatSync(p).isSymbolicLink())
|
|
58
|
+
throw Error("Linked policy directory");
|
|
59
|
+
const s = fs.lstatSync(dir);
|
|
60
|
+
if (!s.isDirectory() || s.uid !== process.getuid?.() || (s.mode & 0o077) !== 0)
|
|
61
|
+
throw Error("Insecure policy directory");
|
|
62
|
+
}
|
|
63
|
+
function registryRoot(root, dir) {
|
|
64
|
+
if (!path.isAbsolute(root) || path.resolve(root) !== root || path.resolve(dir) !== dir)
|
|
65
|
+
throw Error("Invalid policy registry");
|
|
66
|
+
privateDirectory(root);
|
|
67
|
+
if (dir === root)
|
|
68
|
+
return "*"; // Explicit collection of independently owned namespaces.
|
|
69
|
+
const relative = path.relative(root, dir);
|
|
70
|
+
if (!path.isAbsolute(root) || path.resolve(root) !== root || !/^([a-z][a-z0-9-]{0,99})\/authorizations$/.test(relative))
|
|
71
|
+
throw Error("Invalid policy registry");
|
|
72
|
+
privateDirectory(root);
|
|
73
|
+
privateDirectory(dir);
|
|
74
|
+
return relative.split("/")[0];
|
|
75
|
+
}
|
|
76
|
+
function selectedFile(pkg, raw, root, explicit) {
|
|
77
|
+
const descriptor = processGroupDescriptor(pkg);
|
|
78
|
+
if (!descriptor)
|
|
79
|
+
throw Error("Missing runtime contract");
|
|
80
|
+
const c = normalizeProcessGroupConfiguration(raw, descriptor), journal = c.journal;
|
|
81
|
+
const manifest = descriptor.manifests.find((m) => m.file === journal?.["groupManifest"]);
|
|
82
|
+
if (!manifest)
|
|
83
|
+
throw Error("Unregistered group manifest");
|
|
84
|
+
const dir = process.env["UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY"];
|
|
85
|
+
if (explicit)
|
|
86
|
+
return explicit;
|
|
87
|
+
if (dir) {
|
|
88
|
+
const selected = registryRoot(root, dir);
|
|
89
|
+
if (selected !== "*" && selected !== descriptor.namespace)
|
|
90
|
+
throw Error("Foreign runtime registry");
|
|
91
|
+
const registry = selected === "*" ? path.join(root, descriptor.namespace, "authorizations") : dir;
|
|
92
|
+
privateDirectory(registry);
|
|
93
|
+
return path.join(registry, manifest.id + ".json");
|
|
94
|
+
}
|
|
95
|
+
const single = process.env["UNS_PROCESS_GROUP_AUTHORIZATION_FILE"];
|
|
96
|
+
if (!single)
|
|
97
|
+
throw Error("No selected policy");
|
|
98
|
+
return single;
|
|
99
|
+
}
|
|
100
|
+
/** Bounded private registry enumeration; retained state without its policy fails closed.
|
|
101
|
+
* New groups are operator-owned data and never a release-time enum in the Controller.
|
|
102
|
+
*/
|
|
103
|
+
export function configuredGroupProcessNames() {
|
|
104
|
+
if (!hasProcessGroupAuthorization())
|
|
105
|
+
return new Set();
|
|
106
|
+
try {
|
|
107
|
+
const root = process.env["UNS_PROCESS_GROUP_STATE_ROOT"];
|
|
108
|
+
if (!root)
|
|
109
|
+
throw Error();
|
|
110
|
+
const files = new Set();
|
|
111
|
+
const single = process.env["UNS_PROCESS_GROUP_AUTHORIZATION_FILE"];
|
|
112
|
+
if (single)
|
|
113
|
+
files.add(single);
|
|
114
|
+
const dir = process.env["UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY"];
|
|
115
|
+
if (dir) {
|
|
116
|
+
const selected = registryRoot(root, dir);
|
|
117
|
+
let registries;
|
|
118
|
+
if (selected === "*") {
|
|
119
|
+
const namespaces = fs.readdirSync(root, { withFileTypes: true });
|
|
120
|
+
if (namespaces.length > 64 || namespaces.some((e) => e.isSymbolicLink()))
|
|
121
|
+
throw Error("Registry namespace budget or link violation");
|
|
122
|
+
registries = namespaces
|
|
123
|
+
.filter((e) => e.isDirectory())
|
|
124
|
+
.map((e) => {
|
|
125
|
+
if (!id.safeParse(e.name).success)
|
|
126
|
+
throw Error("Invalid registry namespace");
|
|
127
|
+
privateDirectory(path.join(root, e.name));
|
|
128
|
+
return { namespace: e.name, directory: path.join(root, e.name, "authorizations") };
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else
|
|
132
|
+
registries = [{ namespace: selected, directory: dir }];
|
|
133
|
+
for (const registry of registries) {
|
|
134
|
+
let entries = [];
|
|
135
|
+
try {
|
|
136
|
+
privateDirectory(registry.directory);
|
|
137
|
+
entries = fs.readdirSync(registry.directory, { withFileTypes: true });
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
if (e.code !== "ENOENT")
|
|
141
|
+
throw e;
|
|
142
|
+
}
|
|
143
|
+
if (entries.length > 64)
|
|
144
|
+
throw Error("Policy registry budget exceeded");
|
|
145
|
+
for (const entry of entries)
|
|
146
|
+
if (entry.name.endsWith(".json")) {
|
|
147
|
+
if (!/^[a-z][a-z0-9-]{0,99}\.json$/.test(entry.name))
|
|
148
|
+
throw Error("Invalid registry entry");
|
|
149
|
+
files.add(path.join(registry.directory, entry.name));
|
|
150
|
+
if (files.size > 64)
|
|
151
|
+
throw Error("Total policy registry budget exceeded");
|
|
152
|
+
}
|
|
153
|
+
const journals = path.join(root, registry.namespace, "admission");
|
|
154
|
+
try {
|
|
155
|
+
// Root/registry permissions already protect visibility; retain old parent modes.
|
|
156
|
+
for (let parent = journals; parent !== path.dirname(parent); parent = path.dirname(parent))
|
|
157
|
+
if (fs.lstatSync(parent).isSymbolicLink())
|
|
158
|
+
throw Error("Linked journal registry");
|
|
159
|
+
const retained = fs.readdirSync(journals, { withFileTypes: true });
|
|
160
|
+
if (retained.length > 64)
|
|
161
|
+
throw Error("Retained journal budget exceeded");
|
|
162
|
+
for (const entry of retained)
|
|
163
|
+
if (!id.safeParse(entry.name).success ||
|
|
164
|
+
entry.isSymbolicLink() ||
|
|
165
|
+
!entry.isDirectory() ||
|
|
166
|
+
!files.has(path.join(registry.directory, entry.name + ".json")))
|
|
167
|
+
throw Error("Retained journal has no reviewed policy");
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
if (e.code !== "ENOENT")
|
|
171
|
+
throw e;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const result = new Set();
|
|
176
|
+
for (const file of files) {
|
|
177
|
+
const raw = JSON.parse(read(file, true).toString());
|
|
178
|
+
const p = raw.schemaVersion === 3
|
|
179
|
+
? processGroupAuthorizationSchema.parse(raw)
|
|
180
|
+
: z.union([legacy.hvAuthorizationSchema, legacy.processGroupAuthorizationSchema]).parse(raw);
|
|
181
|
+
const { namespace, group } = p.schemaVersion === 3 ? { namespace: p.namespace, group: p.groupId } : legacy.legacyPolicyIdentity(p);
|
|
182
|
+
if (p.stateRoot !== root ||
|
|
183
|
+
file !== path.join(root, namespace, "authorizations", group + ".json") ||
|
|
184
|
+
p.directory !== path.join(root, namespace, "admission", group))
|
|
185
|
+
throw Error();
|
|
186
|
+
privateDirectory(root);
|
|
187
|
+
privateDirectory(path.dirname(file));
|
|
188
|
+
for (const role of p.placements)
|
|
189
|
+
result.add(role.processName);
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
throw Error("Process-group authorization registry is missing, changed or insecure; review required");
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function verifyRuntimePolicy(context, candidate) {
|
|
198
|
+
try {
|
|
199
|
+
const root = context.stateRoot ?? process.env["UNS_PROCESS_GROUP_STATE_ROOT"];
|
|
200
|
+
if (!root || !context.controllerName)
|
|
201
|
+
throw Error();
|
|
202
|
+
const file = selectedFile(context.packageRoot, context.rawConfiguration, root, context.file), bytes = candidate ?? read(file, true), unparsed = JSON.parse(bytes.toString());
|
|
203
|
+
if (unparsed.schemaVersion !== 3) {
|
|
204
|
+
if (candidate)
|
|
205
|
+
throw Error("Only generic policies can be staged");
|
|
206
|
+
return legacy.authorizeHvRuntime({ ...context, file, stateRoot: root });
|
|
207
|
+
}
|
|
208
|
+
const p = processGroupAuthorizationSchema.parse(unparsed), d = processGroupDescriptor(context.packageRoot);
|
|
209
|
+
if (!d || d.legacy)
|
|
210
|
+
throw Error("Generic runtime descriptor required");
|
|
211
|
+
const pkg = JSON.parse(read(path.join(context.packageRoot, "package.json")).toString());
|
|
212
|
+
const manifest = d.manifests.find((m) => m.id === p.groupId);
|
|
213
|
+
if (!manifest ||
|
|
214
|
+
p.packageName !== pkg.name ||
|
|
215
|
+
p.namespace !== d.namespace ||
|
|
216
|
+
p.descriptorSha256 !== configurationAuthorizationHash(pkg.unsDatahub.processGroupRuntime) ||
|
|
217
|
+
p.packageRoot !== context.packageRoot ||
|
|
218
|
+
p.controllerName !== context.controllerName ||
|
|
219
|
+
p.stateRoot !== root ||
|
|
220
|
+
file !== path.join(root, d.namespace, "authorizations", p.groupId + ".json") ||
|
|
221
|
+
p.directory !== path.join(root, d.namespace, "admission", p.groupId))
|
|
222
|
+
throw Error();
|
|
223
|
+
privateDirectory(root);
|
|
224
|
+
privateDirectory(path.dirname(file));
|
|
225
|
+
if (groupArtifactHash(context.packageRoot) !== p.artifactSha256 || groupChannelsHash(context.channels) !== p.channelsSha256)
|
|
226
|
+
throw Error();
|
|
227
|
+
const manifestBytes = read(path.join(context.packageRoot, manifest.file));
|
|
228
|
+
if (sha(manifestBytes) !== p.groupManifestSha256)
|
|
229
|
+
throw Error();
|
|
230
|
+
const m = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));
|
|
231
|
+
if (m.id !== p.groupId)
|
|
232
|
+
throw Error();
|
|
233
|
+
const receiver = m.processName + "-admission";
|
|
234
|
+
if (new Set(m.profiles.map((x) => x.id)).size !== m.profiles.length ||
|
|
235
|
+
new Set(m.profiles.map((x) => x.processName)).size !== m.profiles.length ||
|
|
236
|
+
m.profiles.some((x) => x.processName === m.processName || x.processName === receiver))
|
|
237
|
+
throw Error();
|
|
238
|
+
for (const member of m.profiles) {
|
|
239
|
+
const f = path.resolve(context.packageRoot, path.dirname(manifest.file), member.mappingFile);
|
|
240
|
+
if (!f.startsWith(context.packageRoot + path.sep) || sha(read(f)) !== member.mappingSha256)
|
|
241
|
+
throw Error();
|
|
242
|
+
}
|
|
243
|
+
const expected = new Map([
|
|
244
|
+
...m.profiles.map((x) => [x.processName, "source"]),
|
|
245
|
+
[m.processName, "target"],
|
|
246
|
+
[receiver, "receiver"],
|
|
247
|
+
]);
|
|
248
|
+
if (p.placements.length !== expected.size ||
|
|
249
|
+
new Set(p.placements.map((x) => x.instanceId)).size !== expected.size ||
|
|
250
|
+
new Set(p.placements.map((x) => x.processName)).size !== expected.size ||
|
|
251
|
+
p.placements.some((x) => expected.get(x.processName) !== x.role))
|
|
252
|
+
throw Error();
|
|
253
|
+
const entry = p.placements.find((x) => context.instanceDirectory === path.join(context.packageRoot, "instances", x.instanceId));
|
|
254
|
+
const c = normalizeProcessGroupConfiguration(context.rawConfiguration, d), j = c.journal, k = c.publisher;
|
|
255
|
+
if (!entry ||
|
|
256
|
+
!c.matches ||
|
|
257
|
+
entry.processName !== c.uns?.["processName"] ||
|
|
258
|
+
entry.configurationSha256 !== configurationAuthorizationHash(context.rawConfiguration) ||
|
|
259
|
+
!j ||
|
|
260
|
+
j["directory"] !== p.directory ||
|
|
261
|
+
(j["journalId"] ?? null) !== p.journalId ||
|
|
262
|
+
j["groupManifest"] !== manifest.file)
|
|
263
|
+
throw Error();
|
|
264
|
+
if (context.initialize ? p.journalId !== null || entry.role !== "receiver" : p.journalId === null)
|
|
265
|
+
throw Error();
|
|
266
|
+
if (entry.role === "receiver" ? c.runtimeRole !== "admission" : c.runtimeRole !== undefined && c.runtimeRole !== "publisher")
|
|
267
|
+
throw Error();
|
|
268
|
+
const member = m.profiles.find((x) => x.processName === entry.processName), mapping = path.resolve(context.packageRoot, String(k["mappingFile"]));
|
|
269
|
+
if (entry.role !== "source"
|
|
270
|
+
? k["groupManifest"] !== manifest.file
|
|
271
|
+
: k["groupManifest"] !== undefined ||
|
|
272
|
+
k["dataGroup"] !== member?.dataGroup ||
|
|
273
|
+
!mapping.startsWith(context.packageRoot + path.sep) ||
|
|
274
|
+
sha(read(mapping)) !== member?.mappingSha256)
|
|
275
|
+
throw Error();
|
|
276
|
+
const result = Object.freeze({
|
|
277
|
+
sha256: sha(bytes),
|
|
278
|
+
file,
|
|
279
|
+
directory: p.directory,
|
|
280
|
+
journalId: p.journalId,
|
|
281
|
+
role: entry.role,
|
|
282
|
+
groupId: p.groupId,
|
|
283
|
+
groupProcessName: m.processName,
|
|
284
|
+
namespace: d.namespace,
|
|
285
|
+
});
|
|
286
|
+
if (!candidate)
|
|
287
|
+
issued.add(result);
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
throw Error("Process-group runtime authorization is missing, changed or does not match this installed placement; review required");
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/** Live authority always comes from the current canonical private policy. */
|
|
295
|
+
export function authorizeProcessGroupRuntime(context) {
|
|
296
|
+
return verifyRuntimePolicy(context);
|
|
297
|
+
}
|
|
298
|
+
/** Review only: never issues an authorization accepted by runtime/launch checks. */
|
|
299
|
+
export function validateProcessGroupPolicyCandidate(context, bytes) {
|
|
300
|
+
verifyRuntimePolicy(context, bytes);
|
|
301
|
+
}
|
|
302
|
+
export function processGroupAuthorizationFile(context) {
|
|
303
|
+
const root = context.stateRoot ?? process.env["UNS_PROCESS_GROUP_STATE_ROOT"];
|
|
304
|
+
if (!root)
|
|
305
|
+
throw Error("Missing process-group state root");
|
|
306
|
+
return selectedFile(context.packageRoot, context.rawConfiguration, root, context.file);
|
|
307
|
+
}
|
|
308
|
+
export const authorizeHvRuntime = authorizeProcessGroupRuntime;
|
|
309
|
+
export function authorizeConfiguredProcessGroupRuntime(pkg, dir, raw, controllerName, initialize = false) {
|
|
310
|
+
return authorizeProcessGroupRuntime({
|
|
311
|
+
packageRoot: pkg,
|
|
312
|
+
instanceDirectory: dir,
|
|
313
|
+
rawConfiguration: raw,
|
|
314
|
+
channels: resolvedProcessGroupChannels(raw),
|
|
315
|
+
controllerName,
|
|
316
|
+
initialize,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
export function assertProcessGroupJournalAuthorization(value, directory, journalId) {
|
|
320
|
+
if (value && issued.has(value)) {
|
|
321
|
+
if (value.directory !== directory || value.journalId !== (journalId ?? null) || sha(read(value.file, true)) !== value.sha256)
|
|
322
|
+
throw Error("Exact reviewed process-group authorization required");
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
legacy.assertHvJournalAuthorization(value, directory, journalId);
|
|
326
|
+
}
|
|
327
|
+
export const assertHvJournalAuthorization = assertProcessGroupJournalAuthorization;
|
|
328
|
+
export function assertProcessGroupStateMount(value, root) {
|
|
329
|
+
if (!issued.has(value)) {
|
|
330
|
+
legacy.assertHvStateMount(value, root);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);
|
|
334
|
+
if (process.platform !== "linux" || !("namespace" in value) || value.directory !== path.join(root, value.namespace, "admission", value.groupId))
|
|
335
|
+
throw Error("Process group requires its reviewed Linux state mount");
|
|
336
|
+
const mount = fs
|
|
337
|
+
.readFileSync("/proc/self/mountinfo", "utf8")
|
|
338
|
+
.split("\n")
|
|
339
|
+
.map((l) => l.split(" "))
|
|
340
|
+
.filter((f) => f[4] === root)
|
|
341
|
+
.at(-1);
|
|
342
|
+
if (!mount || !mount[5]?.split(",").includes("rw") || !["xfs", "ext4", "btrfs", "zfs"].includes(mount[mount.indexOf("-") + 1] ?? ""))
|
|
343
|
+
throw Error("Process-group state root must be an explicit writable local Linux filesystem mount");
|
|
344
|
+
}
|
|
345
|
+
export const assertHvStateMount = assertProcessGroupStateMount;
|
|
346
|
+
export function assertProcessGroupTargetLaunch(value, dir, operationId, launchId) {
|
|
347
|
+
if (!issued.has(value)) {
|
|
348
|
+
legacy.assertHvTargetLaunch(value, dir, operationId, launchId);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (value.role !== "target")
|
|
352
|
+
return;
|
|
353
|
+
try {
|
|
354
|
+
assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);
|
|
355
|
+
const r = JSON.parse(read(path.join(dir, "process-group-reservation.json"), true).toString());
|
|
356
|
+
if (!z.string().uuid().safeParse(operationId).success ||
|
|
357
|
+
!z.string().uuid().safeParse(launchId).success ||
|
|
358
|
+
r.operationId !== operationId ||
|
|
359
|
+
r.role !== "target" ||
|
|
360
|
+
r.lastLaunch?.launchId !== launchId ||
|
|
361
|
+
!z.string().uuid().safeParse(r.lastLaunch?.requestId).success ||
|
|
362
|
+
!digest.safeParse(r.configurationChecksum).success)
|
|
363
|
+
throw Error();
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
throw Error("Target requires its exact reviewed group reservation and launch identity");
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
export const assertHvTargetLaunch = assertProcessGroupTargetLaunch;
|
|
370
|
+
//# sourceMappingURL=process-group-authorization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-group-authorization.js","sourceRoot":"","sources":["../../src/runtime/process-group-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport * as legacy from \"./compatibility/energenti-authorization-v1.js\";\nimport {\n type ProcessGroupRuntimeDescriptor,\n normalizeProcessGroupConfiguration,\n processGroupDescriptor,\n resolvedProcessGroupChannels,\n} from \"./process-group-contract.js\";\nimport {\n configurationAuthorizationHash,\n groupArtifactHash,\n groupChannelsHash,\n readProcessGroupResource as read,\n sha256 as sha,\n} from \"./process-group-resources.js\";\n\nexport { configurationAuthorizationHash, groupArtifactHash, groupChannelsHash } from \"./process-group-resources.js\";\n\nexport const hasProcessGroupAuthorization = legacy.hasProcessGroupAuthorization;\nconst digest = z.string().regex(/^[a-f0-9]{64}$/),\n id = z.string().regex(/^[a-z][a-z0-9-]{0,99}$/);\nconst absolute = z\n .string()\n .max(512)\n .refine((v) => path.isAbsolute(v) && path.resolve(v) === v);\nconst placement = z.strictObject({\n instanceId: z.string().regex(/^[a-zA-Z0-9-]{1,100}$/),\n processName: id,\n role: z.enum([\"source\", \"target\", \"receiver\"]),\n configurationSha256: digest,\n});\nexport const processGroupAuthorizationSchema = z.strictObject({\n schemaVersion: z.literal(3),\n kind: z.literal(\"uns-process-group-runtime-authorization\"),\n protocolVersion: z.literal(1),\n packageName: z.string().min(1).max(214),\n namespace: id,\n groupId: id,\n descriptorSha256: digest,\n controllerName: z.string().min(1).max(100),\n packageRoot: absolute,\n artifactSha256: digest,\n groupManifestSha256: digest,\n channelsSha256: digest,\n stateRoot: absolute,\n directory: absolute,\n journalId: z.string().uuid().nullable(),\n placements: z.array(placement).min(4).max(18),\n});\nexport type ProcessGroupAuthorizationPolicy = z.infer<typeof processGroupAuthorizationSchema>;\nexport const processGroupManifestSchema = z.strictObject({\n schemaVersion: z.literal(1),\n id,\n inputTopic: z\n .string()\n .min(1)\n .max(512)\n .regex(/^[^#+\\0]+$/),\n processName: id,\n profiles: z\n .array(z.strictObject({ id, processName: id, mappingFile: z.string().min(1).max(512), mappingSha256: digest, dataGroup: id }))\n .min(2)\n .max(16),\n});\ninterface GenericAuthorization {\n readonly sha256: string;\n readonly file: string;\n readonly directory: string;\n readonly journalId: string | null;\n readonly role: \"source\" | \"target\" | \"receiver\";\n readonly groupId: string;\n readonly groupProcessName: string;\n readonly namespace: string;\n}\nexport type ProcessGroupAuthorization = legacy.HvAuthorization | GenericAuthorization;\nexport type HvAuthorization = ProcessGroupAuthorization;\nexport type HvAuthorizationPolicy = legacy.HvAuthorizationPolicy;\nexport const hvAuthorizationSchema = legacy.hvAuthorizationSchema;\nexport const productionGroupIds = legacy.productionGroupIds;\nconst issued = new WeakSet<object>();\nfunction privateDirectory(dir: string): void {\n for (let p = dir; p !== path.dirname(p); p = path.dirname(p)) if (fs.lstatSync(p).isSymbolicLink()) throw Error(\"Linked policy directory\");\n const s = fs.lstatSync(dir);\n if (!s.isDirectory() || s.uid !== process.getuid?.() || (s.mode & 0o077) !== 0) throw Error(\"Insecure policy directory\");\n}\nfunction registryRoot(root: string, dir: string): string {\n if (!path.isAbsolute(root) || path.resolve(root) !== root || path.resolve(dir) !== dir) throw Error(\"Invalid policy registry\");\n privateDirectory(root);\n if (dir === root) return \"*\"; // Explicit collection of independently owned namespaces.\n const relative = path.relative(root, dir);\n if (!path.isAbsolute(root) || path.resolve(root) !== root || !/^([a-z][a-z0-9-]{0,99})\\/authorizations$/.test(relative))\n throw Error(\"Invalid policy registry\");\n privateDirectory(root);\n privateDirectory(dir);\n return relative.split(\"/\")[0]!;\n}\nfunction selectedFile(pkg: string, raw: Record<string, unknown>, root: string, explicit?: string): string {\n const descriptor = processGroupDescriptor(pkg);\n if (!descriptor) throw Error(\"Missing runtime contract\");\n const c = normalizeProcessGroupConfiguration(raw, descriptor),\n journal = c.journal as Record<string, unknown> | undefined;\n const manifest = descriptor.manifests.find((m) => m.file === journal?.[\"groupManifest\"]);\n if (!manifest) throw Error(\"Unregistered group manifest\");\n const dir = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY\"];\n if (explicit) return explicit;\n if (dir) {\n const selected = registryRoot(root, dir);\n if (selected !== \"*\" && selected !== descriptor.namespace) throw Error(\"Foreign runtime registry\");\n const registry = selected === \"*\" ? path.join(root, descriptor.namespace, \"authorizations\") : dir;\n privateDirectory(registry);\n return path.join(registry, manifest.id + \".json\");\n }\n const single = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_FILE\"];\n if (!single) throw Error(\"No selected policy\");\n return single;\n}\n/** Bounded private registry enumeration; retained state without its policy fails closed.\n * New groups are operator-owned data and never a release-time enum in the Controller.\n */\nexport function configuredGroupProcessNames(): Set<string> {\n if (!hasProcessGroupAuthorization()) return new Set();\n try {\n const root = process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root) throw Error();\n const files = new Set<string>();\n const single = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_FILE\"];\n if (single) files.add(single);\n const dir = process.env[\"UNS_PROCESS_GROUP_AUTHORIZATION_DIRECTORY\"];\n if (dir) {\n const selected = registryRoot(root, dir);\n let registries: { namespace: string; directory: string }[];\n if (selected === \"*\") {\n const namespaces = fs.readdirSync(root, { withFileTypes: true });\n if (namespaces.length > 64 || namespaces.some((e) => e.isSymbolicLink())) throw Error(\"Registry namespace budget or link violation\");\n registries = namespaces\n .filter((e) => e.isDirectory())\n .map((e) => {\n if (!id.safeParse(e.name).success) throw Error(\"Invalid registry namespace\");\n privateDirectory(path.join(root, e.name));\n return { namespace: e.name, directory: path.join(root, e.name, \"authorizations\") };\n });\n } else registries = [{ namespace: selected, directory: dir }];\n for (const registry of registries) {\n let entries: fs.Dirent[] = [];\n try {\n privateDirectory(registry.directory);\n entries = fs.readdirSync(registry.directory, { withFileTypes: true });\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n }\n if (entries.length > 64) throw Error(\"Policy registry budget exceeded\");\n for (const entry of entries)\n if (entry.name.endsWith(\".json\")) {\n if (!/^[a-z][a-z0-9-]{0,99}\\.json$/.test(entry.name)) throw Error(\"Invalid registry entry\");\n files.add(path.join(registry.directory, entry.name));\n if (files.size > 64) throw Error(\"Total policy registry budget exceeded\");\n }\n const journals = path.join(root, registry.namespace, \"admission\");\n try {\n // Root/registry permissions already protect visibility; retain old parent modes.\n for (let parent = journals; parent !== path.dirname(parent); parent = path.dirname(parent))\n if (fs.lstatSync(parent).isSymbolicLink()) throw Error(\"Linked journal registry\");\n const retained = fs.readdirSync(journals, { withFileTypes: true });\n if (retained.length > 64) throw Error(\"Retained journal budget exceeded\");\n for (const entry of retained)\n if (\n !id.safeParse(entry.name).success ||\n entry.isSymbolicLink() ||\n !entry.isDirectory() ||\n !files.has(path.join(registry.directory, entry.name + \".json\"))\n )\n throw Error(\"Retained journal has no reviewed policy\");\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n }\n }\n }\n const result = new Set<string>();\n for (const file of files) {\n const raw = JSON.parse(read(file, true).toString());\n const p =\n raw.schemaVersion === 3\n ? processGroupAuthorizationSchema.parse(raw)\n : z.union([legacy.hvAuthorizationSchema, legacy.processGroupAuthorizationSchema]).parse(raw);\n const { namespace, group } = p.schemaVersion === 3 ? { namespace: p.namespace, group: p.groupId } : legacy.legacyPolicyIdentity(p);\n if (\n p.stateRoot !== root ||\n file !== path.join(root, namespace, \"authorizations\", group + \".json\") ||\n p.directory !== path.join(root, namespace, \"admission\", group)\n )\n throw Error();\n privateDirectory(root);\n privateDirectory(path.dirname(file));\n for (const role of p.placements) result.add(role.processName);\n }\n return result;\n } catch {\n throw Error(\"Process-group authorization registry is missing, changed or insecure; review required\");\n }\n}\nexport interface ProcessGroupAuthorizationContext {\n packageRoot: string;\n instanceDirectory: string;\n rawConfiguration: Record<string, unknown>;\n channels: unknown[];\n controllerName: string;\n file?: string;\n stateRoot?: string;\n initialize?: boolean;\n}\nfunction verifyRuntimePolicy(context: ProcessGroupAuthorizationContext, candidate?: Buffer): ProcessGroupAuthorization {\n try {\n const root = context.stateRoot ?? process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root || !context.controllerName) throw Error();\n const file = selectedFile(context.packageRoot, context.rawConfiguration, root, context.file),\n bytes = candidate ?? read(file, true),\n unparsed = JSON.parse(bytes.toString());\n if (unparsed.schemaVersion !== 3) {\n if (candidate) throw Error(\"Only generic policies can be staged\");\n return legacy.authorizeHvRuntime({ ...context, file, stateRoot: root });\n }\n const p = processGroupAuthorizationSchema.parse(unparsed),\n d = processGroupDescriptor(context.packageRoot);\n if (!d || d.legacy) throw Error(\"Generic runtime descriptor required\");\n const pkg = JSON.parse(read(path.join(context.packageRoot, \"package.json\")).toString());\n const manifest = d.manifests.find((m) => m.id === p.groupId);\n if (\n !manifest ||\n p.packageName !== pkg.name ||\n p.namespace !== d.namespace ||\n p.descriptorSha256 !== configurationAuthorizationHash(pkg.unsDatahub.processGroupRuntime) ||\n p.packageRoot !== context.packageRoot ||\n p.controllerName !== context.controllerName ||\n p.stateRoot !== root ||\n file !== path.join(root, d.namespace, \"authorizations\", p.groupId + \".json\") ||\n p.directory !== path.join(root, d.namespace, \"admission\", p.groupId)\n )\n throw Error();\n privateDirectory(root);\n privateDirectory(path.dirname(file));\n if (groupArtifactHash(context.packageRoot) !== p.artifactSha256 || groupChannelsHash(context.channels) !== p.channelsSha256) throw Error();\n const manifestBytes = read(path.join(context.packageRoot, manifest.file));\n if (sha(manifestBytes) !== p.groupManifestSha256) throw Error();\n const m = processGroupManifestSchema.parse(JSON.parse(manifestBytes.toString()));\n if (m.id !== p.groupId) throw Error();\n const receiver = m.processName + \"-admission\";\n if (\n new Set(m.profiles.map((x) => x.id)).size !== m.profiles.length ||\n new Set(m.profiles.map((x) => x.processName)).size !== m.profiles.length ||\n m.profiles.some((x) => x.processName === m.processName || x.processName === receiver)\n )\n throw Error();\n for (const member of m.profiles) {\n const f = path.resolve(context.packageRoot, path.dirname(manifest.file), member.mappingFile);\n if (!f.startsWith(context.packageRoot + path.sep) || sha(read(f)) !== member.mappingSha256) throw Error();\n }\n const expected = new Map([\n ...m.profiles.map((x) => [x.processName, \"source\"] as const),\n [m.processName, \"target\"] as const,\n [receiver, \"receiver\"] as const,\n ]);\n if (\n p.placements.length !== expected.size ||\n new Set(p.placements.map((x) => x.instanceId)).size !== expected.size ||\n new Set(p.placements.map((x) => x.processName)).size !== expected.size ||\n p.placements.some((x) => expected.get(x.processName) !== x.role)\n )\n throw Error();\n const entry = p.placements.find((x) => context.instanceDirectory === path.join(context.packageRoot, \"instances\", x.instanceId));\n const c = normalizeProcessGroupConfiguration(context.rawConfiguration, d),\n j = c.journal as Record<string, unknown> | undefined,\n k = c.publisher;\n if (\n !entry ||\n !c.matches ||\n entry.processName !== c.uns?.[\"processName\"] ||\n entry.configurationSha256 !== configurationAuthorizationHash(context.rawConfiguration) ||\n !j ||\n j[\"directory\"] !== p.directory ||\n (j[\"journalId\"] ?? null) !== p.journalId ||\n j[\"groupManifest\"] !== manifest.file\n )\n throw Error();\n if (context.initialize ? p.journalId !== null || entry.role !== \"receiver\" : p.journalId === null) throw Error();\n if (entry.role === \"receiver\" ? c.runtimeRole !== \"admission\" : c.runtimeRole !== undefined && c.runtimeRole !== \"publisher\") throw Error();\n const member = m.profiles.find((x) => x.processName === entry.processName),\n mapping = path.resolve(context.packageRoot, String(k[\"mappingFile\"]));\n if (\n entry.role !== \"source\"\n ? k[\"groupManifest\"] !== manifest.file\n : k[\"groupManifest\"] !== undefined ||\n k[\"dataGroup\"] !== member?.dataGroup ||\n !mapping.startsWith(context.packageRoot + path.sep) ||\n sha(read(mapping)) !== member?.mappingSha256\n )\n throw Error();\n const result = Object.freeze({\n sha256: sha(bytes),\n file,\n directory: p.directory,\n journalId: p.journalId,\n role: entry.role,\n groupId: p.groupId,\n groupProcessName: m.processName,\n namespace: d.namespace,\n });\n if (!candidate) issued.add(result);\n return result;\n } catch {\n throw Error(\"Process-group runtime authorization is missing, changed or does not match this installed placement; review required\");\n }\n}\n/** Live authority always comes from the current canonical private policy. */\nexport function authorizeProcessGroupRuntime(context: ProcessGroupAuthorizationContext): ProcessGroupAuthorization {\n return verifyRuntimePolicy(context);\n}\n/** Review only: never issues an authorization accepted by runtime/launch checks. */\nexport function validateProcessGroupPolicyCandidate(context: ProcessGroupAuthorizationContext, bytes: Buffer): void {\n verifyRuntimePolicy(context, bytes);\n}\nexport function processGroupAuthorizationFile(context: ProcessGroupAuthorizationContext): string {\n const root = context.stateRoot ?? process.env[\"UNS_PROCESS_GROUP_STATE_ROOT\"];\n if (!root) throw Error(\"Missing process-group state root\");\n return selectedFile(context.packageRoot, context.rawConfiguration, root, context.file);\n}\nexport const authorizeHvRuntime = authorizeProcessGroupRuntime;\nexport function authorizeConfiguredProcessGroupRuntime(\n pkg: string,\n dir: string,\n raw: Record<string, unknown>,\n controllerName: string,\n initialize = false,\n) {\n return authorizeProcessGroupRuntime({\n packageRoot: pkg,\n instanceDirectory: dir,\n rawConfiguration: raw,\n channels: resolvedProcessGroupChannels(raw),\n controllerName,\n initialize,\n });\n}\nexport function assertProcessGroupJournalAuthorization(\n value: ProcessGroupAuthorization | undefined,\n directory: string,\n journalId: string | undefined,\n): void {\n if (value && issued.has(value)) {\n if (value.directory !== directory || value.journalId !== (journalId ?? null) || sha(read(value.file, true)) !== value.sha256)\n throw Error(\"Exact reviewed process-group authorization required\");\n return;\n }\n legacy.assertHvJournalAuthorization(value as legacy.HvAuthorization | undefined, directory, journalId);\n}\nexport const assertHvJournalAuthorization = assertProcessGroupJournalAuthorization;\nexport function assertProcessGroupStateMount(value: ProcessGroupAuthorization, root: string): void {\n if (!issued.has(value)) {\n legacy.assertHvStateMount(value as legacy.HvAuthorization, root);\n return;\n }\n assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);\n if (process.platform !== \"linux\" || !(\"namespace\" in value) || value.directory !== path.join(root, value.namespace, \"admission\", value.groupId))\n throw Error(\"Process group requires its reviewed Linux state mount\");\n const mount = fs\n .readFileSync(\"/proc/self/mountinfo\", \"utf8\")\n .split(\"\\n\")\n .map((l) => l.split(\" \"))\n .filter((f) => f[4] === root)\n .at(-1);\n if (!mount || !mount[5]?.split(\",\").includes(\"rw\") || ![\"xfs\", \"ext4\", \"btrfs\", \"zfs\"].includes(mount[mount.indexOf(\"-\") + 1] ?? \"\"))\n throw Error(\"Process-group state root must be an explicit writable local Linux filesystem mount\");\n}\nexport const assertHvStateMount = assertProcessGroupStateMount;\nexport function assertProcessGroupTargetLaunch(\n value: ProcessGroupAuthorization,\n dir: string,\n operationId: string | undefined,\n launchId: string | undefined,\n): void {\n if (!issued.has(value)) {\n legacy.assertHvTargetLaunch(value as legacy.HvAuthorization, dir, operationId, launchId);\n return;\n }\n if (value.role !== \"target\") return;\n try {\n assertProcessGroupJournalAuthorization(value, value.directory, value.journalId ?? undefined);\n const r = JSON.parse(read(path.join(dir, \"process-group-reservation.json\"), true).toString());\n if (\n !z.string().uuid().safeParse(operationId).success ||\n !z.string().uuid().safeParse(launchId).success ||\n r.operationId !== operationId ||\n r.role !== \"target\" ||\n r.lastLaunch?.launchId !== launchId ||\n !z.string().uuid().safeParse(r.lastLaunch?.requestId).success ||\n !digest.safeParse(r.configurationChecksum).success\n )\n throw Error();\n } catch {\n throw Error(\"Target requires its exact reviewed group reservation and launch identity\");\n }\n}\nexport const assertHvTargetLaunch = assertProcessGroupTargetLaunch;\n"]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export { legacyDescriptorForPackage, legacyEnergentiDescriptor } from "./compatibility/energenti-descriptor-v1.js";
|
|
3
|
+
export declare const processGroupProtocolVersion: 1;
|
|
4
|
+
export declare const processGroupRuntimeDescriptorSchema: z.ZodObject<{
|
|
5
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
6
|
+
namespace: z.ZodString;
|
|
7
|
+
publisherPath: z.ZodArray<z.ZodString>;
|
|
8
|
+
journalPath: z.ZodArray<z.ZodString>;
|
|
9
|
+
runtimeRolePath: z.ZodArray<z.ZodString>;
|
|
10
|
+
receiverRole: z.ZodString;
|
|
11
|
+
defaultDataGroup: z.ZodOptional<z.ZodString>;
|
|
12
|
+
match: z.ZodOptional<z.ZodObject<{
|
|
13
|
+
path: z.ZodArray<z.ZodString>;
|
|
14
|
+
value: z.ZodString;
|
|
15
|
+
}, z.core.$strict>>;
|
|
16
|
+
manifests: z.ZodArray<z.ZodObject<{
|
|
17
|
+
id: z.ZodString;
|
|
18
|
+
file: z.ZodString;
|
|
19
|
+
}, z.core.$strict>>;
|
|
20
|
+
}, z.core.$strict>;
|
|
21
|
+
export type ProcessGroupRuntimeDescriptor = z.infer<typeof processGroupRuntimeDescriptorSchema> & {
|
|
22
|
+
legacy?: true;
|
|
23
|
+
};
|
|
24
|
+
export declare function readConfigurationSelector(raw: unknown, keys: readonly string[]): unknown;
|
|
25
|
+
/** Strictly bounded package metadata, no executable application adapter in the Controller. */
|
|
26
|
+
export declare function processGroupDescriptor(packageRoot: string): ProcessGroupRuntimeDescriptor | undefined;
|
|
27
|
+
export declare function normalizeProcessGroupConfiguration(raw: Record<string, unknown>, d: ProcessGroupRuntimeDescriptor): {
|
|
28
|
+
uns: Record<string, unknown>;
|
|
29
|
+
publisher: Record<string, unknown>;
|
|
30
|
+
journal: unknown;
|
|
31
|
+
runtimeRole: unknown;
|
|
32
|
+
matches: boolean;
|
|
33
|
+
};
|
|
34
|
+
export declare function projectProcessGroupConfiguration(raw: Record<string, unknown>, d: ProcessGroupRuntimeDescriptor, uns: Record<string, unknown>, authorizationSha256?: string): Record<string, unknown>;
|
|
35
|
+
export declare function resolvedProcessGroupChannels(raw: Record<string, unknown>, _d?: ProcessGroupRuntimeDescriptor): import("../uns-config/mqtt-channel.js").ResolvedMqttChannel[];
|
|
36
|
+
export declare function isLocalPilotPath(value: string, platform?: NodeJS.Platform): boolean;
|
|
37
|
+
export declare function isProcessGroupJournalPath(root: string, directory: string, namespace: string): boolean;
|
|
38
|
+
export declare const processGroupJournalSchema: z.ZodObject<{
|
|
39
|
+
directory: z.ZodString;
|
|
40
|
+
journalId: z.ZodOptional<z.ZodString>;
|
|
41
|
+
minFreeBytes: z.ZodDefault<z.ZodNumber>;
|
|
42
|
+
groupManifest: z.ZodString;
|
|
43
|
+
maxRecords: z.ZodDefault<z.ZodNumber>;
|
|
44
|
+
maxBytes: z.ZodDefault<z.ZodNumber>;
|
|
45
|
+
}, z.core.$strict>;
|
|
46
|
+
export type ProcessGroupJournalConfiguration = z.infer<typeof processGroupJournalSchema>;
|
|
47
|
+
export interface ProcessGroupJournalProfile {
|
|
48
|
+
processName: string;
|
|
49
|
+
mappingSha256: string;
|
|
50
|
+
dataGroup: string;
|
|
51
|
+
}
|
|
52
|
+
export interface ProcessGroupJournalTask {
|
|
53
|
+
profile: string;
|
|
54
|
+
payload: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function resolvedProcessGroupInputChannel(raw: Record<string, unknown>): import("../uns-config/mqtt-channel.js").ResolvedMqttChannel;
|
|
57
|
+
export declare function processGroupSourceIdentity(input: {
|
|
58
|
+
host: string;
|
|
59
|
+
port?: number | undefined;
|
|
60
|
+
protocol?: string | undefined;
|
|
61
|
+
hosts?: string[] | undefined;
|
|
62
|
+
servers?: unknown[] | undefined;
|
|
63
|
+
}): string;
|
|
64
|
+
export declare function processGroupJournalContract(sourceIdentity: string, config: Pick<ProcessGroupJournalConfiguration, "maxRecords" | "maxBytes">, profiles: ProcessGroupJournalProfile[]): string;
|
|
65
|
+
//# sourceMappingURL=process-group-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-group-contract.d.ts","sourceRoot":"","sources":["../../src/runtime/process-group-contract.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,OAAO,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AAEnH,eAAO,MAAM,2BAA2B,EAAG,CAAU,CAAC;AAgBtD,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;kBAqB5C,CAAC;AACL,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AACpH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAOxF;AACD,8FAA8F;AAC9F,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,6BAA6B,GAAG,SAAS,CAyBrG;AACD,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,6BAA6B;SAK1F,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;EAM7C;AACD,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,CAAC,EAAE,6BAA6B,EAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,mBAAmB,CAAC,EAAE,MAAM,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYzB;AACD,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,6BAA6B,iEAO5G;AACD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,kBAAmB,GAAG,OAAO,CAEpF;AACD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAMrG;AACD,eAAO,MAAM,yBAAyB;;;;;;;kBAiBpC,CAAC;AACH,MAAM,MAAM,gCAAgC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AACzF,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,gCAAgC,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,+DAE5E;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;CACjC,GAAG,MAAM,CAUT;AACD,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,IAAI,CAAC,gCAAgC,EAAE,YAAY,GAAG,UAAU,CAAC,EACzE,QAAQ,EAAE,0BAA0B,EAAE,GACrC,MAAM,CAUR"}
|