#!/usr/bin/env node /** * Publish-path rehearsal without publishing: verify the packed tarballs are * exactly what a consumer install needs. `pnpm pack` already produced the * bytes `pnpm publish` would upload; this script checks the payload * (coverage, concrete dependency versions, NO lifecycle install scripts — * this family has no install fallback on purpose), unpacks the entry plus * THIS host's platform tarball into a throwaway consumer OUTSIDE the repo, * byte-pins the installed binary against the workspace build it was packed * from, and drives the INSTALLED entry under plain `node` — resolution, * probe, and a real confinement world-proof through the installed launcher. * * On non-Linux hosts (no platform package exists) it instead proves the * documented degradation: resolution falls back to a nonexistent path and * the probe reports `unusable`. * * Usage: `node scripts/verify-packed-install.mjs [tarball-dir] [--current-platform-only]`. * The flag skips the all-platforms tarball-presence check for * per-architecture CI legs. `NALR_REQUIRE_LANDLOCK=1` makes an unenforcing * kernel a failure instead of a skipped world-proof (set on CI, where the * kernel is known). */ import crypto from 'node:crypto'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; import { entryDirs, packageDirs, platformDirs, readJson, root } from './repo.mjs'; const args = process.argv.slice(2); const currentPlatformOnly = args.includes('--current-platform-only'); const tarballDir = path.resolve(args.find((arg) => !arg.startsWith('--')) || path.join(root, 'dist', 'npm')); const entryPackageName = 'node-addon-landlock-run'; function tarballName(manifest) { if (manifest.name.startsWith('@')) { return `${manifest.name.slice(1).replace('/', '-')}-${manifest.version}.tgz`; } return `${manifest.name}-${manifest.version}.tgz`; } function tarballPath(manifest) { const tarball = path.join(tarballDir, tarballName(manifest)); if (!fs.existsSync(tarball)) { throw new Error(`missing packed tarball: ${tarball}`); } return tarball; } function run(command, commandArgs, options = {}) { const result = spawnSync(command, commandArgs, { cwd: options.cwd || root, stdio: 'inherit', env: { ...process.env, ...options.env }, }); if (result.error) throw result.error; if (result.status !== 0) { process.exit(result.status ?? 1); } } function runCapture(command, commandArgs) { const result = spawnSync(command, commandArgs, { cwd: root, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 }); if (result.error) throw result.error; if (result.status !== 0) { process.stderr.write(result.stderr); process.exit(result.status ?? 1); } return result.stdout; } function readPackedManifest(manifest) { return JSON.parse(runCapture('tar', ['-xOf', tarballPath(manifest), 'package/package.json'])); } function verifyPackedManifest(packed) { const lifecycle = ['preinstall', 'install', 'postinstall', 'prepare']; for (const script of lifecycle) { if (packed.scripts?.[script]) { throw new Error(`${packed.name}: packed manifest carries a "${script}" lifecycle script — this family has no install fallback`); } } for (const field of ['dependencies', 'optionalDependencies', 'peerDependencies']) { for (const [name, version] of Object.entries(packed[field] ?? {})) { if (version.includes('workspace:')) { throw new Error(`${packed.name}: packed ${field} still uses the workspace protocol: ${name}@${version}`); } } } } function sha256(file) { return crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex'); } function packageInstallDir(packageName) { return path.join(tempRoot, 'node_modules', ...packageName.split('/')); } function unpackTarball(manifest) { const extractRoot = fs.mkdtempSync(path.join(tempRoot, 'extract-')); run('tar', ['-xzf', tarballPath(manifest), '-C', extractRoot]); const source = path.join(extractRoot, 'package'); const destination = packageInstallDir(manifest.name); fs.rmSync(destination, { recursive: true, force: true }); fs.mkdirSync(path.dirname(destination), { recursive: true }); fs.renameSync(source, destination); fs.rmSync(extractRoot, { recursive: true, force: true }); console.log(`Unpacked ${manifest.name} -> ${path.relative(tempRoot, destination)}`); } const manifests = packageDirs().map((dir) => ({ dir, manifest: readJson(path.join(root, dir, 'package.json')) })); const entryManifest = manifests.find(({ manifest }) => manifest.name === entryPackageName)?.manifest; if (!entryManifest) throw new Error(`missing source manifest for ${entryPackageName}`); const hostPlatform = `${process.platform}-${process.arch}`; const currentPlatformEntry = manifests.find( ({ dir, manifest }) => platformDirs().includes(dir) && manifest.name === `${entryPackageName}-${hostPlatform}`, ); // Payload checks: every expected tarball exists (full mode), the packed // entry's optional-dependency set names exactly the platform packages, and // no packed manifest carries workspace versions or install lifecycle. const expectedTarballs = currentPlatformOnly ? manifests.filter(({ dir }) => entryDirs().includes(dir) || dir === currentPlatformEntry?.dir) : manifests; for (const { manifest } of expectedTarballs) { tarballPath(manifest); } const packedEntry = readPackedManifest(entryManifest); const platformPackageNames = manifests .filter(({ dir }) => platformDirs().includes(dir)) .map(({ manifest }) => manifest.name) .sort(); const optionalNames = Object.keys(packedEntry.optionalDependencies || {}).sort(); if (optionalNames.join('\n') !== platformPackageNames.join('\n')) { throw new Error(`packed entry optionalDependencies mismatch\nactual:\n${optionalNames.join('\n')}\nexpected:\n${platformPackageNames.join('\n')}`); } for (const { manifest } of expectedTarballs) { verifyPackedManifest(readPackedManifest(manifest)); } // Throwaway ESM consumer, built from local tarballs only — no registry. const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'nalr-packed-install-')); fs.writeFileSync( path.join(tempRoot, 'package.json'), `${JSON.stringify({ name: 'nalr-packed-install-check', version: '0.0.0', private: true, type: 'module' }, null, 2)}\n`, ); console.log(`Verifying packed install in ${tempRoot}`); unpackTarball(entryManifest); if (currentPlatformEntry) { unpackTarball(currentPlatformEntry.manifest); // Byte-pin: the installed binary must be the workspace build it was packed // from — any divergence means the tarball did not carry the built bytes. const prebuilds = readJson(path.join(root, currentPlatformEntry.dir, 'prebuilds.json')); for (const binary of prebuilds.binaries) { const workspaceFile = path.join(root, currentPlatformEntry.dir, binary.path); const installedFile = path.join(packageInstallDir(currentPlatformEntry.manifest.name), binary.path); if (sha256(workspaceFile) !== sha256(installedFile)) { throw new Error(`installed ${binary.path} differs from the workspace build it was packed from`); } console.log(`Byte-pinned ${binary.path} against the workspace build`); } } else if (process.platform === 'linux') { throw new Error(`linux host without a platform package in the matrix: ${hostPlatform}`); } // Drive the INSTALLED entry under plain node: resolution, probe, and (on an // enforcing kernel) a real confinement world-proof through the installed // launcher. const driver = path.join(tempRoot, 'driver.mjs'); fs.writeFileSync(driver, ` import assert from 'node:assert/strict'; import { spawnSync } from 'node:child_process'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { grantArgs, launcherPath, probe } from 'node-addon-landlock-run'; const requireLandlock = process.env.NALR_REQUIRE_LANDLOCK === '1'; const platformPackage = 'node-addon-landlock-run-' + process.platform + '-' + process.arch; const resolved = launcherPath(); assert.ok(path.isAbsolute(resolved), 'launcherPath must be absolute'); assert.ok(resolved.includes(path.join(...platformPackage.split('/'))), 'launcherPath must point into the platform package: ' + resolved); if (process.platform === 'linux') { assert.ok(fs.existsSync(resolved), 'installed launcher missing at ' + resolved); try { fs.accessSync(resolved, fs.constants.X_OK); } catch { throw new Error('installed launcher is not executable — the pack path stripped the mode bit: ' + resolved); } const enforcement = probe(resolved); console.log('probe through the installed launcher: ' + enforcement); if (enforcement === 'unusable') { if (requireLandlock) throw new Error('NALR_REQUIRE_LANDLOCK=1 but the probe reports unusable'); console.log('kernel does not enforce Landlock — skipping the confinement world-proof'); } else { const work = fs.mkdtempSync(path.join(os.tmpdir(), 'nalr-confine-')); const denied = path.join(work, 'denied.txt'); const deniedRun = spawnSync(resolved, [...grantArgs({ readOnly: ['/'] }), '--', '/bin/sh', '-c', 'echo x > ' + denied], { encoding: 'utf8' }); assert.notEqual(deniedRun.status, 0, 'write outside the grants must fail'); assert.ok(!fs.existsSync(denied), 'denied write must not land on disk'); const granted = path.join(work, 'granted.txt'); const grantedRun = spawnSync(resolved, [...grantArgs({ readOnly: ['/'], readWrite: [work] }), '--', '/bin/sh', '-c', 'echo ok > ' + granted], { encoding: 'utf8' }); assert.equal(grantedRun.status, 0, 'granted write must succeed: ' + grantedRun.stderr); assert.equal(fs.readFileSync(granted, 'utf8').trim(), 'ok'); console.log('confinement world-proof passed through the installed launcher'); } } else { assert.ok(!fs.existsSync(resolved), 'no platform package exists for this host — the fallback path must not exist'); assert.equal(probe(resolved), 'unusable'); console.log('non-linux host: fallback resolution and unusable probe verified'); } `); run(process.execPath, [driver], { cwd: tempRoot }); console.log('Packed install verification passed.');