@uns-kit/core 3.0.45 → 3.0.47
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 +31 -0
- package/dist/runtime/catalog-publication-client.d.ts +21 -0
- package/dist/runtime/catalog-publication-client.d.ts.map +1 -0
- package/dist/runtime/catalog-publication-client.js +92 -0
- package/dist/runtime/catalog-publication-client.js.map +1 -0
- package/dist/runtime/catalog-publication.d.ts +97 -0
- package/dist/runtime/catalog-publication.d.ts.map +1 -0
- package/dist/runtime/catalog-publication.js +185 -0
- package/dist/runtime/catalog-publication.js.map +1 -0
- package/dist/runtime/retained-store-copy.d.mts +3 -0
- package/dist/runtime/retained-store-copy.mjs +133 -0
- package/dist/runtime/retained-store-guide.md +44 -2
- package/dist/runtime/retained-store-job.d.mts +1 -0
- package/dist/runtime/retained-store-job.mjs +28 -0
- package/dist/runtime/retained-store-storage.d.mts +7 -0
- package/dist/runtime/retained-store-storage.mjs +66 -21
- package/dist/runtime/retained-store.d.ts +12 -3
- package/dist/runtime/retained-store.d.ts.map +1 -1
- package/dist/runtime/retained-store.js +74 -19
- package/dist/runtime/retained-store.js.map +1 -1
- package/dist/runtime/service-access-guide.md +130 -0
- package/dist/runtime/service-access.d.ts +23 -0
- package/dist/runtime/service-access.d.ts.map +1 -0
- package/dist/runtime/service-access.js +62 -0
- package/dist/runtime/service-access.js.map +1 -0
- package/dist/runtime/service-access.test.d.ts +2 -0
- package/dist/runtime/service-access.test.d.ts.map +1 -0
- package/dist/runtime/service-access.test.js +57 -0
- package/dist/runtime/service-access.test.js.map +1 -0
- package/package.json +14 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retained-store.js","sourceRoot":"","sources":["../../src/runtime/retained-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport { available, maintenanceLease, runtimeLease } from \"./retained-store-storage.mjs\";\n\nconst segment = z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/);\nconst relative = z\n .string()\n .min(1)\n .max(256)\n .refine((value) => !path.isAbsolute(value) && !value.includes(\"\\\\\") && value.split(\"/\").every((p) => /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(p)));\nexport const RETAINED_STORE_MANIFEST = \"retained-store.manifest.json\";\nexport const RETAINED_STORE_BINDING = \"retained-store-binding.json\";\nexport const RETAINED_STORE_GUARD = \"retained-store-guard.json\";\nexport const retainedStoreManifestSchema = z\n .object({\n protocol: z.literal(1),\n storageProtocol: z.literal(1).optional(),\n format: segment,\n resources: z\n .array(\n z\n .object({\n id: segment,\n path: relative,\n kind: z.enum([\"file\", \"directory\"]),\n required: z.boolean(),\n backup: z.enum([\"payload\", \"metadata\"]).optional(),\n })\n .strict(),\n )\n .min(1)\n .max(16),\n legacyVersions: z.array(segment).max(32).default([]),\n })\n .strict()\n .superRefine((m, ctx) => {\n if (new Set(m.resources.map((r) => r.id)).size !== m.resources.length) ctx.addIssue({ code: \"custom\", message: \"Duplicate resource ID\" });\n for (const r of m.resources) {\n if ([\"store.json\", \"store-resources.json\", \"store-operation.json\", \"store-lease.sqlite\", \"store-returned.json\"].includes(r.id))\n ctx.addIssue({ code: \"custom\", message: \"Reserved store metadata resource\" });\n if ([\"config.json\", \"controller-state.json\", RETAINED_STORE_BINDING, RETAINED_STORE_GUARD].includes(r.path))\n ctx.addIssue({ code: \"custom\", message: \"Reserved instance resource\" });\n if (m.resources.some((o) => o !== r && (o.path === r.path || o.path.startsWith(r.path + \"/\"))))\n ctx.addIssue({ code: \"custom\", message: \"Overlapping resources\" });\n }\n });\nexport type RetainedStoreManifest = z.infer<typeof retainedStoreManifestSchema>;\nexport type StoreOwner = { rttNode: string; version: string; instanceId: string };\nexport type StoreBinding = {\n protocol: 1;\n storeId: string;\n generation: string;\n operationId: string;\n directory: string;\n format: string;\n configurationDigest: string;\n owner: StoreOwner;\n maintenance: true;\n};\nexport type ResourceMove = { id: string; relative: string; kind: \"file\" | \"directory\"; device: number; inode: number };\nexport type StoreMovePlan = {\n storeId: string;\n generation: string;\n format: string;\n source: string;\n directory: string;\n slots: RetainedStoreManifest[\"resources\"];\n moves: ResourceMove[];\n};\nconst ownerSchema = z.object({ rttNode: segment, version: segment, instanceId: segment }).strict();\nconst bindingSchema = z\n .object({\n protocol: z.literal(1),\n storeId: z.uuid(),\n generation: z.uuid(),\n operationId: z.uuid(),\n directory: z.string().max(4096),\n format: segment,\n configurationDigest: z.string().regex(/^[a-f0-9]{64}$/),\n owner: ownerSchema,\n maintenance: z.literal(true),\n })\n .strict();\nexport function retainedStoreDigest(value: unknown): string {\n const stable = (v: any): any =>\n Array.isArray(v)\n ? v.map(stable)\n : v && typeof v === \"object\"\n ? Object.fromEntries(\n Object.keys(v)\n .sort()\n .map((k) => [k, stable(v[k])]),\n )\n : v;\n return createHash(\"sha256\")\n .update(JSON.stringify(stable(value)))\n .digest(\"hex\");\n}\nexport function retainedStoreEntry(file: string): fs.Stats | undefined {\n try {\n return fs.lstatSync(file);\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw e;\n }\n}\nexport function assertRetainedStorePath(file: string): void {\n if (!path.isAbsolute(file) || path.normalize(file) !== file) throw Error(\"Unnormalized retained store path\");\n for (let p = file; p !== path.dirname(p); p = path.dirname(p)) {\n const s = retainedStoreEntry(p);\n if (s?.isSymbolicLink()) throw Error(\"Linked retained store path\");\n }\n}\nexport function readRetainedStoreJson(file: string): unknown {\n assertRetainedStorePath(file);\n const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);\n try {\n const s = fs.fstatSync(fd);\n if (!s.isFile() || s.nlink !== 1 || s.size > 128 * 1024 || s.uid !== process.getuid?.()) throw Error(\"Unsafe retained store metadata\");\n return JSON.parse(fs.readFileSync(fd, \"utf8\"));\n } finally {\n fs.closeSync(fd);\n }\n}\nexport function syncRetainedDirectory(directory: string): void {\n const fd = fs.openSync(directory, \"r\");\n try {\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n}\nexport function writeRetainedStoreJson(file: string, value: unknown): void {\n assertRetainedStorePath(file);\n const temporary = file + \".\" + randomUUID() + \".tmp\";\n const text = JSON.stringify(value);\n if (Buffer.byteLength(text) > 128 * 1024) throw Error(\"Retained store metadata too large\");\n try {\n const fd = fs.openSync(temporary, \"wx\", 0o600);\n try {\n fs.writeFileSync(fd, text);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n fs.renameSync(temporary, file);\n syncRetainedDirectory(path.dirname(file));\n } finally {\n if (retainedStoreEntry(temporary)) fs.unlinkSync(temporary);\n }\n}\nexport function readRetainedStoreManifest(packageDirectory: string): RetainedStoreManifest {\n return retainedStoreManifestSchema.parse(readRetainedStoreJson(path.join(packageDirectory, RETAINED_STORE_MANIFEST)));\n}\nexport function prepareRetainedStoreMove(source: string, root: string, storeId: string, manifest: RetainedStoreManifest): StoreMovePlan {\n z.uuid().parse(storeId);\n retainedStoreManifestSchema.parse(manifest);\n assertRetainedStorePath(source);\n assertRetainedStorePath(root);\n const directory = path.join(root, storeId);\n if (retainedStoreEntry(directory)) throw Error(\"Retained store destination exists\");\n const existingRoot = retainedStoreEntry(root);\n if (existingRoot && (!existingRoot.isDirectory() || existingRoot.uid !== process.getuid?.() || existingRoot.mode & 0o077))\n throw Error(\"Retained root must be private and owned\");\n const rootStat = existingRoot ?? fs.statSync(path.dirname(root)),\n sourceStat = fs.statSync(source);\n if (root === source || root.startsWith(source + path.sep) || source.startsWith(root + path.sep)) throw Error(\"Nested retained store roots\");\n if (rootStat.dev !== sourceStat.dev) throw Error(\"Retained store requires same filesystem; copy is not permitted\");\n const moves: ResourceMove[] = [];\n for (const resource of manifest.resources) {\n const file = path.join(source, resource.path);\n assertRetainedStorePath(file);\n const s = retainedStoreEntry(file);\n if (!s) {\n if (resource.required) throw Error(\"Required retained resource missing\");\n continue;\n }\n if (\n s.uid !== process.getuid?.() ||\n s.dev !== rootStat.dev ||\n s.isSymbolicLink() ||\n (resource.kind === \"file\" ? !s.isFile() || s.nlink !== 1 : !s.isDirectory())\n )\n throw Error(\"Unsafe retained resource\");\n moves.push({ id: resource.id, relative: resource.path, kind: resource.kind, device: s.dev, inode: s.ino });\n }\n return { storeId, generation: randomUUID(), format: manifest.format, source, directory, slots: manifest.resources, moves };\n}\nfunction matches(file: string, move: ResourceMove): boolean {\n assertRetainedStorePath(file);\n const s = retainedStoreEntry(file);\n return (\n !!s &&\n !s.isSymbolicLink() &&\n s.dev === move.device &&\n s.ino === move.inode &&\n s.uid === process.getuid?.() &&\n (move.kind === \"file\" ? s.isFile() && s.nlink === 1 : s.isDirectory())\n );\n}\n/** Caller durably records the complete plan and holds its resource reservation first.\n * Each rename is atomic; the multi-resource operation is deliberately resumable. */\nexport function applyRetainedStoreMove(plan: StoreMovePlan, direction: \"adopt\" | \"return\", afterMove?: (id: string) => void): void {\n z.object({\n storeId: z.uuid(),\n generation: z.uuid(),\n format: segment,\n source: z.string().max(4096),\n directory: z.string().max(4096),\n slots: z\n .array(\n z\n .object({\n id: segment,\n path: relative,\n kind: z.enum([\"file\", \"directory\"]),\n required: z.boolean(),\n backup: z.enum([\"payload\", \"metadata\"]).optional(),\n })\n .strict(),\n )\n .max(16),\n moves: z\n .array(\n z\n .object({\n id: segment,\n relative,\n kind: z.enum([\"file\", \"directory\"]),\n device: z.number().int().nonnegative(),\n inode: z.number().int().nonnegative(),\n })\n .strict(),\n )\n .max(16),\n })\n .strict()\n .parse(plan);\n z.enum([\"adopt\", \"return\"]).parse(direction);\n const manifest = retainedStoreManifestSchema.parse({ protocol: 1, format: plan.format, resources: plan.slots });\n if (plan.moves.some((move) => !manifest.resources.some((slot) => slot.id === move.id && slot.path === move.relative && slot.kind === move.kind)))\n throw Error(\"Retained move differs from declared resources\");\n if (\n new Set(plan.moves.map((m) => m.id)).size !== plan.moves.length ||\n plan.moves.some((m) => plan.moves.some((o) => o !== m && (m.relative === o.relative || o.relative.startsWith(m.relative + \"/\"))))\n )\n throw Error(\"Overlapping retained moves\");\n if (plan.directory === plan.source || plan.directory.startsWith(plan.source + path.sep) || plan.source.startsWith(plan.directory + path.sep))\n throw Error(\"Nested retained move\");\n assertRetainedStorePath(plan.source);\n assertRetainedStorePath(plan.directory);\n if (!retainedStoreEntry(plan.directory)) {\n fs.mkdirSync(plan.directory, { mode: 0o700 });\n syncRetainedDirectory(path.dirname(plan.directory));\n }\n const directoryStat = fs.lstatSync(plan.directory);\n if (!directoryStat.isDirectory() || directoryStat.uid !== process.getuid?.() || directoryStat.mode & 0o077)\n throw Error(\"Unsafe retained store directory\");\n for (const move of plan.moves) {\n const legacy = path.join(plan.source, move.relative),\n stable = path.join(plan.directory, move.id);\n const [from, to] = direction === \"adopt\" ? [legacy, stable] : [stable, legacy];\n if (!retainedStoreEntry(from) && matches(to, move)) continue;\n if (!matches(from, move) || retainedStoreEntry(to)) throw Error(\"Retained resource changed or destination is occupied\");\n fs.renameSync(from, to);\n syncRetainedDirectory(path.dirname(from));\n syncRetainedDirectory(path.dirname(to));\n if (!matches(to, move)) throw Error(\"Retained resource identity changed\");\n afterMove?.(move.id);\n }\n}\nexport function writeRetainedStoreBinding(instanceDirectory: string, binding: StoreBinding): void {\n bindingSchema.parse(binding);\n writeRetainedStoreJson(path.join(instanceDirectory, RETAINED_STORE_BINDING), binding);\n}\nexport function loadRetainedStoreBinding(instanceDirectory: string, operationId?: string): StoreBinding | undefined {\n const file = path.join(instanceDirectory, RETAINED_STORE_BINDING);\n if (!retainedStoreEntry(file)) return;\n const s = fs.statSync(file);\n if (s.mode & 0o077) throw Error(\"Retained store binding must be private\");\n const binding = bindingSchema.parse(readRetainedStoreJson(file));\n assertRetainedStorePath(binding.directory);\n const runtimeRoot = process.env[\"UNS_RETAINED_STORE_ROOT\"]?.trim();\n if (runtimeRoot && path.dirname(binding.directory) !== runtimeRoot) throw Error(\"Retained binding does not match the configured Runtime root\");\n const directoryStat = retainedStoreEntry(binding.directory);\n if (!directoryStat?.isDirectory() || directoryStat.uid !== process.getuid?.() || directoryStat.mode & 0o077)\n throw Error(\"Unsafe retained store directory\");\n available(path.dirname(binding.directory));\n if (\n retainedStoreEntry(path.join(binding.directory, \"store-operation.json\")) &&\n (readRetainedStoreJson(path.join(binding.directory, \"store-operation.json\")) as any).operationId !== operationId\n )\n throw Error(\"Retained store operation is incomplete\");\n const meta = bindingSchema.parse(readRetainedStoreJson(path.join(binding.directory, \"store.json\")));\n if (retainedStoreDigest(meta) !== retainedStoreDigest(binding)) throw Error(\"Retained store owner or generation changed\");\n return binding;\n}\n/** No application payload/schema inspection is performed by this helper. */\nexport function resolveRetainedStoreResources(\n instanceDirectory: string,\n manifest: RetainedStoreManifest,\n expected?: Partial<StoreOwner>,\n): { binding?: StoreBinding; resources: Record<string, string> } {\n retainedStoreManifestSchema.parse(manifest);\n if (retainedStoreEntry(path.join(instanceDirectory, RETAINED_STORE_GUARD))) throw Error(\"Retained store operation has fenced this instance\");\n const binding = loadRetainedStoreBinding(instanceDirectory);\n if (\n binding &&\n expected &&\n Object.entries(expected).some(([k, v]) =>\n k === \"version\" ? binding.owner.version.replace(/^v/, \"\") !== String(v).replace(/^v/, \"\") : (binding.owner as any)[k] !== v,\n )\n )\n throw Error(\"Retained binding does not name this runtime\");\n if (binding && binding.format !== manifest.format) throw Error(\"Unsupported retained store format\");\n if (binding) {\n if (manifest.storageProtocol !== 1) throw Error(\"Bound retained stores require the shared storage protocol\");\n const declaration = retainedStoreManifestSchema.parse(readRetainedStoreJson(path.join(binding.directory, \"store-resources.json\")));\n if (\n declaration.storageProtocol !== 1 ||\n declaration.format !== manifest.format ||\n retainedStoreDigest(declaration.resources) !== retainedStoreDigest(manifest.resources)\n )\n throw Error(\"Retained store resource declaration changed\");\n for (const resource of manifest.resources)\n if (resource.required && !retainedStoreEntry(path.join(binding.directory, resource.id))) throw Error(\"Required retained resource missing\");\n }\n return {\n binding,\n resources: Object.fromEntries(\n manifest.resources.map((r) => [r.id, binding ? path.join(binding.directory, r.id) : path.join(instanceDirectory, r.path)]),\n ),\n };\n}\n\nexport const retainedStoreSelectionSchema = z\n .object({\n requestId: z.uuid(),\n rttNode: segment,\n sourceVersion: segment,\n sourceInstanceId: segment,\n targetVersion: segment,\n targetInstanceId: segment,\n })\n .strict()\n .refine((x) => x.sourceVersion !== x.targetVersion || x.sourceInstanceId !== x.targetInstanceId, \"Source and target must differ\");\nexport const retainedStoreRequestSchema = z.discriminatedUnion(\"action\", [\n z.object({ action: z.literal(\"review\"), selection: retainedStoreSelectionSchema }).strict(),\n z.object({ action: z.literal(\"get\"), id: z.uuid() }).strict(),\n z.object({ action: z.enum([\"adopt\", \"return\"]), id: z.uuid(), reviewedChecksum: z.string().regex(/^[a-f0-9]{64}$/) }).strict(),\n]);\nexport type RetainedStoreRequest = z.infer<typeof retainedStoreRequestSchema>;\n\n/** Capture mutable control files from the current stopped owner before persisting return intent. */\nexport function prepareRetainedStoreReturn(plan: StoreMovePlan): StoreMovePlan {\n const moves: ResourceMove[] = [];\n for (const slot of plan.slots) {\n const stable = path.join(plan.directory, slot.id),\n legacy = path.join(plan.source, slot.path);\n assertRetainedStorePath(stable);\n assertRetainedStorePath(legacy);\n const a = retainedStoreEntry(stable),\n b = retainedStoreEntry(legacy);\n if (a && b) throw Error(\"Return destination is occupied\");\n if (a) {\n if (a.uid !== process.getuid?.() || a.isSymbolicLink() || (slot.kind === \"file\" ? !a.isFile() || a.nlink !== 1 : !a.isDirectory()))\n throw Error(\"Unsafe current retained resource\");\n moves.push({ id: slot.id, relative: slot.path, kind: slot.kind, device: a.dev, inode: a.ino });\n } else if (b) {\n const original = plan.moves.find((m) => m.id === slot.id);\n if (!original || !matches(legacy, original)) throw Error(\"Return source identity changed\");\n moves.push(original);\n } else if (slot.required) throw Error(\"Current retained resource missing\");\n }\n return { ...plan, moves };\n}\n\nexport function retainedStoreRoot(defaultBase: string, configured?: string): string {\n const root = configured?.trim() || path.join(defaultBase, \"retained-stores\");\n assertRetainedStorePath(root);\n return root;\n}\nexport function openRetainedStoreLease(binding: StoreBinding): { close: () => void } {\n return runtimeLease(binding);\n}\nexport function openRetainedStoreMaintenance(directory: string): () => void {\n return maintenanceLease(directory);\n}\nexport const retainedStoreBackupSchema = z\n .object({\n schemaVersion: z.literal(1),\n state: z.enum([\"included\", \"excluded\", \"empty\"]),\n rootSha256: z.string().regex(/^[a-f0-9]{64}$/),\n stores: z.number().int().min(0).max(32),\n files: z.number().int().min(0).max(100000),\n bytes: z.number().int().positive().max(68753031168),\n sha256: z.string().regex(/^[a-f0-9]{64}$/),\n })\n .strict();\n"]}
|
|
1
|
+
{"version":3,"file":"retained-store.js","sourceRoot":"","sources":["../../src/runtime/retained-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport { available, maintenanceLease, runtimeLease } from \"./retained-store-storage.mjs\";\nimport { inspectRetainedCopy, applyRetainedCopy, type RetainedCopyFingerprint } from \"./retained-store-copy.mjs\";\nimport { retainedStoreJob } from \"./retained-store-job.mjs\";\nconst copyLimits = () => JSON.parse(fs.readFileSync(new URL(\"./retained-store-storage-contract.json\", import.meta.url), \"utf8\"));\n\nconst segment = z.string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,127}$/);\nconst relative = z\n .string()\n .min(1)\n .max(256)\n .refine((value) => !path.isAbsolute(value) && !value.includes(\"\\\\\") && value.split(\"/\").every((p) => /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(p)));\nexport const RETAINED_STORE_MANIFEST = \"retained-store.manifest.json\";\nexport const RETAINED_STORE_BINDING = \"retained-store-binding.json\";\nexport const RETAINED_STORE_GUARD = \"retained-store-guard.json\";\nexport const retainedStoreManifestSchema = z\n .object({\n protocol: z.literal(1),\n storageProtocol: z.literal(1).optional(),\n format: segment,\n resources: z\n .array(\n z\n .object({\n id: segment,\n path: relative,\n kind: z.enum([\"file\", \"directory\"]),\n required: z.boolean(),\n backup: z.enum([\"payload\", \"metadata\"]).optional(),\n })\n .strict(),\n )\n .min(1)\n .max(16),\n legacyVersions: z.array(segment).max(32).default([]),\n })\n .strict()\n .superRefine((m, ctx) => {\n if (new Set(m.resources.map((r) => r.id)).size !== m.resources.length) ctx.addIssue({ code: \"custom\", message: \"Duplicate resource ID\" });\n for (const r of m.resources) {\n if ([\"store.json\", \"store-resources.json\", \"store-operation.json\", \"store-lease.sqlite\", \"store-returned.json\"].includes(r.id))\n ctx.addIssue({ code: \"custom\", message: \"Reserved store metadata resource\" });\n if ([\"config.json\", \"controller-state.json\", RETAINED_STORE_BINDING, RETAINED_STORE_GUARD].includes(r.path))\n ctx.addIssue({ code: \"custom\", message: \"Reserved instance resource\" });\n if (m.resources.some((o) => o !== r && (o.path === r.path || o.path.startsWith(r.path + \"/\"))))\n ctx.addIssue({ code: \"custom\", message: \"Overlapping resources\" });\n }\n });\nexport type RetainedStoreManifest = z.infer<typeof retainedStoreManifestSchema>;\nexport type StoreOwner = { rttNode: string; version: string; instanceId: string };\nexport type StoreBinding = {\n protocol: 1;\n storeId: string;\n generation: string;\n operationId: string;\n directory: string;\n format: string;\n configurationDigest: string;\n owner: StoreOwner;\n maintenance: true;\n};\nexport type ResourceMove = { id: string; relative: string; kind: \"file\" | \"directory\"; device: number; inode: number; content?: RetainedCopyFingerprint };\nexport type StoreMovePlan = {\n storeId: string;\n generation: string;\n format: string;\n source: string;\n directory: string;\n slots: RetainedStoreManifest[\"resources\"];\n moves: ResourceMove[];\n transfer?: \"copy-verified\";\n originalMoves?: ResourceMove[];\n};\nconst ownerSchema = z.object({ rttNode: segment, version: segment, instanceId: segment }).strict();\nconst bindingSchema = z\n .object({\n protocol: z.literal(1),\n storeId: z.uuid(),\n generation: z.uuid(),\n operationId: z.uuid(),\n directory: z.string().max(4096),\n format: segment,\n configurationDigest: z.string().regex(/^[a-f0-9]{64}$/),\n owner: ownerSchema,\n maintenance: z.literal(true),\n })\n .strict();\nexport function retainedStoreDigest(value: unknown): string {\n const stable = (v: any): any =>\n Array.isArray(v)\n ? v.map(stable)\n : v && typeof v === \"object\"\n ? Object.fromEntries(\n Object.keys(v)\n .sort()\n .map((k) => [k, stable(v[k])]),\n )\n : v;\n return createHash(\"sha256\")\n .update(JSON.stringify(stable(value)))\n .digest(\"hex\");\n}\nexport function retainedStoreEntry(file: string): fs.Stats | undefined {\n try {\n return fs.lstatSync(file);\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw e;\n }\n}\nexport function assertRetainedStorePath(file: string): void {\n if (!path.isAbsolute(file) || path.normalize(file) !== file) throw Error(\"Unnormalized retained store path\");\n for (let p = file; p !== path.dirname(p); p = path.dirname(p)) {\n const s = retainedStoreEntry(p);\n if (s?.isSymbolicLink()) throw Error(\"Linked retained store path\");\n }\n}\nexport function readRetainedStoreJson(file: string): unknown {\n assertRetainedStorePath(file);\n const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);\n try {\n const s = fs.fstatSync(fd);\n if (!s.isFile() || s.nlink !== 1 || s.size > 128 * 1024 || s.uid !== process.getuid?.()) throw Error(\"Unsafe retained store metadata\");\n return JSON.parse(fs.readFileSync(fd, \"utf8\"));\n } finally {\n fs.closeSync(fd);\n }\n}\nexport function syncRetainedDirectory(directory: string): void {\n const fd = fs.openSync(directory, \"r\");\n try {\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n}\nexport function writeRetainedStoreJson(file: string, value: unknown): void {\n assertRetainedStorePath(file);\n const temporary = file + \".\" + randomUUID() + \".tmp\";\n const text = JSON.stringify(value);\n if (Buffer.byteLength(text) > 128 * 1024) throw Error(\"Retained store metadata too large\");\n try {\n const fd = fs.openSync(temporary, \"wx\", 0o600);\n try {\n fs.writeFileSync(fd, text);\n fs.fsyncSync(fd);\n } finally {\n fs.closeSync(fd);\n }\n fs.renameSync(temporary, file);\n syncRetainedDirectory(path.dirname(file));\n } finally {\n if (retainedStoreEntry(temporary)) fs.unlinkSync(temporary);\n }\n}\nexport function readRetainedStoreManifest(packageDirectory: string): RetainedStoreManifest {\n return retainedStoreManifestSchema.parse(readRetainedStoreJson(path.join(packageDirectory, RETAINED_STORE_MANIFEST)));\n}\nexport function prepareRetainedStoreMove(source: string, root: string, storeId: string, manifest: RetainedStoreManifest, transfer?: \"copy-verified\", deferContent=false): StoreMovePlan {\n z.uuid().parse(storeId);\n retainedStoreManifestSchema.parse(manifest);\n assertRetainedStorePath(source);\n assertRetainedStorePath(root);\n const directory = path.join(root, storeId);\n if (retainedStoreEntry(directory)) throw Error(\"Retained store destination exists\");\n const existingRoot = retainedStoreEntry(root);\n if (existingRoot && (!existingRoot.isDirectory() || existingRoot.uid !== process.getuid?.() || existingRoot.mode & 0o077))\n throw Error(\"Retained root must be private and owned\");\n const rootStat = existingRoot ?? fs.statSync(path.dirname(root)),\n sourceStat = fs.statSync(source);\n if (root === source || root.startsWith(source + path.sep) || source.startsWith(root + path.sep)) throw Error(\"Nested retained store roots\");\n if (transfer !== undefined && transfer !== \"copy-verified\") throw Error(\"Unsupported retained transfer\");\n if (!transfer && rootStat.dev !== sourceStat.dev) throw Error(\"Retained store requires same filesystem; review an explicit verified copy\");\n const moves: ResourceMove[] = [];\n for (const resource of manifest.resources) {\n const file = path.join(source, resource.path);\n assertRetainedStorePath(file);\n const s = retainedStoreEntry(file);\n if (!s) {\n if (resource.required) throw Error(\"Required retained resource missing\");\n continue;\n }\n if (\n s.uid !== process.getuid?.() ||\n (!transfer && s.dev !== rootStat.dev) ||\n s.isSymbolicLink() ||\n (resource.kind === \"file\" ? !s.isFile() || s.nlink !== 1 : !s.isDirectory())\n )\n throw Error(\"Unsafe retained resource\");\n moves.push({ id: resource.id, relative: resource.path, kind: resource.kind, device: s.dev, inode: s.ino,\n ...(transfer&&!deferContent ? {content:inspectRetainedCopy(file,resource.kind,copyLimits())} : {}) });\n }\n if(transfer && (moves.reduce((n,m)=>n+(m.content?.bytes??0),0)>copyLimits().maximumBytes || moves.reduce((n,m)=>n+(m.content?.entries??0),0)>copyLimits().maximumEntries))throw Error(\"Retained copy aggregate limit\");\n return { storeId, generation: randomUUID(), format: manifest.format, source, directory, slots: manifest.resources, moves, ...(transfer?{transfer}:{}) };\n}\nfunction matches(file: string, move: ResourceMove): boolean {\n assertRetainedStorePath(file);\n const s = retainedStoreEntry(file);\n return (\n !!s &&\n !s.isSymbolicLink() &&\n s.dev === move.device &&\n s.ino === move.inode &&\n s.uid === process.getuid?.() &&\n (move.kind === \"file\" ? s.isFile() && s.nlink === 1 : s.isDirectory())\n );\n}\n/** Caller durably records the complete plan and holds its resource reservation first.\n * Each rename is atomic; the multi-resource operation is deliberately resumable. */\nexport function applyRetainedStoreMove(plan: StoreMovePlan, direction: \"adopt\" | \"return\", afterMove?: (id: string) => void, onFile?: (file:string)=>void, validateOnly=false): void {\n const resourceMove = z.object({id:segment,relative,kind:z.enum([\"file\",\"directory\"]),device:z.number().int().nonnegative(),inode:z.number().int().nonnegative(),content:z.object({digest:z.string().regex(/^[a-f0-9]{64}$/),bytes:z.number().int().nonnegative().max(copyLimits().maximumBytes),entries:z.number().int().positive().max(copyLimits().maximumEntries)}).strict().optional()}).strict();\n z.object({\n storeId: z.uuid(),\n generation: z.uuid(),\n format: segment,\n source: z.string().max(4096),\n directory: z.string().max(4096),\n slots: z\n .array(\n z\n .object({\n id: segment,\n path: relative,\n kind: z.enum([\"file\", \"directory\"]),\n required: z.boolean(),\n backup: z.enum([\"payload\", \"metadata\"]).optional(),\n })\n .strict(),\n )\n .max(16),\n moves:z.array(resourceMove).max(16),\n transfer:z.literal(\"copy-verified\").optional(),\n originalMoves:z.array(resourceMove).max(16).optional(),\n })\n .strict()\n .parse(plan);\n z.enum([\"adopt\", \"return\"]).parse(direction);\n const manifest = retainedStoreManifestSchema.parse({ protocol: 1, format: plan.format, resources: plan.slots });\n if (plan.moves.some((move) => !manifest.resources.some((slot) => slot.id === move.id && slot.path === move.relative && slot.kind === move.kind)))\n throw Error(\"Retained move differs from declared resources\");\n if (\n new Set(plan.moves.map((m) => m.id)).size !== plan.moves.length ||\n plan.moves.some((m) => plan.moves.some((o) => o !== m && (m.relative === o.relative || o.relative.startsWith(m.relative + \"/\"))))\n )\n throw Error(\"Overlapping retained moves\");\n if (plan.directory === plan.source || plan.directory.startsWith(plan.source + path.sep) || plan.source.startsWith(plan.directory + path.sep))\n throw Error(\"Nested retained move\");\n assertRetainedStorePath(plan.source);\n assertRetainedStorePath(plan.directory);\n if (!retainedStoreEntry(plan.directory)) {\n fs.mkdirSync(plan.directory, { mode: 0o700 });\n syncRetainedDirectory(path.dirname(plan.directory));\n }\n const directoryStat = fs.lstatSync(plan.directory);\n if (!directoryStat.isDirectory() || directoryStat.uid !== process.getuid?.() || directoryStat.mode & 0o077)\n throw Error(\"Unsafe retained store directory\");\n if(plan.transfer){\n if(plan.moves.some(m=>!m.content) || plan.originalMoves?.some(m=>!m.content))throw Error(\"Verified copy requires reviewed content fingerprints\");\n for(const entries of [plan.moves,plan.originalMoves??[]])if(entries.reduce((n,m)=>n+(m.content?.bytes??0),0)>copyLimits().maximumBytes||entries.reduce((n,m)=>n+(m.content?.entries??0),0)>copyLimits().maximumEntries)throw Error(\"Retained copy aggregate limit\");\n if((plan.originalMoves??[]).some(m=>!manifest.resources.some(r=>r.id===m.id&&r.path===m.relative&&r.kind===m.kind)))throw Error(\"Original copy differs from declared resources\");\n if(!validateOnly)applyRetainedCopy(plan,direction,copyLimits(),afterMove,onFile); return;\n }\n if(plan.originalMoves)throw Error(\"Original copy receipt requires verified transfer\");\n for (const move of plan.moves) {\n const legacy = path.join(plan.source, move.relative),\n stable = path.join(plan.directory, move.id);\n const [from, to] = direction === \"adopt\" ? [legacy, stable] : [stable, legacy];\n if (!retainedStoreEntry(from) && matches(to, move)) continue;\n if (!matches(from, move) || retainedStoreEntry(to)) throw Error(\"Retained resource changed or destination is occupied\");\n fs.renameSync(from, to);\n syncRetainedDirectory(path.dirname(from));\n syncRetainedDirectory(path.dirname(to));\n if (!matches(to, move)) throw Error(\"Retained resource identity changed\");\n afterMove?.(move.id);\n }\n}\nexport function writeRetainedStoreBinding(instanceDirectory: string, binding: StoreBinding): void {\n bindingSchema.parse(binding);\n writeRetainedStoreJson(path.join(instanceDirectory, RETAINED_STORE_BINDING), binding);\n}\nexport function loadRetainedStoreBinding(instanceDirectory: string, operationId?: string): StoreBinding | undefined {\n const file = path.join(instanceDirectory, RETAINED_STORE_BINDING);\n if (!retainedStoreEntry(file)) return;\n const s = fs.statSync(file);\n if (s.mode & 0o077) throw Error(\"Retained store binding must be private\");\n const binding = bindingSchema.parse(readRetainedStoreJson(file));\n assertRetainedStorePath(binding.directory);\n const runtimeRoot = process.env[\"UNS_RETAINED_STORE_ROOT\"]?.trim();\n if (runtimeRoot && path.dirname(binding.directory) !== runtimeRoot) throw Error(\"Retained binding does not match the configured Runtime root\");\n const directoryStat = retainedStoreEntry(binding.directory);\n if (!directoryStat?.isDirectory() || directoryStat.uid !== process.getuid?.() || directoryStat.mode & 0o077)\n throw Error(\"Unsafe retained store directory\");\n available(path.dirname(binding.directory));\n if (\n retainedStoreEntry(path.join(binding.directory, \"store-operation.json\")) &&\n (readRetainedStoreJson(path.join(binding.directory, \"store-operation.json\")) as any).operationId !== operationId\n )\n throw Error(\"Retained store operation is incomplete\");\n const meta = bindingSchema.parse(readRetainedStoreJson(path.join(binding.directory, \"store.json\")));\n if (retainedStoreDigest(meta) !== retainedStoreDigest(binding)) throw Error(\"Retained store owner or generation changed\");\n return binding;\n}\n/** No application payload/schema inspection is performed by this helper. */\nexport function resolveRetainedStoreResources(\n instanceDirectory: string,\n manifest: RetainedStoreManifest,\n expected?: Partial<StoreOwner>,\n): { binding?: StoreBinding; resources: Record<string, string> } {\n retainedStoreManifestSchema.parse(manifest);\n if (retainedStoreEntry(path.join(instanceDirectory, RETAINED_STORE_GUARD))) throw Error(\"Retained store operation has fenced this instance\");\n const binding = loadRetainedStoreBinding(instanceDirectory);\n if (\n binding &&\n expected &&\n Object.entries(expected).some(([k, v]) =>\n k === \"version\" ? binding.owner.version.replace(/^v/, \"\") !== String(v).replace(/^v/, \"\") : (binding.owner as any)[k] !== v,\n )\n )\n throw Error(\"Retained binding does not name this runtime\");\n if (binding && binding.format !== manifest.format) throw Error(\"Unsupported retained store format\");\n if (binding) {\n if (manifest.storageProtocol !== 1) throw Error(\"Bound retained stores require the shared storage protocol\");\n const declaration = retainedStoreManifestSchema.parse(readRetainedStoreJson(path.join(binding.directory, \"store-resources.json\")));\n if (\n declaration.storageProtocol !== 1 ||\n declaration.format !== manifest.format ||\n retainedStoreDigest(declaration.resources) !== retainedStoreDigest(manifest.resources)\n )\n throw Error(\"Retained store resource declaration changed\");\n for (const resource of manifest.resources)\n if (resource.required && !retainedStoreEntry(path.join(binding.directory, resource.id))) throw Error(\"Required retained resource missing\");\n }\n return {\n binding,\n resources: Object.fromEntries(\n manifest.resources.map((r) => [r.id, binding ? path.join(binding.directory, r.id) : path.join(instanceDirectory, r.path)]),\n ),\n };\n}\n\nexport const retainedStoreSelectionSchema = z\n .object({\n requestId: z.uuid(),\n rttNode: segment,\n sourceVersion: segment,\n sourceInstanceId: segment,\n targetVersion: segment,\n targetInstanceId: segment,\n transfer:z.literal(\"copy-verified\").optional(),\n })\n .strict()\n .refine((x) => x.sourceVersion !== x.targetVersion || x.sourceInstanceId !== x.targetInstanceId, \"Source and target must differ\");\nexport const retainedStoreRequestSchema = z.discriminatedUnion(\"action\", [\n z.object({ action: z.literal(\"review\"), selection: retainedStoreSelectionSchema }).strict(),\n z.object({ action: z.literal(\"get\"), id: z.uuid() }).strict(),\n z.object({ action: z.enum([\"adopt\", \"return\"]), id: z.uuid(), reviewedChecksum: z.string().regex(/^[a-f0-9]{64}$/) }).strict(),\n]);\nexport type RetainedStoreRequest = z.infer<typeof retainedStoreRequestSchema>;\n\n/** Capture mutable control files from the current stopped owner before persisting return intent. */\nexport function prepareRetainedStoreReturn(plan: StoreMovePlan,deferContent=false): StoreMovePlan {\n const moves: ResourceMove[] = [];\n if(plan.transfer){\n for(const slot of plan.slots){\n const stable=path.join(plan.directory,slot.id),legacy=path.join(plan.source,slot.path),a=retainedStoreEntry(stable),b=retainedStoreEntry(legacy);\n if(a){assertRetainedStorePath(stable);moves.push({id:slot.id,relative:slot.path,kind:slot.kind,device:a.dev,inode:a.ino,...(!deferContent?{content:inspectRetainedCopy(stable,slot.kind,copyLimits())}:{})});}\n else if(b){const original=plan.moves.find(m=>m.id===slot.id);if(!original||!matches(legacy,original)||(!deferContent&&retainedStoreDigest(inspectRetainedCopy(legacy,slot.kind,copyLimits()))!==retainedStoreDigest(original.content)))throw Error(\"Original retained copy changed\");}\n else if(slot.required)throw Error(\"Current retained resource missing\");\n }\n return{...plan,moves,originalMoves:plan.moves};\n }\n for (const slot of plan.slots) {\n const stable = path.join(plan.directory, slot.id),\n legacy = path.join(plan.source, slot.path);\n assertRetainedStorePath(stable);\n assertRetainedStorePath(legacy);\n const a = retainedStoreEntry(stable),\n b = retainedStoreEntry(legacy);\n if (a && b) throw Error(\"Return destination is occupied\");\n if (a) {\n if (a.uid !== process.getuid?.() || a.isSymbolicLink() || (slot.kind === \"file\" ? !a.isFile() || a.nlink !== 1 : !a.isDirectory()))\n throw Error(\"Unsafe current retained resource\");\n moves.push({ id: slot.id, relative: slot.path, kind: slot.kind, device: a.dev, inode: a.ino });\n } else if (b) {\n const original = plan.moves.find((m) => m.id === slot.id);\n if (!original || !matches(legacy, original)) throw Error(\"Return source identity changed\");\n moves.push(original);\n } else if (slot.required) throw Error(\"Current retained resource missing\");\n }\n return { ...plan, moves };\n}\n\nexport function retainedStoreRoot(defaultBase: string, configured?: string): string {\n const root = configured?.trim() || path.join(defaultBase, \"retained-stores\");\n assertRetainedStorePath(root);\n return root;\n}\nexport function openRetainedStoreLease(binding: StoreBinding): { close: () => void } {\n return runtimeLease(binding);\n}\nexport function openRetainedStoreMaintenance(directory: string): () => void {\n return maintenanceLease(directory);\n}\nexport async function prepareRetainedStoreMoveAsync(source:string,root:string,id:string,manifest:RetainedStoreManifest,transfer?:\"copy-verified\"):Promise<StoreMovePlan>{\n const plan=prepareRetainedStoreMove(source,root,id,manifest,transfer,!!transfer);\n if(transfer)for(const move of plan.moves)move.content=await retainedStoreJob({action:\"inspect\",path:path.join(source,move.relative),kind:move.kind,limits:copyLimits()}) as RetainedCopyFingerprint;\n return plan;\n}\nexport async function prepareRetainedStoreReturnAsync(plan:StoreMovePlan):Promise<StoreMovePlan>{\n const back=prepareRetainedStoreReturn(plan,!!plan.transfer);\n if(plan.transfer)for(const move of back.moves)move.content=await retainedStoreJob({action:\"inspect\",path:path.join(plan.directory,move.id),kind:move.kind,limits:copyLimits()}) as RetainedCopyFingerprint;\n return back;\n}\nexport async function applyRetainedStoreMoveAsync(plan:StoreMovePlan,direction:\"adopt\"|\"return\",afterMove?:(id:string)=>void):Promise<void>{\n if(!plan.transfer){applyRetainedStoreMove(plan,direction,afterMove);return;}\n applyRetainedStoreMove(plan,direction,undefined,undefined,true);\n await retainedStoreJob({action:\"apply\",plan,direction,limits:copyLimits()},afterMove);\n}\nexport const retainedStoreBackupSchema = z\n .object({\n schemaVersion: z.literal(1),\n state: z.enum([\"included\", \"excluded\", \"empty\"]),\n rootSha256: z.string().regex(/^[a-f0-9]{64}$/),\n stores: z.number().int().min(0).max(32),\n files: z.number().int().min(0).max(100000),\n bytes: z.number().int().positive().max(68753031168),\n sha256: z.string().regex(/^[a-f0-9]{64}$/),\n })\n .strict();\n"]}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Service access and publications (3.0.47)
|
|
2
|
+
|
|
3
|
+
This opt-in protocol separates permission to call a catalog operation from
|
|
4
|
+
permission to read its source. It is not a sandbox for arbitrary application
|
|
5
|
+
code or a substitute for restricted database and MQTT identities.
|
|
6
|
+
|
|
7
|
+
Package metadata requests authority; it never grants it. Keep existing JWT/JWKS
|
|
8
|
+
endpoint guards. Do not forward caller tokens to privileged sources or retry a
|
|
9
|
+
denied caller read with stronger credentials.
|
|
10
|
+
|
|
11
|
+
## Declaration
|
|
12
|
+
|
|
13
|
+
Ship a bounded JSON file with the installed package, and retain it in the build:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{"unsDatahub":{"serviceAccess":"service-access.json"}}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Use `parseServiceAccessDeclaration` from `@uns-kit/core/runtime/service-access.js`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"protocol": 1,
|
|
24
|
+
"permissions": {
|
|
25
|
+
"scopes": ["read:uns"],
|
|
26
|
+
"accessRules": ["example/background/#"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This works without a catalog, HTTP endpoint, or human requester. The declaration
|
|
32
|
+
requests a ceiling; an administrator must apply the effective policy under
|
|
33
|
+
**Microservices → instance → Service access** before the service can start with
|
|
34
|
+
a managed identity. Review the exact installed version and declaration digest.
|
|
35
|
+
The administrator can select fewer capabilities and narrower MQTT path filters;
|
|
36
|
+
unknown or administrative scopes are rejected. The identity, revocation and
|
|
37
|
+
same-request reissue mechanisms are the existing managed workload mechanisms.
|
|
38
|
+
UNS resource rules bound direct UNS reads; other recognized runtime scopes retain
|
|
39
|
+
their existing authorization semantics. This protocol does not create new
|
|
40
|
+
SQL, broker, filesystem or arbitrary external-service permissions.
|
|
41
|
+
|
|
42
|
+
A combined service adds optional `publications`, containing the manifest parsed
|
|
43
|
+
by `parseCatalogPublicationManifest`, to the same envelope. A publication-only
|
|
44
|
+
service uses empty `permissions.scopes` and `permissions.accessRules`. Its
|
|
45
|
+
managed token then has `catalog:sources:read` and **no raw UNS paths**. Adding
|
|
46
|
+
publication sources never adds them to the service's direct `read:uns` rules.
|
|
47
|
+
Publication approval is a separate operation/audience grant and never silently
|
|
48
|
+
grants other package-requested capabilities. Review both in Service access.
|
|
49
|
+
The Catalog contains execution/status and an administrator link to that editor.
|
|
50
|
+
There is one writable publication editor.
|
|
51
|
+
|
|
52
|
+
The earlier unpublished `unsDatahub.catalogAccess` marker remains an isolated
|
|
53
|
+
compatibility adapter for the first local fixtures. New consumers use
|
|
54
|
+
`serviceAccess`; declaring both markers is rejected. No released applications
|
|
55
|
+
are automatically migrated.
|
|
56
|
+
|
|
57
|
+
The optional publication manifest supports GET JSON,
|
|
58
|
+
closed JSON schemas (primitive, object and array types; no references, defaults,
|
|
59
|
+
or composition), string query parameters, and exact history source topics.
|
|
60
|
+
Source path segments follow the existing managed-identity resource vocabulary:
|
|
61
|
+
ASCII letters, digits and hyphens. Each source binds required `from`/`to` date-time parameters, a maximum window
|
|
62
|
+
(at most 31 days) and row count (at most 27000). Dates require a UTC offset.
|
|
63
|
+
Wildcard topics, arbitrary URLs/SQL/source selectors and undeclared input fields
|
|
64
|
+
are rejected. The broker caps source responses at 1 MiB; published responses
|
|
65
|
+
have a separately declared cap of at most 1 MiB.
|
|
66
|
+
|
|
67
|
+
Each operation declares `caller` or `approved-service`. Both require an explicit
|
|
68
|
+
administrator publication review and current caller permission on the SDK UNS
|
|
69
|
+
resource path (the operation path without `/api/`). In caller mode, source rules
|
|
70
|
+
and `read:uns` must also belong to the caller. Service mode never grants these
|
|
71
|
+
raw permissions to the caller.
|
|
72
|
+
|
|
73
|
+
## Runtime
|
|
74
|
+
|
|
75
|
+
Use `CatalogPublicationClient` with the installed, normalized manifest and the
|
|
76
|
+
Controller-provided runtime identity (`RTT_NODE`, `version`, `RTT_INSTANCE_ID`,
|
|
77
|
+
`UNS_CONTROLLER_PUBLIC_BASE`). The default `ServiceTokenProvider` reads the
|
|
78
|
+
Controller's rotating token file. There is no caller-token fallback.
|
|
79
|
+
|
|
80
|
+
Use `catalogPublicationHandler(client, operationId, transform)` in an existing
|
|
81
|
+
`registerApiCatalog` handler. Call `api.registerCatalogRoute()` to opt into the
|
|
82
|
+
existing signed launch route lease. The transform receives `history(sourceId)`
|
|
83
|
+
and the already validated input. It owns the derived result, not authorization.
|
|
84
|
+
The HTTP helper sets `Cache-Control: no-store` and rejects undeclared result
|
|
85
|
+
fields. Each execution rechecks current authority after asynchronous work,
|
|
86
|
+
including cached application results. Custom downloads and other handlers must
|
|
87
|
+
use the same mediated path; this candidate adds no persistent result cache.
|
|
88
|
+
|
|
89
|
+
A publication-only workload token has `catalog:sources:read` and no direct
|
|
90
|
+
`read:uns` authority. A combined service may separately receive `read:uns` on
|
|
91
|
+
its reviewed background paths, without receiving raw access to publication
|
|
92
|
+
sources. The Controller broker checks current user policy, active machine
|
|
93
|
+
identity/token generation, reviewed identity binding, launch, loaded portable
|
|
94
|
+
configuration, publication revision, audience and source bounds. Its internal
|
|
95
|
+
history token is exact-topic, lasts 15 seconds, and never leaves the broker.
|
|
96
|
+
Neither token bytes nor raw records belong in logs, review receipts or audit.
|
|
97
|
+
|
|
98
|
+
Two local acceptance consumers (energy intervals and quality sample counts) use
|
|
99
|
+
the same helper and Controller path. No application-name branch is needed.
|
|
100
|
+
|
|
101
|
+
## Adoption boundary
|
|
102
|
+
|
|
103
|
+
The SDK contract is introduced in 3.0.47. A matching Controller implementation
|
|
104
|
+
must also be installed; an SDK upgrade alone does not enable the host capability.
|
|
105
|
+
Existing applications do not change mode
|
|
106
|
+
implicitly. Install the shared SDK release first, update consumer lockfiles,
|
|
107
|
+
then review the matching installed declaration through the Controller.
|
|
108
|
+
Controller publication is bound to the installed declaration and portable
|
|
109
|
+
configuration; edits require review. A changed loaded configuration requires a
|
|
110
|
+
new launch, not token refresh. With the matching Controller candidate, the
|
|
111
|
+
signed digest of the same confirmed live launch survives ordinary credential
|
|
112
|
+
expiry and Controller restart. Current identity, policy, generation and approval
|
|
113
|
+
are still checked; expired bearer tokens remain invalid. Missing, corrupt,
|
|
114
|
+
foreign or changed-launch evidence requires explicit reviewed recovery.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## Local common-contract acceptance
|
|
118
|
+
|
|
119
|
+
An unrelated background history processor, with no API or Catalog offer, was
|
|
120
|
+
reviewed, narrowed live, revoked, reissued with the same identity and cold-moved
|
|
121
|
+
to another Controller. It retained the same policy and generation across the
|
|
122
|
+
move. A combined service read its separate background source directly, while a
|
|
123
|
+
catalog-only user consumed a derived result from a different approved source.
|
|
124
|
+
Both the user and workload were denied direct access to that publication source.
|
|
125
|
+
A publication-only empty raw policy stayed empty in storage and actual tokens.
|
|
126
|
+
|
|
127
|
+
These are local candidate checks, including clean packed-SDK installs. They are
|
|
128
|
+
not production, arbitrary-code isolation or external-resource adapter acceptance.
|
|
129
|
+
SDK publication and downstream frozen dependency updates
|
|
130
|
+
remain separate steps.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type CatalogPublicationManifest } from "./catalog-publication.js";
|
|
2
|
+
export declare const SERVICE_ACCESS_PROTOCOL = 1;
|
|
3
|
+
export declare const SERVICE_ACCESS_MANIFEST_FIELD = "serviceAccess";
|
|
4
|
+
export declare const SERVICE_RESOURCE_SCOPES: readonly ["read:uns", "identity:asset:publish", "runtime:captures:read", "runtime:captures:write", "runtime:triggers:read"];
|
|
5
|
+
export type ServiceAccessDeclaration = {
|
|
6
|
+
protocol: 1;
|
|
7
|
+
permissions: {
|
|
8
|
+
scopes: string[];
|
|
9
|
+
accessRules: string[];
|
|
10
|
+
};
|
|
11
|
+
publications?: CatalogPublicationManifest;
|
|
12
|
+
};
|
|
13
|
+
export declare function parseServiceAccessDeclaration(value: unknown): ServiceAccessDeclaration;
|
|
14
|
+
export declare const serviceAccessDigest: (value: unknown) => string;
|
|
15
|
+
/** Publication source rules are deliberately not raw UNS permissions. A service
|
|
16
|
+
* combining a background reader with a catalog must not gain their cross-product. */
|
|
17
|
+
export declare function serviceAccessCeiling(declaration: ServiceAccessDeclaration): {
|
|
18
|
+
scopes: string[];
|
|
19
|
+
accessRules: string[];
|
|
20
|
+
};
|
|
21
|
+
/** Conservative MQTT filter inclusion, not matching a filter as if it were data. */
|
|
22
|
+
export declare function serviceRuleWithin(requested: string, allowed: string): boolean;
|
|
23
|
+
//# sourceMappingURL=service-access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-access.d.ts","sourceRoot":"","sources":["../../src/runtime/service-access.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,0BAA0B,EAAmC,MAAM,0BAA0B,CAAC;AAGlI,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,6BAA6B,kBAAkB,CAAC;AAI7D,eAAO,MAAM,uBAAuB,6HAM1B,CAAC;AAaX,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,CAAC,CAAC;IACZ,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACzD,YAAY,CAAC,EAAE,0BAA0B,CAAC;CAC3C,CAAC;AACF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAQtF;AACD,eAAO,MAAM,mBAAmB,4BAAiB,CAAC;AAClD;qFACqF;AACrF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,wBAAwB;;;EAKzE;AACD,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAU7E"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CATALOG_SOURCE_SCOPE, parseCatalogPublicationManifest } from "./catalog-publication.js";
|
|
3
|
+
import { operatorDigest, operatorJson } from "./operator-api.js";
|
|
4
|
+
export const SERVICE_ACCESS_PROTOCOL = 1;
|
|
5
|
+
export const SERVICE_ACCESS_MANIFEST_FIELD = "serviceAccess";
|
|
6
|
+
// Only existing platform data/runtime capabilities. Administrative authority is
|
|
7
|
+
// never a package-requestable scope. UNS rules bound direct UNS reads; other
|
|
8
|
+
// runtime capabilities retain their existing platform authorization semantics.
|
|
9
|
+
export const SERVICE_RESOURCE_SCOPES = [
|
|
10
|
+
"read:uns",
|
|
11
|
+
"identity:asset:publish",
|
|
12
|
+
"runtime:captures:read",
|
|
13
|
+
"runtime:captures:write",
|
|
14
|
+
"runtime:triggers:read",
|
|
15
|
+
];
|
|
16
|
+
const rule = z
|
|
17
|
+
.string()
|
|
18
|
+
.min(1)
|
|
19
|
+
.max(512)
|
|
20
|
+
.refine((s) => s.split("/").every((p, i, a) => p === "+" || (p === "#" && i === a.length - 1) || /^[A-Za-z0-9-]+$/.test(p)));
|
|
21
|
+
const envelope = z
|
|
22
|
+
.object({
|
|
23
|
+
protocol: z.literal(1),
|
|
24
|
+
permissions: z.object({ scopes: z.array(z.enum(SERVICE_RESOURCE_SCOPES)).max(5), accessRules: z.array(rule).max(64) }).strict(),
|
|
25
|
+
publications: z.unknown().optional(),
|
|
26
|
+
})
|
|
27
|
+
.strict();
|
|
28
|
+
export function parseServiceAccessDeclaration(value) {
|
|
29
|
+
operatorJson(value);
|
|
30
|
+
const parsed = envelope.parse(value);
|
|
31
|
+
const permissions = { scopes: [...new Set(parsed.permissions.scopes)].sort(), accessRules: [...new Set(parsed.permissions.accessRules)].sort() };
|
|
32
|
+
if (!!permissions.scopes.length !== !!permissions.accessRules.length)
|
|
33
|
+
throw Error("service_access_resources_required");
|
|
34
|
+
const publications = parsed.publications === undefined ? undefined : parseCatalogPublicationManifest(parsed.publications);
|
|
35
|
+
if (!permissions.scopes.length && !publications)
|
|
36
|
+
throw Error("service_access_capability_required");
|
|
37
|
+
return { protocol: 1, permissions, ...(publications ? { publications } : {}) };
|
|
38
|
+
}
|
|
39
|
+
export const serviceAccessDigest = operatorDigest;
|
|
40
|
+
/** Publication source rules are deliberately not raw UNS permissions. A service
|
|
41
|
+
* combining a background reader with a catalog must not gain their cross-product. */
|
|
42
|
+
export function serviceAccessCeiling(declaration) {
|
|
43
|
+
return {
|
|
44
|
+
scopes: [...declaration.permissions.scopes, ...(declaration.publications ? [CATALOG_SOURCE_SCOPE] : [])].sort(),
|
|
45
|
+
accessRules: [...declaration.permissions.accessRules],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Conservative MQTT filter inclusion, not matching a filter as if it were data. */
|
|
49
|
+
export function serviceRuleWithin(requested, allowed) {
|
|
50
|
+
const a = allowed.split("/"), r = requested.split("/");
|
|
51
|
+
let i = 0;
|
|
52
|
+
for (; i < a.length; i++) {
|
|
53
|
+
if (a[i] === "#")
|
|
54
|
+
return true;
|
|
55
|
+
if (r[i] === undefined || r[i] === "#")
|
|
56
|
+
return false;
|
|
57
|
+
if (a[i] !== r[i] && a[i] !== "+")
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return i === r.length;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=service-access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-access.js","sourceRoot":"","sources":["../../src/runtime/service-access.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { CATALOG_SOURCE_SCOPE, type CatalogPublicationManifest, parseCatalogPublicationManifest } from \"./catalog-publication.js\";\nimport { operatorDigest, operatorJson } from \"./operator-api.js\";\n\nexport const SERVICE_ACCESS_PROTOCOL = 1;\nexport const SERVICE_ACCESS_MANIFEST_FIELD = \"serviceAccess\";\n// Only existing platform data/runtime capabilities. Administrative authority is\n// never a package-requestable scope. UNS rules bound direct UNS reads; other\n// runtime capabilities retain their existing platform authorization semantics.\nexport const SERVICE_RESOURCE_SCOPES = [\n \"read:uns\",\n \"identity:asset:publish\",\n \"runtime:captures:read\",\n \"runtime:captures:write\",\n \"runtime:triggers:read\",\n] as const;\nconst rule = z\n .string()\n .min(1)\n .max(512)\n .refine((s) => s.split(\"/\").every((p, i, a) => p === \"+\" || (p === \"#\" && i === a.length - 1) || /^[A-Za-z0-9-]+$/.test(p)));\nconst envelope = z\n .object({\n protocol: z.literal(1),\n permissions: z.object({ scopes: z.array(z.enum(SERVICE_RESOURCE_SCOPES)).max(5), accessRules: z.array(rule).max(64) }).strict(),\n publications: z.unknown().optional(),\n })\n .strict();\nexport type ServiceAccessDeclaration = {\n protocol: 1;\n permissions: { scopes: string[]; accessRules: string[] };\n publications?: CatalogPublicationManifest;\n};\nexport function parseServiceAccessDeclaration(value: unknown): ServiceAccessDeclaration {\n operatorJson(value);\n const parsed = envelope.parse(value);\n const permissions = { scopes: [...new Set(parsed.permissions.scopes)].sort(), accessRules: [...new Set(parsed.permissions.accessRules)].sort() };\n if (!!permissions.scopes.length !== !!permissions.accessRules.length) throw Error(\"service_access_resources_required\");\n const publications = parsed.publications === undefined ? undefined : parseCatalogPublicationManifest(parsed.publications);\n if (!permissions.scopes.length && !publications) throw Error(\"service_access_capability_required\");\n return { protocol: 1, permissions, ...(publications ? { publications } : {}) };\n}\nexport const serviceAccessDigest = operatorDigest;\n/** Publication source rules are deliberately not raw UNS permissions. A service\n * combining a background reader with a catalog must not gain their cross-product. */\nexport function serviceAccessCeiling(declaration: ServiceAccessDeclaration) {\n return {\n scopes: [...declaration.permissions.scopes, ...(declaration.publications ? [CATALOG_SOURCE_SCOPE] : [])].sort(),\n accessRules: [...declaration.permissions.accessRules],\n };\n}\n/** Conservative MQTT filter inclusion, not matching a filter as if it were data. */\nexport function serviceRuleWithin(requested: string, allowed: string): boolean {\n const a = allowed.split(\"/\"),\n r = requested.split(\"/\");\n let i = 0;\n for (; i < a.length; i++) {\n if (a[i] === \"#\") return true;\n if (r[i] === undefined || r[i] === \"#\") return false;\n if (a[i] !== r[i] && a[i] !== \"+\") return false;\n }\n return i === r.length;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-access.test.d.ts","sourceRoot":"","sources":["../../src/runtime/service-access.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { parseServiceAccessDeclaration, serviceAccessCeiling, serviceAccessDigest } from "./service-access.js";
|
|
3
|
+
import { serviceRuleWithin } from "./service-access.js";
|
|
4
|
+
const background = { protocol: 1, permissions: { scopes: ["read:uns"], accessRules: ["factory/sensors/#"] } };
|
|
5
|
+
it("supports an unrelated background service without catalog or HTTP", () => {
|
|
6
|
+
const d = parseServiceAccessDeclaration(background);
|
|
7
|
+
expect(d.publications).toBeUndefined();
|
|
8
|
+
expect(serviceAccessCeiling(d)).toEqual(background.permissions);
|
|
9
|
+
});
|
|
10
|
+
it.each(["admin:all", "catalog:sources:read", "write:anything"])("rejects package-requested privileged or unknown scope %s", (scope) => {
|
|
11
|
+
expect(() => parseServiceAccessDeclaration({ ...background, permissions: { ...background.permissions, scopes: [scope] } })).toThrow();
|
|
12
|
+
});
|
|
13
|
+
it.each([
|
|
14
|
+
{ protocol: 2 },
|
|
15
|
+
{ unknown: true },
|
|
16
|
+
{ permissions: { scopes: ["read:uns"], accessRules: [] } },
|
|
17
|
+
{ permissions: { scopes: [], accessRules: [] } },
|
|
18
|
+
{ permissions: { scopes: ["read:uns"], accessRules: ["factory/#/escape"] } },
|
|
19
|
+
])("fails closed on malformed declaration %j", (patch) => expect(() => parseServiceAccessDeclaration({ ...background, ...patch })).toThrow());
|
|
20
|
+
it("normalizes duplicate requirements for stable review digests", () => expect(serviceAccessDigest(parseServiceAccessDeclaration({
|
|
21
|
+
...background,
|
|
22
|
+
permissions: { scopes: ["read:uns", "read:uns"], accessRules: ["factory/sensors/#", "factory/sensors/#"] },
|
|
23
|
+
}))).toBe(serviceAccessDigest(parseServiceAccessDeclaration(background))));
|
|
24
|
+
it.each([
|
|
25
|
+
["plant/a", "plant/#", true],
|
|
26
|
+
["plant/+", "plant/#", true],
|
|
27
|
+
["plant/#", "plant/+", false],
|
|
28
|
+
["#", "plant/#", false],
|
|
29
|
+
["other/a", "plant/#", false],
|
|
30
|
+
])("validates resource narrowing %s within %s", (r, a, expected) => expect(serviceRuleWithin(r, a)).toBe(expected));
|
|
31
|
+
it("does not combine publication sources with raw background rules", () => {
|
|
32
|
+
const d = parseServiceAccessDeclaration({
|
|
33
|
+
...background,
|
|
34
|
+
publications: {
|
|
35
|
+
protocol: 1,
|
|
36
|
+
operations: [
|
|
37
|
+
{
|
|
38
|
+
id: "summary",
|
|
39
|
+
title: "Summary",
|
|
40
|
+
method: "GET",
|
|
41
|
+
path: "/api/derived/summary",
|
|
42
|
+
mode: "approved-service",
|
|
43
|
+
requestSchema: {
|
|
44
|
+
type: "object",
|
|
45
|
+
additionalProperties: false,
|
|
46
|
+
required: ["from", "to"],
|
|
47
|
+
properties: { from: { type: "string", format: "date-time" }, to: { type: "string", format: "date-time" } },
|
|
48
|
+
},
|
|
49
|
+
responseSchema: { type: "integer" },
|
|
50
|
+
sources: [{ id: "history", kind: "history", topic: "private/published" }],
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
expect(serviceAccessCeiling(d)).toEqual({ scopes: ["catalog:sources:read", "read:uns"], accessRules: ["factory/sensors/#"] });
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=service-access.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-access.test.js","sourceRoot":"","sources":["../../src/runtime/service-access.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, it } from \"vitest\";\n\nimport { parseServiceAccessDeclaration, serviceAccessCeiling, serviceAccessDigest } from \"./service-access.js\";\nimport { serviceRuleWithin } from \"./service-access.js\";\n\nconst background = { protocol: 1, permissions: { scopes: [\"read:uns\"], accessRules: [\"factory/sensors/#\"] } };\nit(\"supports an unrelated background service without catalog or HTTP\", () => {\n const d = parseServiceAccessDeclaration(background);\n expect(d.publications).toBeUndefined();\n expect(serviceAccessCeiling(d)).toEqual(background.permissions);\n});\nit.each([\"admin:all\", \"catalog:sources:read\", \"write:anything\"])(\"rejects package-requested privileged or unknown scope %s\", (scope) => {\n expect(() => parseServiceAccessDeclaration({ ...background, permissions: { ...background.permissions, scopes: [scope] } })).toThrow();\n});\nit.each([\n { protocol: 2 },\n { unknown: true },\n { permissions: { scopes: [\"read:uns\"], accessRules: [] } },\n { permissions: { scopes: [], accessRules: [] } },\n { permissions: { scopes: [\"read:uns\"], accessRules: [\"factory/#/escape\"] } },\n])(\"fails closed on malformed declaration %j\", (patch) => expect(() => parseServiceAccessDeclaration({ ...background, ...patch })).toThrow());\nit(\"normalizes duplicate requirements for stable review digests\", () =>\n expect(\n serviceAccessDigest(\n parseServiceAccessDeclaration({\n ...background,\n permissions: { scopes: [\"read:uns\", \"read:uns\"], accessRules: [\"factory/sensors/#\", \"factory/sensors/#\"] },\n }),\n ),\n ).toBe(serviceAccessDigest(parseServiceAccessDeclaration(background))));\n\nit.each([\n [\"plant/a\", \"plant/#\", true],\n [\"plant/+\", \"plant/#\", true],\n [\"plant/#\", \"plant/+\", false],\n [\"#\", \"plant/#\", false],\n [\"other/a\", \"plant/#\", false],\n])(\"validates resource narrowing %s within %s\", (r, a, expected) => expect(serviceRuleWithin(r as string, a as string)).toBe(expected));\nit(\"does not combine publication sources with raw background rules\", () => {\n const d = parseServiceAccessDeclaration({\n ...background,\n publications: {\n protocol: 1,\n operations: [\n {\n id: \"summary\",\n title: \"Summary\",\n method: \"GET\",\n path: \"/api/derived/summary\",\n mode: \"approved-service\",\n requestSchema: {\n type: \"object\",\n additionalProperties: false,\n required: [\"from\", \"to\"],\n properties: { from: { type: \"string\", format: \"date-time\" }, to: { type: \"string\", format: \"date-time\" } },\n },\n responseSchema: { type: \"integer\" },\n sources: [{ id: \"history\", kind: \"history\", topic: \"private/published\" }],\n },\n ],\n },\n });\n expect(serviceAccessCeiling(d)).toEqual({ scopes: [\"catalog:sources:read\", \"read:uns\"], accessRules: [\"factory/sensors/#\"] });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uns-kit/core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.47",
|
|
4
4
|
"description": "Core utilities and runtime building blocks for UNS-based realtime transformers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,6 +23,19 @@
|
|
|
23
23
|
"MIGRATIONS.md"
|
|
24
24
|
],
|
|
25
25
|
"exports": {
|
|
26
|
+
"./runtime/service-access.js": {
|
|
27
|
+
"types": "./dist/runtime/service-access.d.ts",
|
|
28
|
+
"import": "./dist/runtime/service-access.js"
|
|
29
|
+
},
|
|
30
|
+
"./runtime/catalog-publication.js": {
|
|
31
|
+
"types": "./dist/runtime/catalog-publication.d.ts",
|
|
32
|
+
"import": "./dist/runtime/catalog-publication.js"
|
|
33
|
+
},
|
|
34
|
+
"./runtime/catalog-publication-client.js": {
|
|
35
|
+
"types": "./dist/runtime/catalog-publication-client.d.ts",
|
|
36
|
+
"import": "./dist/runtime/catalog-publication-client.js"
|
|
37
|
+
},
|
|
38
|
+
"./runtime/service-access-guide.md": "./dist/runtime/service-access-guide.md",
|
|
26
39
|
"./runtime/retained-store.js": {
|
|
27
40
|
"types": "./dist/runtime/retained-store.d.ts",
|
|
28
41
|
"import": "./dist/runtime/retained-store.js"
|