@serve.zone/pallet-bundle 35.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist_ts_bundle/classes.controlprocess.d.ts +71 -0
  2. package/dist_ts_bundle/classes.controlprocess.js +441 -0
  3. package/dist_ts_bundle/classes.controlstderr.d.ts +36 -0
  4. package/dist_ts_bundle/classes.controlstderr.js +95 -0
  5. package/dist_ts_bundle/classes.releaseclient.d.ts +38 -0
  6. package/dist_ts_bundle/classes.releaseclient.js +285 -0
  7. package/dist_ts_bundle/errors.d.ts +35 -0
  8. package/dist_ts_bundle/errors.js +20 -0
  9. package/dist_ts_bundle/index.d.ts +10 -0
  10. package/dist_ts_bundle/index.js +11 -0
  11. package/dist_ts_bundle/inventory.d.ts +90 -0
  12. package/dist_ts_bundle/inventory.js +78 -0
  13. package/dist_ts_bundle/paths.d.ts +12 -0
  14. package/dist_ts_bundle/paths.js +76 -0
  15. package/dist_ts_bundle/plugins.d.ts +14 -0
  16. package/dist_ts_bundle/plugins.js +19 -0
  17. package/dist_ts_bundle/protocol.d.ts +48 -0
  18. package/dist_ts_bundle/protocol.js +47 -0
  19. package/dist_ts_bundle/units.d.ts +67 -0
  20. package/dist_ts_bundle/units.js +128 -0
  21. package/dist_ts_bundle/verify.d.ts +75 -0
  22. package/dist_ts_bundle/verify.js +263 -0
  23. package/dist_ts_bundle/version.d.ts +7 -0
  24. package/dist_ts_bundle/version.js +17 -0
  25. package/license.md +21 -0
  26. package/package.json +35 -0
  27. package/readme.md +176 -0
  28. package/ts_bundle/classes.controlprocess.ts +453 -0
  29. package/ts_bundle/classes.controlstderr.ts +92 -0
  30. package/ts_bundle/classes.releaseclient.ts +288 -0
  31. package/ts_bundle/errors.ts +40 -0
  32. package/ts_bundle/index.ts +10 -0
  33. package/ts_bundle/inventory.ts +104 -0
  34. package/ts_bundle/paths.ts +74 -0
  35. package/ts_bundle/plugins.ts +25 -0
  36. package/ts_bundle/protocol.ts +56 -0
  37. package/ts_bundle/readme.md +176 -0
  38. package/ts_bundle/units.ts +165 -0
  39. package/ts_bundle/verify.ts +353 -0
  40. package/ts_bundle/version.ts +18 -0
@@ -0,0 +1,263 @@
1
+ import * as plugins from './plugins.js';
2
+ import { PalletBundleError, requireBundle } from './errors.js';
3
+ import { canonicalPath, requireCanonicalDirectory } from './paths.js';
4
+ import { palletBundleVersion } from './version.js';
5
+ import { isPalletControlTarget, palletControlBundleName, palletControlComponents, palletControlNoticeTrees, palletControlPackageName, palletControlPaths, palletControlRecordKeys, palletControlRecordName, palletControlRoles, palletControlSourceInventories, palletNativeTarget, } from './inventory.js';
6
+ const hash = /^[a-f0-9]{64}$/;
7
+ const commit = /^[a-f0-9]{40}$/;
8
+ const semver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
9
+ const executableMode = 0o755;
10
+ const fileMode = 0o644;
11
+ const maximumMetadataBytes = 2 * 1024 * 1024;
12
+ const record = (valueArg) => typeof valueArg === 'object' && valueArg !== null && !Array.isArray(valueArg) &&
13
+ Object.getPrototypeOf(valueArg) === Object.prototype;
14
+ const sameKeys = (valueArg, keysArg) => {
15
+ const keys = Object.keys(valueArg);
16
+ return keys.length === keysArg.length && keysArg.every((key) => Object.hasOwn(valueArg, key));
17
+ };
18
+ const list = (valueArg) => Array.isArray(valueArg);
19
+ const safeName = (nameArg) => typeof nameArg === 'string' && nameArg.length <= 1024 && /^[A-Za-z0-9][A-Za-z0-9._+@/-]*$/.test(nameArg) &&
20
+ !nameArg.split('/').some((part) => ['', '.', '..'].includes(part));
21
+ const invalid = () => { throw new PalletBundleError('invalid_release'); };
22
+ export const validPalletBundlePin = (valueArg) => record(valueArg) && sameKeys(valueArg, ['version', 'sourceCommit', 'manifestSha256']) &&
23
+ typeof valueArg.version === 'string' && semver.test(valueArg.version) &&
24
+ typeof valueArg.sourceCommit === 'string' && commit.test(valueArg.sourceCommit) &&
25
+ typeof valueArg.manifestSha256 === 'string' && hash.test(valueArg.manifestSha256);
26
+ /** Refuses a malformed pin, and a pin of another Pallet version than this package states. */
27
+ export async function requirePalletBundlePin(pinArg) {
28
+ requireBundle(validPalletBundlePin(pinArg), 'invalid_options');
29
+ if (pinArg.version !== await palletBundleVersion())
30
+ throw new PalletBundleError('version_mismatch');
31
+ return Object.freeze({ version: pinArg.version, sourceCommit: pinArg.sourceCommit, manifestSha256: pinArg.manifestSha256 });
32
+ }
33
+ /** Reads one sealed file back and proves its bytes are the sealed record's. */
34
+ async function readSealed(directoryArg, filesArg, nameArg) {
35
+ const sealed = filesArg[nameArg];
36
+ requireBundle(sealed && safeName(nameArg) && sealed.mode === fileMode && sealed.size <= maximumMetadataBytes, 'invalid_release');
37
+ const filename = plugins.path.join(directoryArg, nameArg);
38
+ const file = await plugins.fs.open(filename, plugins.fsConstants.O_RDONLY | plugins.fsConstants.O_NOFOLLOW)
39
+ .catch(() => { throw new PalletBundleError('invalid_release'); });
40
+ try {
41
+ const info = await file.stat();
42
+ requireBundle(info.isFile() && info.size === sealed.size, 'invalid_release');
43
+ const bytes = Buffer.alloc(info.size);
44
+ let offset = 0;
45
+ while (offset < bytes.length) {
46
+ const { bytesRead } = await file.read(bytes, offset, bytes.length - offset, offset);
47
+ requireBundle(bytesRead > 0, 'invalid_release');
48
+ offset += bytesRead;
49
+ }
50
+ requireBundle(plugins.crypto.createHash('sha256').update(bytes).digest('hex') === sealed.sha256, 'artifact_mismatch');
51
+ return bytes;
52
+ }
53
+ finally {
54
+ await file.close();
55
+ }
56
+ }
57
+ async function readJson(directoryArg, filesArg, nameArg) {
58
+ const bytes = await readSealed(directoryArg, filesArg, nameArg);
59
+ try {
60
+ return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
61
+ }
62
+ catch {
63
+ return invalid();
64
+ }
65
+ }
66
+ /** The files below the prefixes, as the sealed manifest names them. */
67
+ const below = (filesArg, prefixesArg) => Object.keys(filesArg).filter((name) => prefixesArg.some((prefix) => name.startsWith(prefix))).sort();
68
+ const sameSet = (leftArg, rightArg) => leftArg.length === rightArg.length && [...leftArg].sort().every((name, index) => name === [...rightArg].sort()[index]);
69
+ /** The control record: its identity, its fixed paths, and each declared file's sealed record. */
70
+ function checkRecord(recordArg, filesArg, expectedArg) {
71
+ requireBundle(record(recordArg) && sameKeys(recordArg, palletControlRecordKeys), 'invalid_release');
72
+ const control = recordArg;
73
+ const compiler = control.compiler;
74
+ requireBundle(control.packageName === palletControlPackageName && control.version === expectedArg.version &&
75
+ control.sourceCommit === expectedArg.sourceCommit && control.sourceDirty === expectedArg.sourceDirty &&
76
+ control.target === expectedArg.target && control.expectedUid === palletControlPaths.expectedUid &&
77
+ control.dataRoot === palletControlPaths.dataRoot && control.socketPath === palletControlPaths.socketPath &&
78
+ control.runtimeSocketPath === palletControlPaths.runtimeSocketPath &&
79
+ typeof control.lockSha256 === 'string' && hash.test(control.lockSha256) &&
80
+ record(compiler) && Object.values(compiler).every((value) => typeof value === 'string') &&
81
+ typeof compiler.deno === 'string' && semver.test(compiler.deno), 'invalid_release');
82
+ const componentDigest = (componentArg) => {
83
+ const component = palletControlComponents[componentArg];
84
+ const digest = control[component.recordKey];
85
+ requireBundle(typeof digest === 'string' && hash.test(digest) && filesArg[component.manifest]?.sha256 === digest &&
86
+ filesArg[component.manifest].mode === fileMode, 'invalid_release');
87
+ return digest;
88
+ };
89
+ const facts = {
90
+ denoVersion: compiler.deno, lockSha256: control.lockSha256,
91
+ clockManifestSha256: componentDigest('clock'), containerdManifestSha256: componentDigest('containerd'),
92
+ dnsManifestSha256: componentDigest('dns'), vpnInventorySha256: componentDigest('vpn'),
93
+ };
94
+ const declared = control.files;
95
+ requireBundle(record(declared) && Object.keys(declared).length > 0, 'invalid_release');
96
+ for (const [name, described] of Object.entries(declared)) {
97
+ const sealed = filesArg[name];
98
+ requireBundle(safeName(name) && record(described) && sameKeys(described, ['sha256', 'size']) && sealed &&
99
+ described.sha256 === sealed.sha256 && described.size === sealed.size, 'invalid_release');
100
+ }
101
+ // Every executable the bundle carries is one the control record declares.
102
+ for (const [name, sealed] of Object.entries(filesArg)) {
103
+ requireBundle(safeName(name) && (sealed.mode === fileMode || (sealed.mode === executableMode && Object.hasOwn(declared, name))), 'invalid_release');
104
+ }
105
+ for (const role of Object.values(palletControlRoles)) {
106
+ requireBundle(Object.hasOwn(declared, role.path) && filesArg[role.path]?.mode === executableMode &&
107
+ filesArg[role.path].size > 0, 'invalid_release');
108
+ if (role.provenance) {
109
+ requireBundle(Object.hasOwn(declared, role.provenance.path) && filesArg[role.provenance.path]?.mode === fileMode, 'invalid_release');
110
+ }
111
+ }
112
+ return facts;
113
+ }
114
+ /** A listing component: its manifest names exactly the files below its directory. */
115
+ async function checkListing(directoryArg, filesArg, manifestArg, prefixArg) {
116
+ const manifest = await readJson(directoryArg, filesArg, manifestArg);
117
+ requireBundle(record(manifest) && list(manifest.files) && manifest.files.length > 0, 'invalid_release');
118
+ const listed = [];
119
+ for (const entry of manifest.files) {
120
+ requireBundle(record(entry) && safeName(entry.path) && typeof entry.sha256 === 'string' && hash.test(entry.sha256) &&
121
+ Number.isSafeInteger(entry.size) && (entry.mode === executableMode || entry.mode === fileMode), 'invalid_release');
122
+ const name = `${prefixArg}${entry.path}`;
123
+ const sealed = filesArg[name];
124
+ requireBundle(name !== manifestArg && sealed && sealed.sha256 === entry.sha256 && sealed.size === entry.size &&
125
+ sealed.mode === entry.mode, 'invalid_release');
126
+ listed.push(name);
127
+ }
128
+ requireBundle(new Set(listed).size === listed.length && sameSet(below(filesArg, [prefixArg]), [manifestArg, ...listed]), 'invalid_release');
129
+ return manifest;
130
+ }
131
+ /** A `tsrust.native-notices` tree: its manifest names every file below the prefix by digest. */
132
+ async function checkNoticeTree(directoryArg, filesArg, prefixArg) {
133
+ const manifestName = `${prefixArg}manifest.json`;
134
+ const manifest = await readJson(directoryArg, filesArg, manifestName);
135
+ requireBundle(record(manifest) && manifest.format === 'tsrust.native-notices' && record(manifest.files), 'invalid_release');
136
+ const named = Object.entries(manifest.files);
137
+ requireBundle(named.length > 0 && named.length <= 1024 && !Object.hasOwn(manifest.files, 'manifest.json'), 'invalid_release');
138
+ for (const [name, digest] of named) {
139
+ const sealed = filesArg[`${prefixArg}${name}`];
140
+ requireBundle(safeName(name) && typeof digest === 'string' && hash.test(digest) && sealed?.sha256 === digest &&
141
+ sealed.mode === fileMode, 'invalid_release');
142
+ }
143
+ requireBundle(sameSet(below(filesArg, [prefixArg]), [manifestName, ...named.map(([name]) => `${prefixArg}${name}`)]), 'invalid_release');
144
+ }
145
+ /** A notice and corresponding-source inventory: its manifest lists every file below its prefixes. */
146
+ async function checkSourceInventory(directoryArg, filesArg, manifestArg, prefixesArg) {
147
+ const manifest = await readJson(directoryArg, filesArg, manifestArg);
148
+ requireBundle(record(manifest) && list(manifest.files) && manifest.files.length > 0, 'invalid_release');
149
+ const listed = [];
150
+ for (const entry of manifest.files) {
151
+ requireBundle(record(entry), 'invalid_release');
152
+ const path = entry.path;
153
+ requireBundle(safeName(path) && path !== manifestArg && prefixesArg.some((prefix) => path.startsWith(prefix)) &&
154
+ typeof entry.sha256 === 'string' && hash.test(entry.sha256) && Number.isSafeInteger(entry.size) &&
155
+ filesArg[path]?.sha256 === entry.sha256 && filesArg[path].size === entry.size &&
156
+ filesArg[path].mode === fileMode, 'invalid_release');
157
+ listed.push(path);
158
+ }
159
+ requireBundle(new Set(listed).size === listed.length && sameSet(below(filesArg, prefixesArg), [manifestArg, ...listed]), 'invalid_release');
160
+ }
161
+ /** One native executable's tsrust provenance, bound to the sealed executable and this bundle's target. */
162
+ async function checkProvenance(directoryArg, filesArg, roleArg, expectedArg) {
163
+ const role = palletControlRoles[roleArg];
164
+ const description = role.provenance;
165
+ const provenance = await readJson(directoryArg, filesArg, description.path);
166
+ requireBundle(record(provenance), 'invalid_release');
167
+ const build = provenance.buildInfo;
168
+ requireBundle(record(build), 'invalid_release');
169
+ const own = roleArg === 'runtime';
170
+ requireBundle(provenance.format === 'tsrust.build-provenance.v2' && provenance.binarySha256 === filesArg[role.path].sha256 &&
171
+ build.projectName === description.projectName && build.binary === description.binary &&
172
+ build.target === palletNativeTarget(expectedArg.target) &&
173
+ typeof build.projectVersion === 'string' && semver.test(build.projectVersion) &&
174
+ typeof build.gitCommit === 'string' && commit.test(build.gitCommit) &&
175
+ build.gitDirty === (own ? expectedArg.sourceDirty : false) &&
176
+ (!own || (build.projectVersion === expectedArg.version && build.gitCommit === expectedArg.sourceCommit)), 'invalid_release');
177
+ return Object.freeze({ projectName: description.projectName, projectVersion: build.projectVersion, gitCommit: build.gitCommit });
178
+ }
179
+ /**
180
+ * Checks a control build directory against the sealed records of its files: the control record,
181
+ * every executable's role and provenance, the component manifests and the notice and source
182
+ * inventories. Pallet's packaging runs this over every build before sealing it, with the build's
183
+ * own source identity; consumers use {@link verifyPalletControlBundle}, which also binds the pin.
184
+ */
185
+ export async function inspectPalletControlBuild(directoryArg, filesArg, expectedArg) {
186
+ const directory = canonicalPath(directoryArg);
187
+ requireBundle(isPalletControlTarget(expectedArg.target) && semver.test(expectedArg.version) &&
188
+ commit.test(expectedArg.sourceCommit) && typeof expectedArg.sourceDirty === 'boolean' && record(filesArg), 'invalid_options');
189
+ await requireCanonicalDirectory(directory);
190
+ const control = checkRecord(await readJson(directory, filesArg, palletControlRecordName), filesArg, expectedArg);
191
+ await checkListing(directory, filesArg, palletControlComponents.clock.manifest, palletControlComponents.clock.directory);
192
+ const containerd = await checkListing(directory, filesArg, palletControlComponents.containerd.manifest, palletControlComponents.containerd.directory);
193
+ requireBundle(typeof containerd.containerdVersion === 'string' && typeof containerd.runcVersion === 'string', 'invalid_release');
194
+ for (const tree of palletControlNoticeTrees)
195
+ await checkNoticeTree(directory, filesArg, tree);
196
+ for (const inventory of palletControlSourceInventories) {
197
+ await checkSourceInventory(directory, filesArg, inventory.manifest, inventory.prefixes);
198
+ }
199
+ const provenance = {
200
+ store: await checkProvenance(directory, filesArg, 'store', expectedArg),
201
+ runtime: await checkProvenance(directory, filesArg, 'runtime', expectedArg),
202
+ guard: await checkProvenance(directory, filesArg, 'guard', expectedArg),
203
+ dns: await checkProvenance(directory, filesArg, 'dns', expectedArg),
204
+ vpn: await checkProvenance(directory, filesArg, 'vpn', expectedArg),
205
+ };
206
+ const executable = (roleArg) => Object.freeze({
207
+ path: plugins.path.join(directory, palletControlRoles[roleArg].path), sha256: filesArg[palletControlRoles[roleArg].path].sha256,
208
+ });
209
+ return Object.freeze({
210
+ directory, target: expectedArg.target, version: expectedArg.version, sourceCommit: expectedArg.sourceCommit,
211
+ sourceDirty: expectedArg.sourceDirty, denoVersion: control.denoVersion, lockSha256: control.lockSha256,
212
+ executables: Object.freeze({ control: executable('control'), store: executable('store'), runtime: executable('runtime'),
213
+ guard: executable('guard'), dns: executable('dns'), vpn: executable('vpn') }),
214
+ provenance: Object.freeze(provenance),
215
+ clockManifestSha256: control.clockManifestSha256, dnsManifestSha256: control.dnsManifestSha256,
216
+ vpnInventorySha256: control.vpnInventorySha256, containerdManifestSha256: control.containerdManifestSha256,
217
+ containerdVersion: containerd.containerdVersion, runcVersion: containerd.runcVersion,
218
+ files: Object.freeze({ ...filesArg }),
219
+ });
220
+ }
221
+ /**
222
+ * Verifies an extracted release bundle of the pinned version: `filesArg` are the records of the
223
+ * sealed release manifest whose digest the pin states (tspack's `extractBundle` result), and the
224
+ * pin must name this package's own Pallet version.
225
+ */
226
+ export async function verifyPalletControlBundle(directoryArg, filesArg, pinArg, targetArg) {
227
+ const pin = await requirePalletBundlePin(pinArg);
228
+ requireBundle(isPalletControlTarget(targetArg), 'invalid_options');
229
+ const bundle = await inspectPalletControlBuild(directoryArg, filesArg, { version: pin.version, sourceCommit: pin.sourceCommit, sourceDirty: false, target: targetArg });
230
+ return Object.freeze({ ...bundle, manifestSha256: pin.manifestSha256 });
231
+ }
232
+ /**
233
+ * Extracts and verifies the pinned bundle from a download directory that holds the release's
234
+ * `tspack-manifest.json`, `SHA256SUMS.txt` and the target's archive. The bundle is extracted into a
235
+ * fresh private directory below `stagingParentArg`, which the caller owns from then on.
236
+ */
237
+ export async function extractPalletControlBundle(downloadDirectoryArg, targetArg, stagingParentArg, pinArg, signalArg) {
238
+ const pin = await requirePalletBundlePin(pinArg);
239
+ requireBundle(isPalletControlTarget(targetArg), 'invalid_options');
240
+ await requireCanonicalDirectory(canonicalPath(stagingParentArg));
241
+ let extracted;
242
+ try {
243
+ extracted = await new plugins.tspack.TsPack().extractBundle(downloadDirectoryArg, targetArg, stagingParentArg, {
244
+ expectedManifestSha256: pin.manifestSha256, expectedSourceCommit: pin.sourceCommit, requireRelease: true,
245
+ ...(signalArg ? { signal: signalArg } : {}),
246
+ });
247
+ }
248
+ catch (error) {
249
+ if (signalArg?.aborted)
250
+ throw new PalletBundleError('aborted', { cause: error });
251
+ throw new PalletBundleError('invalid_release', { cause: error });
252
+ }
253
+ try {
254
+ requireBundle(extracted.manifest.packageName === palletControlPackageName &&
255
+ extracted.manifest.name === palletControlBundleName && extracted.manifest.version === pin.version, 'invalid_release');
256
+ return await verifyPalletControlBundle(extracted.directory, extracted.artifact.files, pin, targetArg);
257
+ }
258
+ catch (error) {
259
+ await plugins.fs.rm(extracted.directory, { recursive: true, force: true });
260
+ throw error;
261
+ }
262
+ }
263
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyaWZ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfYnVuZGxlL3ZlcmlmeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxhQUFhLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ25ELE9BQU8sRUFDTCxxQkFBcUIsRUFBRSx1QkFBdUIsRUFBRSx1QkFBdUIsRUFBRSx3QkFBd0IsRUFBRSx3QkFBd0IsRUFDM0gsa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUsdUJBQXVCLEVBQUUsa0JBQWtCLEVBQUUsOEJBQThCLEVBQ3hILGtCQUFrQixHQUNuQixNQUFNLGdCQUFnQixDQUFDO0FBNER4QixNQUFNLElBQUksR0FBRyxnQkFBZ0IsQ0FBQztBQUM5QixNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQztBQUNoQyxNQUFNLE1BQU0sR0FBRyw0Q0FBNEMsQ0FBQztBQUM1RCxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUM7QUFDN0IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDO0FBQ3ZCLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFHN0MsTUFBTSxNQUFNLEdBQUcsQ0FBQyxRQUFpQixFQUF1QixFQUFFLENBQ3hELE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxRQUFRLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7SUFDN0UsTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsS0FBSyxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQ3ZELE1BQU0sUUFBUSxHQUFHLENBQUMsUUFBaUIsRUFB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
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The Pallet version this package describes. The package is released from Pallet's repository with
3
+ * Pallet's own version, so this is the one bundle version whose inventory and contracts it states.
4
+ * It is read from the package manifest beside the compiled module, which is Pallet's root manifest
5
+ * in the repository and the published package's own manifest in `node_modules`.
6
+ */
7
+ export declare const palletBundleVersion: () => Promise<string>;
@@ -0,0 +1,17 @@
1
+ import * as plugins from './plugins.js';
2
+ let ownVersion;
3
+ /**
4
+ * The Pallet version this package describes. The package is released from Pallet's repository with
5
+ * Pallet's own version, so this is the one bundle version whose inventory and contracts it states.
6
+ * It is read from the package manifest beside the compiled module, which is Pallet's root manifest
7
+ * in the repository and the published package's own manifest in `node_modules`.
8
+ */
9
+ export const palletBundleVersion = () => ownVersion ??= (async () => {
10
+ const manifest = JSON.parse(await plugins.fs.readFile(new URL('../package.json', import.meta.url), 'utf8'));
11
+ const version = typeof manifest === 'object' && manifest !== null && 'version' in manifest ? manifest.version : undefined;
12
+ if (typeof version !== 'string' || !/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(version)) {
13
+ throw new Error('The Pallet bundle package manifest carries no release version.');
14
+ }
15
+ return version;
16
+ })();
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2J1bmRsZS92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLElBQUksVUFBdUMsQ0FBQztBQUU1Qzs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLEdBQW9CLEVBQUUsQ0FBQyxVQUFVLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRTtJQUNuRixNQUFNLFFBQVEsR0FBWSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sT0FBTyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxHQUFHLENBQUMsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3JILE1BQU0sT0FBTyxHQUFHLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxRQUFRLEtBQUssSUFBSSxJQUFJLFNBQVMsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUMxSCxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxDQUFDLDRDQUE0QyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQy9GLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBQ0QsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyJ9
package/license.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Task Venture Capital GmbH
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "author": "Task Venture Capital GmbH",
3
+ "license": "MIT",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://code.foss.global/serve.zone/pallet.git"
7
+ },
8
+ "homepage": "https://code.foss.global/serve.zone/pallet",
9
+ "bugs": {
10
+ "url": "https://community.foss.global/"
11
+ },
12
+ "name": "@serve.zone/pallet-bundle",
13
+ "version": "35.3.0",
14
+ "type": "module",
15
+ "description": "Install surface of Pallet's sealed control bundle: pinned release download and verification, the service units Pallet's contract states, and supervisors for the pallet-control process protocol.",
16
+ "main": "./dist_ts_bundle/index.js",
17
+ "types": "./dist_ts_bundle/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist_ts_bundle/index.d.ts",
21
+ "import": "./dist_ts_bundle/index.js"
22
+ }
23
+ },
24
+ "dependencies": {
25
+ "@git.zone/tspack": "1.4.1",
26
+ "@push.rocks/smartdaemon": "2.14.0",
27
+ "@serve.zone/interfaces": "32.32.0"
28
+ },
29
+ "files": [
30
+ "ts_bundle",
31
+ "dist_ts_bundle",
32
+ "readme.md",
33
+ "license.md"
34
+ ]
35
+ }
package/readme.md ADDED
@@ -0,0 +1,176 @@
1
+ # @serve.zone/pallet-bundle
2
+
3
+ The install surface of Pallet's sealed control bundle, released from Pallet's repository with
4
+ Pallet's own version. An installer — Spark on fleet nodes, Onebox on its own host — uses it to
5
+
6
+ - download a pinned Pallet release and verify it with tspack,
7
+ - verify the extracted bundle: its control record, every executable's role and build provenance, the
8
+ component manifests and the notice and source inventories,
9
+ - write the service units Pallet's "Service unit contract" states, and read them back from the
10
+ service manager,
11
+ - run and supervise `pallet-control` modes over its `PALLET_CONTROL` process protocol.
12
+
13
+ Pallet is the source of truth for all of it. Pallet's own packaging runs this package's verifier over
14
+ every bundle it seals, so a release never disagrees with the version of this package that carries
15
+ the same version number.
16
+
17
+ ## Issue Reporting and Security
18
+
19
+ For reporting bugs, issues, or security vulnerabilities, please visit
20
+ [community.foss.global/](https://community.foss.global/). This is the central community hub for all
21
+ issue reporting. Developers who sign and comply with our contribution agreement and go through
22
+ identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull
23
+ Requests directly.
24
+
25
+ ## Install
26
+
27
+ ```sh
28
+ pnpm install @serve.zone/pallet-bundle
29
+ ```
30
+
31
+ The package runs under Node.js and Deno; it uses `node:` APIs and the global `fetch` only.
32
+
33
+ It reads its own version at runtime from the `package.json` beside its compiled modules
34
+ (`version.ts`, resolved relative to `import.meta.url`). Consume it as an npm dependency and do not
35
+ bundle it into another file: a bundler that inlines the modules loses that manifest, and
36
+ `palletBundleVersion` and every call that takes a pin (the release client and the verifiers) then fail. `deno compile`
37
+ keeps it: a compiled binary embeds each npm package it
38
+ uses with its `package.json`, whether the dependency comes from a `node_modules` directory
39
+ installed by pnpm or from Deno's own `nodeModulesDir: "auto"` install.
40
+
41
+ ## Pins
42
+
43
+ A release is selected only by its pin, the values a consumer compiles in:
44
+
45
+ ```typescript
46
+ import type { IPalletBundlePin } from '@serve.zone/pallet-bundle';
47
+
48
+ const pin: IPalletBundlePin = {
49
+ version: '35.3.0',
50
+ sourceCommit: '<the 40-hex commit of the v35.3.0 tag>',
51
+ manifestSha256: '<SHA-256 of that release\'s tspack-manifest.json>',
52
+ };
53
+ ```
54
+
55
+ Every entry point refuses a pin whose `version` differs from this package's own version
56
+ (`version_mismatch`): the inventory and contracts it states belong to that one Pallet version.
57
+ Upgrade the package and the pin together.
58
+
59
+ ## Download, extract and verify
60
+
61
+ ```typescript
62
+ import { PalletReleaseClient, extractPalletControlBundle } from '@serve.zone/pallet-bundle';
63
+
64
+ const client = new PalletReleaseClient();
65
+ const bundle = await client.run(pin, 'linux-amd64', '/opt/onebox/pallet', (download) =>
66
+ extractPalletControlBundle(download, 'linux-amd64', '/opt/onebox/pallet', pin, signal), signal);
67
+ // bundle.directory is a fresh private directory below /opt/onebox/pallet; the caller owns it.
68
+ console.log(bundle.executables.control.path, bundle.executables.control.sha256);
69
+ console.log(bundle.containerdManifestSha256, bundle.provenance.store.projectVersion);
70
+ ```
71
+
72
+ `PalletReleaseClient.run` resolves the release `v<version>` of `serve.zone/pallet` on
73
+ `https://code.foss.global`, requires its tag to name the pinned commit, verifies the release metadata
74
+ against the pinned manifest digest (tspack `verifyMetadata`), downloads the manifest, the checksums
75
+ and the target's archive into a private directory below the given parent, verifies the archive
76
+ (tspack `verifyBundle`) and hands the directory to the callback. It removes the download directory
77
+ when the callback settles. A release that exists without all of its assets answers
78
+ `release_pending` with the missing asset names.
79
+
80
+ `extractPalletControlBundle` extracts the target's archive with tspack `extractBundle`, then runs
81
+ `verifyPalletControlBundle` over it and removes the extraction again if that fails. For a bundle
82
+ that is already extracted, call `verifyPalletControlBundle(directory, sealedFiles, pin, target)`
83
+ with the file records of the pinned manifest.
84
+
85
+ The verifier checks, against the sealed records of the bundle's files:
86
+
87
+ - `control-build.json`: exactly its keys, Pallet's package name, the pinned version and commit, a
88
+ clean source, the target and the fixed host paths; every file it declares carries the sealed
89
+ digest and size, and every executable in the bundle is one it declares;
90
+ - the executables `pallet-control` starts by name (`pallet-control`, `pallet-smartdb`,
91
+ `pallet-runtime`, `pallet-guard`, `pallet-dns`, `pallet-vpn`) and their tsrust provenance: the
92
+ sealed digest, the owning project and binary, the target, a clean build, and for `pallet-runtime`
93
+ the pinned version and commit;
94
+ - the clock and containerd manifests, which list every file below their directories with digest,
95
+ size and mode, and the digests the control record pins for them and for the DNS and VPN notices;
96
+ - the notice trees (`native-notices/`, `notices/smartnftables/`) and the clock and containerd notice
97
+ and corresponding-source inventories: each manifest names exactly the files below it.
98
+
99
+ Refusals are `PalletBundleError` values with a fixed `code`; see `TPalletBundleErrorCode`.
100
+
101
+ ## Service units
102
+
103
+ ```typescript
104
+ import { SystemdUnit, SystemdUnitFile } from '@push.rocks/smartdaemon';
105
+ import {
106
+ createPalletGuardServiceDefinition, createPalletContainerdServiceDefinition,
107
+ createPalletNodeServiceDefinition, palletContainerdServiceSettingsMatch,
108
+ } from '@serve.zone/pallet-bundle';
109
+
110
+ const control = '/opt/onebox/pallet/current/pallet-control';
111
+ const guard = createPalletGuardServiceDefinition({ unitName: 'onebox-pallet-guard.service',
112
+ executable: control, workingDirectory: '/opt/onebox/pallet' });
113
+ const containerd = createPalletContainerdServiceDefinition({ unitName: 'onebox-pallet-containerd.service',
114
+ controlExecutable: control, workingDirectory: '/opt/onebox/pallet',
115
+ guardUnitName: guard.unitName, nodeUnitName: 'onebox-pallet-node.service' });
116
+ const node = createPalletNodeServiceDefinition({ unitName: 'onebox-pallet-node.service',
117
+ controlExecutable: control, workingDirectory: '/opt/onebox/pallet',
118
+ guardUnitName: guard.unitName, containerdUnitName: containerd.unitName });
119
+ ```
120
+
121
+ The definitions are `SystemdServiceDefinition` values of `@push.rocks/smartdaemon`; install them
122
+ with its `SystemdUnitFile`. The unit names and the install root are the installer's.
123
+
124
+ - The guard unit is a oneshot that runs `guard-recover` before `network-pre.target` and
125
+ `systemd-networkd.service`, which both require it. Install it only after the first
126
+ `guard-commission`. Its executable is `pallet-control` or an installer's own executable that
127
+ verifies the installation before it starts that mode.
128
+ - The containerd unit runs `containerd-serve` to the contract in Pallet's readme ("Pallet's own
129
+ containerd"). `palletContainerdServiceSettingsMatch` reads the loaded unit's settings, drop-ins
130
+ included, back against that contract.
131
+ - The node unit runs `runtime-unit`, the node lifetime as a unit's main process: null stdin, stopped
132
+ by SIGTERM, `KillMode=mixed`, restarted on failure by the service manager, after the guard and
133
+ containerd units. `palletNodeServiceSettingsMatch` reads it back.
134
+
135
+ ## Process supervisors
136
+
137
+ ```typescript
138
+ import { PalletControlOneshot, PalletControlLifetime } from '@serve.zone/pallet-bundle';
139
+
140
+ // A null-stdin oneshot: guard-recover, guard-commission, network-acquire, network-acquire-local, store-provision.
141
+ await new PalletControlOneshot({ binaryPath: control, binarySha256: bundle.executables.control.sha256 })
142
+ .run('store-provision', signal);
143
+
144
+ // A supervised lifetime held by a stdin pipe: enrollment-serve, enrollment-provision, runtime-serve.
145
+ const lifetime = new PalletControlLifetime({ binaryPath: control, binarySha256, mode: 'enrollment-serve' });
146
+ await lifetime.run(signal, async (running) => { /* talk to the enrollment socket */ });
147
+ ```
148
+
149
+ Both verify the executable's digest before every start, start it with a clean environment and `/`
150
+ as its working directory, read the `PALLET_CONTROL` lines of the mode's protocol and forward its
151
+ standard error line by line, bounded (`PalletControlStderr`). They never restart a child. A oneshot
152
+ succeeds only on `ready`, `stopped`, drained pipes and exit status 0. A lifetime runs the operation
153
+ while the child is `ready`; closing its stdin is the graceful stop, and a missed shutdown deadline
154
+ signals SIGTERM and then SIGKILL, which fails the lifetime as `shutdown_failed`. Refusals are
155
+ `PalletControlProcessError` values; `unsupported_kernel` carries the operator's remedy.
156
+
157
+ ## License and Legal Information
158
+
159
+ This repository contains open-source code licensed under the MIT License. A copy of the license is included in this package as `license.md`.
160
+
161
+ **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
162
+
163
+ ### Trademarks
164
+
165
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
166
+
167
+ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
168
+
169
+ ### Company Information
170
+
171
+ Task Venture Capital GmbH<br>
172
+ Registered at District Court Bremen HRB 35230 HB, Germany
173
+
174
+ For any legal inquiries or further information, please contact us via email at hello@task.vc.
175
+
176
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.