From e2358992ec3170f6ca9346f3a0053a3b5d16cf86 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Mon, 24 Aug 2026 13:04:31 +0200 Subject: [PATCH 1/4] Integrate `LavaMoat/harden` Add the `LavaMoat/harden` setup, based on https://github.com/MetaMask/metamask-module-template/pull/335. This introduces a `lavamoat/` directory with config files containing secure defaults for running scripts (`scripts.strict.json`, `scripts.loose.json`, and `scripts.skills.json`), plus a banned environment variable list, and a Yarn runner plugin that applies them. The plugin wraps every `yarn run` script with Node's permission model, restricting filesystem, network, child process, worker, addon, WASI, and inspector access, filters sensitive environment variables out of the script environment, and moves `node_modules/.bin` to the end of `PATH` to prevent bin confusion attacks. Each workspace now declares `scriptsConfig.#default` pointing at the strict config, enforced by a new Yarn constraint. Yarn hardened mode is enabled, `.npmrc` and `.yarnrc` are added to make accidental npm or Yarn 1 usage safe, and Node is pinned to 26 since the permission model requires a recent runtime. --- .npmrc | 5 + .nvmrc | 2 +- .oxfmtrc.json | 2 +- .yarnrc | 2 + .yarnrc.yml | 15 +- lavamoat/.env.ban.json | 9 + lavamoat/.runner-plugin.cjs | 370 ++++++++++++++++++ lavamoat/plugin-allow-scripts.cjs | 17 + lavamoat/scripts.loose.json | 16 + lavamoat/scripts.skills.json | 14 + lavamoat/scripts.strict.json | 14 + package.json | 11 + packages/account-tree-controller/package.json | 3 + packages/accounts-controller/package.json | 3 + packages/address-book-controller/package.json | 3 + packages/ai-controllers/package.json | 3 + packages/analytics-controller/package.json | 3 + .../package.json | 3 + packages/announcement-controller/package.json | 3 + packages/app-metadata-controller/package.json | 3 + packages/approval-controller/package.json | 3 + packages/assets-controller/package.json | 3 + packages/assets-controllers/package.json | 3 + .../authenticated-user-storage/package.json | 3 + packages/base-controller/package.json | 3 + packages/base-data-service/package.json | 3 + packages/bitcoin-regtest-up/package.json | 3 + packages/bridge-controller/package.json | 3 + .../bridge-status-controller/package.json | 3 + packages/build-utils/package.json | 3 + .../chain-agnostic-permission/package.json | 3 + packages/chomp-api-service/package.json | 3 + packages/claims-controller/package.json | 3 + packages/client-controller/package.json | 3 + packages/client-utils/package.json | 3 + packages/compliance-controller/package.json | 3 + packages/composable-controller/package.json | 3 + .../config-registry-controller/package.json | 3 + packages/connectivity-controller/package.json | 3 + packages/controller-utils/package.json | 3 + packages/core-backend/package.json | 3 + packages/cryptography/package.json | 3 + packages/delegation-controller/package.json | 3 + packages/earn-controller/package.json | 3 + packages/eip-5792-middleware/package.json | 3 + .../package.json | 3 + .../package.json | 3 + packages/eth-block-tracker/package.json | 3 + packages/eth-json-rpc-middleware/package.json | 3 + packages/eth-json-rpc-provider/package.json | 3 + packages/foundryup/package.json | 3 + packages/gas-fee-controller/package.json | 3 + .../gator-permissions-controller/package.json | 3 + packages/geolocation-controller/package.json | 3 + packages/java-tron-up/package.json | 3 + packages/json-rpc-engine/package.json | 3 + .../json-rpc-middleware-stream/package.json | 3 + packages/keyring-controller/package.json | 3 + packages/kyc-controller/package.json | 3 + packages/local-node-utils/package.json | 3 + packages/logging-controller/package.json | 3 + packages/message-manager/package.json | 3 + packages/messenger-cli/package.json | 3 + packages/messenger/package.json | 3 + .../package.json | 3 + .../package.json | 3 + .../money-account-controller/package.json | 3 + .../package.json | 3 + packages/money-account-utils/package.json | 3 + .../multichain-account-service/package.json | 3 + .../multichain-api-middleware/package.json | 3 + .../package.json | 3 + .../package.json | 3 + packages/name-controller/package.json | 3 + .../package.json | 3 + packages/network-controller/package.json | 3 + .../package.json | 3 + .../package.json | 3 + packages/package-template/package.json | 3 + packages/passkey-controller/package.json | 3 + packages/permission-controller/package.json | 3 + .../permission-log-controller/package.json | 3 + packages/perps-controller/package.json | 3 + packages/phishing-controller/package.json | 3 + packages/platform-api-docs/package.json | 3 + packages/polling-controller/package.json | 3 + packages/preferences-controller/package.json | 3 + .../profile-metrics-controller/package.json | 3 + packages/profile-sync-controller/package.json | 3 + packages/ramps-controller/package.json | 3 + packages/rate-limit-controller/package.json | 3 + packages/react-data-query/package.json | 3 + .../package.json | 3 + packages/sample-controllers/package.json | 3 + .../package.json | 3 + .../selected-network-controller/package.json | 3 + packages/sentinel-api-service/package.json | 3 + packages/shield-controller/package.json | 3 + packages/signature-controller/package.json | 3 + .../package.json | 3 + packages/snap-account-service/package.json | 3 + packages/social-controllers/package.json | 3 + .../solana-test-validator-up/package.json | 3 + packages/stellar-quickstart-up/package.json | 3 + packages/storage-service/package.json | 3 + packages/subscription-controller/package.json | 3 + packages/transaction-controller/package.json | 3 + .../transaction-pay-controller/package.json | 3 + .../user-operation-controller/package.json | 3 + packages/utils/package.json | 3 + packages/wallet-cli/package.json | 3 + packages/wallet-framework-docs/package.json | 3 + packages/wallet/package.json | 3 + yarn.config.cjs | 6 + 114 files changed, 782 insertions(+), 4 deletions(-) create mode 100644 .npmrc create mode 100644 .yarnrc create mode 100644 lavamoat/.env.ban.json create mode 100755 lavamoat/.runner-plugin.cjs create mode 100644 lavamoat/plugin-allow-scripts.cjs create mode 100644 lavamoat/scripts.loose.json create mode 100644 lavamoat/scripts.skills.json create mode 100644 lavamoat/scripts.strict.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000000..15d263ad343 --- /dev/null +++ b/.npmrc @@ -0,0 +1,5 @@ +## Make using npm impossible. +offline=true + +## Ignore scripts just in case. +ignore-scripts=true diff --git a/.nvmrc b/.nvmrc index b009dfb9d9f..6f4247a6255 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -lts/* +26 diff --git a/.oxfmtrc.json b/.oxfmtrc.json index b5e76ee140b..850fd7035e5 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -16,5 +16,5 @@ }, "tabWidth": 2, "trailingComma": "all", - "ignorePatterns": [".yarnrc.yml", "merged-packages/**"] + "ignorePatterns": [".yarnrc.yml", "merged-packages/**", "lavamoat"] } diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 00000000000..c136bd0fa11 --- /dev/null +++ b/.yarnrc @@ -0,0 +1,2 @@ +## Ignore scripts in case yarn1 is accidentally used. +ignore-scripts true diff --git a/.yarnrc.yml b/.yarnrc.yml index 4c0e4f39a5a..461df016a73 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -7,10 +7,20 @@ compressionLevel: mixed enableGlobalCache: false +# Hardened mode to validate lockfile content against remote registries. +enableHardenedMode: true + +# Disable Yarn's mirror feature to avoid writing to the global cache. +enableMirror: false + enableScripts: false enableTelemetry: false +# Despite `enableGlobalCache` and `enableMirror` being `false`, Yarn is still +# writing to the global folder. +globalFolder: .yarn/global + logFilters: - code: YN0004 level: discard @@ -28,6 +38,7 @@ npmPreapprovedPackages: - "@metamask-previews/*" - "@lavamoat/*" +# Protect the runtime of calls to "yarn run" scripts using a local plugin. plugins: - - path: .yarn/plugins/@yarnpkg/plugin-allow-scripts.cjs - spec: "https://raw.githubusercontent.com/LavaMoat/LavaMoat/main/packages/yarn-plugin-allow-scripts/bundles/@yarnpkg/plugin-allow-scripts.js" + - path: ./lavamoat/plugin-allow-scripts.cjs + - path: ./lavamoat/.runner-plugin.cjs diff --git a/lavamoat/.env.ban.json b/lavamoat/.env.ban.json new file mode 100644 index 00000000000..4d4ed65eac9 --- /dev/null +++ b/lavamoat/.env.ban.json @@ -0,0 +1,9 @@ +[ + "SESSION", + "SSH", + "KEY", + "TOKEN", + "SECRET", + "PASSWORD", + "AUTH" +] diff --git a/lavamoat/.runner-plugin.cjs b/lavamoat/.runner-plugin.cjs new file mode 100755 index 00000000000..9acee99fda5 --- /dev/null +++ b/lavamoat/.runner-plugin.cjs @@ -0,0 +1,370 @@ +/** + * Yarn 4 plugin for script environment hardening. + * + * @module + */ + +/** @typedef {NonNullable} WrapScriptExecutionHook */ + +/* global makeRunScriptWrapper */ + +/** + * Yarn 4 plugin factory for wrapScriptExecution hook. + * + * @param {any} require - Yarn's require function + * @returns {{ hooks: { wrapScriptExecution: Function } }} + */ +module.exports = { + name: '@yarnpkg/plugin-runner', + factory: function (/** @type {NodeJS.Require} */ require) { + const { tmpdir } = require('node:os') + return { + hooks: { + /** @type {WrapScriptExecutionHook} */ + wrapScriptExecution: async ( + executor, + project, + locator, + scriptName, + extra + ) => { + const path = require('node:path') + const fs = require('node:fs') + const workspace = project.tryWorkspaceByLocator(locator) + + if (!workspace) { + // a script is being executed outside of a workspace context, so we + // can't apply any custom logic. + // This is the case when a postinstal is running. + + // "Do nothing" - return the original executor immediately + // without running any custom plugin logic or reading manifests. + // TODO: implement wrapping these scripts with reasonable defaults + return executor + } + + const pkgJson = workspace.manifest.raw + const binFolder = + extra.env.BERRY_BIN_FOLDER || `node_modules${path.sep}.bin` + + const wrapper = makeRunScriptWrapper( + { + scriptName, + scriptPayload: extra.script, + projectRoot: extra.cwd, + pathBinMatcher: (fragment) => { + return fragment.endsWith(binFolder) + }, + customizePermissionsConfig: addMandatoryReads, + readScriptsConfig: () => { + return pkgJson.scriptsConfig + }, + }, + { + readFileSync: fs.readFileSync, + pathJoin: path.join, + pathDelimiter: path.delimiter, + tmpdir, + realpathSync: fs.realpathSync, + } + ) + + // extra.env is a reference to the mutable object, but a different variable + // containing that reference is used within execute, so we must amend not + // replace it. + const newEnv = wrapper.processEnv(extra.env) + for (const key of Object.keys(extra.env)) { + delete extra.env[key] + } + Object.assign(extra.env, newEnv) + return executor + }, + }, + } + }, +} + +/** + * @param {Record} configOptions + * @param {NodeJS.ProcessEnv} _env + */ +function addMandatoryReads(configOptions, _env) { + if (!configOptions['--permission']) { + return + } + configOptions['--allow-fs-tmp'] = true // yarn always uses tmp dirs. +} + +;; +/// + +/** + * @param {MakeRunScriptWrapperOptions} param0 + * @param {MakeRunScriptWrapperIO} param1 + * @returns {MakeRunScriptWrapper} + */ +function makeRunScriptWrapper( + { + scriptName, + scriptPayload: _scriptPayload, // might be useful to read in the future + projectRoot, + pathBinMatcher, + customizePermissionsConfig, + readScriptsConfig, + }, + { readFileSync, pathJoin, pathDelimiter, tmpdir, realpathSync } +) { + const DEFAULT_PERMISSION_KEY = '#default' + + /** @param {string} filePath */ + function readJsonFile(filePath) { + return JSON.parse(readFileSync(filePath, 'utf8')) + } + + /** + * @param {object} opts + * @param {Record | undefined} opts.scriptsConfig + * @param {string} [opts.scriptName] + * @param {string} opts.projectRoot + */ + function readConfig({ + scriptsConfig, + scriptName = DEFAULT_PERMISSION_KEY, + projectRoot, + }) { + if (!scriptsConfig) { + return {} + } + const configName = + scriptsConfig[scriptName] || scriptsConfig[DEFAULT_PERMISSION_KEY] + + // config needs to be optional, because it's opt-in first and specifying a default turns it opt-out. + if (!configName) { + return {} + } + const configPath = pathJoin(projectRoot, configName) + let conf + try { + conf = readJsonFile(configPath) + if (typeof conf !== 'object' || conf === null) { + throw Error(`Expected an object, got ${typeof conf}`) + } + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + throw Error( + `[LavaMoat] Error loading script config file "${configPath}": ${message}`, + { cause: err } + ) + } + return conf + } + + /** + * Adds features we'd want in Node.js permissions model and intend to + * eventually upstream + * + * @param {ConfigOptions} configOptions + * @param {NodeJS.ProcessEnv} env + * @returns {void} + */ + function permissionsModelCompatibilityExtensions(configOptions, env) { + // 1. support env variables as values in allow-fs-* + /** + * @param {string} value + * @returns {string} + */ + const replaceEnvVar = (value) => { + const envVarMatch = value.match(/^\$([A-Z_][A-Z0-9_]*)$/i) + if (envVarMatch) { + const envVarName = envVarMatch[1] + if (env[envVarName] !== undefined) { + return env[envVarName] + } else { + console.error( + `[LavaMoat] Environment variable "${envVarName}" referenced in config but not found in environment` + ) + } + } + return value + } + + for (const key of ['--allow-fs-read', '--allow-fs-write']) { + if (Array.isArray(configOptions[key])) { + configOptions[key] = configOptions[key].map(replaceEnvVar) + } + } + + // 2. tmp write - crossplatform + if (configOptions['--allow-fs-tmp'] === true) { + delete configOptions['--allow-fs-tmp'] + if (configOptions['--allow-fs-write']) { + if (typeof configOptions['--allow-fs-write'] === 'string') { + configOptions['--allow-fs-write'] = [ + configOptions['--allow-fs-write'], + ] + } + if (configOptions['--allow-fs-write'] === true) { + return // none of this matters + } + } else { + // do this for both undefined and false + configOptions['--allow-fs-write'] = [] + } + const tmp = tmpdir() + configOptions['--allow-fs-write'].push(tmp) + // because macos is being weird + const tmpRealPath = realpathSync(tmp) + if (tmpRealPath !== tmp) { + configOptions['--allow-fs-write'].push(tmpRealPath) + } + } + } + + /** @param {ConfigOptions} configOptions */ + function makeFlagsFromConfig(configOptions) { + return Object.entries(configOptions) + .map(([arg, value]) => { + if (typeof value === 'boolean') { + return value ? arg : '' + } else if (Array.isArray(value)) { + return value.map((v) => `${arg}="${v}"`).join(' ') + } else { + return `${arg}="${value}"` + } + }) + .filter(Boolean) + .join(' ') + } + + /** + * Checks the config obtained from package.json and puts it in as NODE_OPTIONS + * + * @param {string | undefined} existingOptions + * @param {ConfigOptions} configOptions + * @param {NodeJS.ProcessEnv} env + */ + function installNodeOptions(existingOptions, configOptions, env) { + if (!configOptions) { + return existingOptions || '' + } + + customizePermissionsConfig(configOptions, env) + + permissionsModelCompatibilityExtensions(configOptions, env) + + const confOption = makeFlagsFromConfig(configOptions) + + return `${existingOptions || ''} ${confOption.trim()}`.trim() + } + + /** + * Filter environment variables based on ban keywords + * + * @param {NodeJS.ProcessEnv} env + * @param {string} lavamoatDir + * @returns {NodeJS.ProcessEnv} + */ + function filterEnv(env, lavamoatDir) { + const banFilePath = pathJoin(lavamoatDir, '.env.ban.json') + let banConfig + + try { + banConfig = readJsonFile(banFilePath) + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + console.error( + `[LavaMoat] Warning: Failed to read .env.ban.json: ${message}.` + ) + return env + } + let banKeywords = [] + try { + if (Array.isArray(banConfig)) { + banKeywords.push(...banConfig) + } else { + throw Error(`Expected .env.ban.json to contain an array of keywords`) + } + } catch (err) { + const message = err instanceof Error ? err.message : String(err) + console.error( + `[LavaMoat] Warning: Failed to read .env.ban.json: ${message}.` + ) + return env + } + + /** @type {NodeJS.ProcessEnv} */ + const filteredEnv = {} + const bannedEnv = [] + banKeywords = banKeywords.map((keyword) => keyword.toLowerCase()) + for (const [key, value] of Object.entries(env)) { + if ( + !key.toLowerCase().startsWith('npm_config') && + banKeywords.some((keyword) => key.toLowerCase().includes(keyword)) + ) { + bannedEnv.push(key) + } else { + filteredEnv[key] = value + } + } + if (bannedEnv.length > 0) { + console.error( + `[LavaMoat] Warning: The following environment variables were banned: ${bannedEnv.join(', ')}` + ) + } + return filteredEnv + } + + /** @param {string} PATH */ + function envPathOpinions(PATH) { + const pathFragments = PATH.split(pathDelimiter) + // This is to eliminate bin confusion attacks. + // Find node_modules/.bin and remove it, put it on the end that gets looked up last when looking for a name in the path. + + /** @type {string[]} */ + const filteredFragments = [] + /** @type {string[]} */ + const nodeModulesBinFragments = [] + + for (const fragment of pathFragments) { + if (pathBinMatcher(fragment)) { + nodeModulesBinFragments.push(fragment) + } else { + filteredFragments.push(fragment) + } + } + // Why would there be multiple bin fragments? In a npm workspace, local bin and workspace root bin is added + filteredFragments.push(...nodeModulesBinFragments) + return filteredFragments.join(pathDelimiter) + } + + return { + processEnv: (existingEnv) => { + const scriptsConfig = readScriptsConfig(projectRoot) + const config = readConfig({ + scriptsConfig, + scriptName, + projectRoot, + }) + + // Smell: Windows environment variables are case-insensitive, but Node's process.env + // might expose it as 'Path' instead of 'PATH'. Checking both ensures it doesn't get wiped out. + + const existingPath = existingEnv.PATH || existingEnv.Path || '' + + const lavamoatDir = pathJoin(projectRoot, 'lavamoat') + + const fixedEnv = { + ...filterEnv(existingEnv, lavamoatDir), + PATH: envPathOpinions(existingPath), + NODE_OPTIONS: installNodeOptions( + existingEnv.NODE_OPTIONS, + config.nodeOptions, + existingEnv + ), + } + return fixedEnv + }, + } +} + + diff --git a/lavamoat/plugin-allow-scripts.cjs b/lavamoat/plugin-allow-scripts.cjs new file mode 100644 index 00000000000..fbd0f019daf --- /dev/null +++ b/lavamoat/plugin-allow-scripts.cjs @@ -0,0 +1,17 @@ +//prettier-ignore +module.exports = { +name: "@yarnpkg/plugin-allow-scripts", +factory: function (/** @type {(arg0: string) => { execute: any; }} */ require) { + const { execute } = require(`@yarnpkg/shell`); + return { + hooks: { + afterAllInstalled: async () => { + const exitCode = await execute('yarn run allow-scripts') + if (exitCode !== 0) { + process.exit(exitCode) + } + }, + }, + } + } +}; diff --git a/lavamoat/scripts.loose.json b/lavamoat/scripts.loose.json new file mode 100644 index 00000000000..d255c351fbb --- /dev/null +++ b/lavamoat/scripts.loose.json @@ -0,0 +1,16 @@ +{ + "notes": "Should prevent basic malicious behavior of writing to locations outside the project and sending network requests, but not break any of the advanced packages in use. Everything below the net permission can be used to bypass the restrictions by a more sophisticated attacker. The warnings are suppressed. You should strive to deny as many native capabilities as possible and limit the fs-read to not have access to your entire home folder.", + "nodeOptions": { + "--permission": true, + "--allow-fs-read": ["/", "$npm_config_prefix", "$npm_config_userconfig"], + "--allow-fs-write": ["./"], + "--allow-fs-tmp": true, + "--allow-net": false, + "--allow-child-process": true, + "--allow-worker": true, + "--allow-addons": true, + "--allow-wasi": true, + "--allow-inspector": false, + "--disable-warning": "SecurityWarning" + } +} diff --git a/lavamoat/scripts.skills.json b/lavamoat/scripts.skills.json new file mode 100644 index 00000000000..db0d36cf7e3 --- /dev/null +++ b/lavamoat/scripts.skills.json @@ -0,0 +1,14 @@ +{ + "notes": "Should prevent basic malicious behavior of writing to locations outside the project and sending network requests, but not break any of the advanced packages in use. Everything below the net permission can be used to bypass the restrictions by a more sophisticated attacker.", + "nodeOptions": { + "--permission": true, + "--allow-fs-read": ["./"], + "--allow-fs-write": ["./"], + "--allow-child-process": true, + "--allow-net": false, + "--allow-worker": false, + "--allow-addons": false, + "--allow-wasi": false, + "--allow-inspector": false + } +} diff --git a/lavamoat/scripts.strict.json b/lavamoat/scripts.strict.json new file mode 100644 index 00000000000..40a815933e5 --- /dev/null +++ b/lavamoat/scripts.strict.json @@ -0,0 +1,14 @@ +{ + "notes": "Denies all powerful IO capabilities that a linter script should not need. If a script needs more permissions, copy this file and edit.", + "nodeOptions": { + "--permission": true, + "--allow-fs-read": ["./"], + "--allow-fs-write": ["./"], + "--allow-child-process": false, + "--allow-net": false, + "--allow-worker": false, + "--allow-addons": false, + "--allow-wasi": false, + "--allow-inspector": false + } +} diff --git a/package.json b/package.json index 9683a6441f0..6824772ac75 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,13 @@ "simple-git-hooks": { "pre-push": "yarn lint" }, + "devEngines": { + "packageManager": { + "name": "yarn", + "version": ">=4.16.0+sha256.ba05224324578801b9cc98170d64aa50b9a36733b440fb0942306da3fbbdc7d1", + "onFail": "error" + } + }, "engines": { "node": "^22.14.0 || ^24" }, @@ -134,5 +141,9 @@ "@metamask/network-controller>@metamask/config-registry-controller>@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography>keccak": false, "@metamask/network-controller>@metamask/config-registry-controller>@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography>secp256k1": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json", + "skills:postinstall": "lavamoat/scripts.skills.json" } } diff --git a/packages/account-tree-controller/package.json b/packages/account-tree-controller/package.json index a1f9649a9eb..718d72d1287 100644 --- a/packages/account-tree-controller/package.json +++ b/packages/account-tree-controller/package.json @@ -88,5 +88,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/accounts-controller/package.json b/packages/accounts-controller/package.json index b801b1185ac..ee9ac08c528 100644 --- a/packages/accounts-controller/package.json +++ b/packages/accounts-controller/package.json @@ -90,5 +90,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/address-book-controller/package.json b/packages/address-book-controller/package.json index 6c85e5fb758..9ac5b2da1d0 100644 --- a/packages/address-book-controller/package.json +++ b/packages/address-book-controller/package.json @@ -70,5 +70,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/ai-controllers/package.json b/packages/ai-controllers/package.json index 67b5a0ba9d8..16fc97a82ce 100644 --- a/packages/ai-controllers/package.json +++ b/packages/ai-controllers/package.json @@ -69,5 +69,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/analytics-controller/package.json b/packages/analytics-controller/package.json index 2a5bf977690..5817c3345d5 100644 --- a/packages/analytics-controller/package.json +++ b/packages/analytics-controller/package.json @@ -72,5 +72,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/analytics-data-regulation-controller/package.json b/packages/analytics-data-regulation-controller/package.json index e75435104f6..5e3db847995 100644 --- a/packages/analytics-data-regulation-controller/package.json +++ b/packages/analytics-data-regulation-controller/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/announcement-controller/package.json b/packages/announcement-controller/package.json index f1d0499af82..184f37cc0f1 100644 --- a/packages/announcement-controller/package.json +++ b/packages/announcement-controller/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/app-metadata-controller/package.json b/packages/app-metadata-controller/package.json index dead4d9d738..c302cdcd04e 100644 --- a/packages/app-metadata-controller/package.json +++ b/packages/app-metadata-controller/package.json @@ -66,5 +66,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/approval-controller/package.json b/packages/approval-controller/package.json index 2b37528c6fd..a910c7b2094 100644 --- a/packages/approval-controller/package.json +++ b/packages/approval-controller/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/assets-controller/package.json b/packages/assets-controller/package.json index fd8ad532db8..4f28fdff5cc 100644 --- a/packages/assets-controller/package.json +++ b/packages/assets-controller/package.json @@ -99,5 +99,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/assets-controllers/package.json b/packages/assets-controllers/package.json index f4472fbf94a..5ceda09c809 100644 --- a/packages/assets-controllers/package.json +++ b/packages/assets-controllers/package.json @@ -129,5 +129,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/authenticated-user-storage/package.json b/packages/authenticated-user-storage/package.json index 93ece0483d7..c4f4f0c014b 100644 --- a/packages/authenticated-user-storage/package.json +++ b/packages/authenticated-user-storage/package.json @@ -72,5 +72,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/base-controller/package.json b/packages/base-controller/package.json index 70bfd667219..d0a3a8ccc20 100644 --- a/packages/base-controller/package.json +++ b/packages/base-controller/package.json @@ -66,5 +66,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/base-data-service/package.json b/packages/base-data-service/package.json index 6f4774bbcab..4c99c476e60 100644 --- a/packages/base-data-service/package.json +++ b/packages/base-data-service/package.json @@ -78,5 +78,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/bitcoin-regtest-up/package.json b/packages/bitcoin-regtest-up/package.json index 91fa0ebba96..ff3094896fe 100644 --- a/packages/bitcoin-regtest-up/package.json +++ b/packages/bitcoin-regtest-up/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/bridge-controller/package.json b/packages/bridge-controller/package.json index b0e915edd03..5f481082a0c 100644 --- a/packages/bridge-controller/package.json +++ b/packages/bridge-controller/package.json @@ -95,5 +95,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/bridge-status-controller/package.json b/packages/bridge-status-controller/package.json index ac2781e9039..5809a331cd4 100644 --- a/packages/bridge-status-controller/package.json +++ b/packages/bridge-status-controller/package.json @@ -84,5 +84,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/build-utils/package.json b/packages/build-utils/package.json index 5f491616ce5..e24f99cc2c7 100644 --- a/packages/build-utils/package.json +++ b/packages/build-utils/package.json @@ -66,5 +66,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/chain-agnostic-permission/package.json b/packages/chain-agnostic-permission/package.json index 33e1ec93f70..cb183af41a2 100644 --- a/packages/chain-agnostic-permission/package.json +++ b/packages/chain-agnostic-permission/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/chomp-api-service/package.json b/packages/chomp-api-service/package.json index 5f008fec4b0..a48a6bbf1d6 100644 --- a/packages/chomp-api-service/package.json +++ b/packages/chomp-api-service/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/claims-controller/package.json b/packages/claims-controller/package.json index e2ebe62c529..fcdd359220e 100644 --- a/packages/claims-controller/package.json +++ b/packages/claims-controller/package.json @@ -75,5 +75,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/client-controller/package.json b/packages/client-controller/package.json index 10b713c57bb..7dd1ca95aa4 100644 --- a/packages/client-controller/package.json +++ b/packages/client-controller/package.json @@ -69,5 +69,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/client-utils/package.json b/packages/client-utils/package.json index a8f36866af1..c927949dcdc 100644 --- a/packages/client-utils/package.json +++ b/packages/client-utils/package.json @@ -75,5 +75,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/compliance-controller/package.json b/packages/compliance-controller/package.json index 603d700caef..5715f0c9f4f 100644 --- a/packages/compliance-controller/package.json +++ b/packages/compliance-controller/package.json @@ -72,5 +72,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/composable-controller/package.json b/packages/composable-controller/package.json index 72dd6f9b43b..5a2fb5150fc 100644 --- a/packages/composable-controller/package.json +++ b/packages/composable-controller/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/config-registry-controller/package.json b/packages/config-registry-controller/package.json index a71704203d3..d301904fc33 100644 --- a/packages/config-registry-controller/package.json +++ b/packages/config-registry-controller/package.json @@ -78,5 +78,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/connectivity-controller/package.json b/packages/connectivity-controller/package.json index db14eb409be..84561a1543e 100644 --- a/packages/connectivity-controller/package.json +++ b/packages/connectivity-controller/package.json @@ -69,5 +69,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/controller-utils/package.json b/packages/controller-utils/package.json index dbe23f24113..03d40239b4a 100644 --- a/packages/controller-utils/package.json +++ b/packages/controller-utils/package.json @@ -84,5 +84,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/core-backend/package.json b/packages/core-backend/package.json index b75ec2eefca..3914bdf862a 100644 --- a/packages/core-backend/package.json +++ b/packages/core-backend/package.json @@ -78,5 +78,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/cryptography/package.json b/packages/cryptography/package.json index 6e7e184f1c8..4de174c125d 100644 --- a/packages/cryptography/package.json +++ b/packages/cryptography/package.json @@ -65,5 +65,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/delegation-controller/package.json b/packages/delegation-controller/package.json index 00f24efa5b5..2752cbf5846 100644 --- a/packages/delegation-controller/package.json +++ b/packages/delegation-controller/package.json @@ -70,5 +70,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/earn-controller/package.json b/packages/earn-controller/package.json index 2b0f3fa788a..eeca775a6d7 100644 --- a/packages/earn-controller/package.json +++ b/packages/earn-controller/package.json @@ -77,5 +77,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/eip-5792-middleware/package.json b/packages/eip-5792-middleware/package.json index 6339b22c2ca..a56be52b17f 100644 --- a/packages/eip-5792-middleware/package.json +++ b/packages/eip-5792-middleware/package.json @@ -74,5 +74,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/eip-7702-internal-rpc-middleware/package.json b/packages/eip-7702-internal-rpc-middleware/package.json index 8bc21bf7f9e..c6756a98ee4 100644 --- a/packages/eip-7702-internal-rpc-middleware/package.json +++ b/packages/eip-7702-internal-rpc-middleware/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/eip1193-permission-middleware/package.json b/packages/eip1193-permission-middleware/package.json index 8cf0c6e4ec5..0bdeb779243 100644 --- a/packages/eip1193-permission-middleware/package.json +++ b/packages/eip1193-permission-middleware/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/eth-block-tracker/package.json b/packages/eth-block-tracker/package.json index 1eccb96d189..6a2350132f8 100644 --- a/packages/eth-block-tracker/package.json +++ b/packages/eth-block-tracker/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/eth-json-rpc-middleware/package.json b/packages/eth-json-rpc-middleware/package.json index 58c9827ce8c..fa22631653f 100644 --- a/packages/eth-json-rpc-middleware/package.json +++ b/packages/eth-json-rpc-middleware/package.json @@ -83,5 +83,8 @@ "@metamask/eth-sig-util>ethereumjs-util>ethereum-cryptography>secp256k1": false, "eslint-plugin-import-x>unrs-resolver": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/eth-json-rpc-provider/package.json b/packages/eth-json-rpc-provider/package.json index 46b73b94c16..d535a5efa32 100644 --- a/packages/eth-json-rpc-provider/package.json +++ b/packages/eth-json-rpc-provider/package.json @@ -78,5 +78,8 @@ "allowScripts": { "@lavamoat/preinstall-always-fail": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/foundryup/package.json b/packages/foundryup/package.json index 5666cce40cf..3425a8ee9d7 100644 --- a/packages/foundryup/package.json +++ b/packages/foundryup/package.json @@ -74,5 +74,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/gas-fee-controller/package.json b/packages/gas-fee-controller/package.json index c92bcfd67f8..40fc82c658a 100644 --- a/packages/gas-fee-controller/package.json +++ b/packages/gas-fee-controller/package.json @@ -83,5 +83,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/gator-permissions-controller/package.json b/packages/gator-permissions-controller/package.json index c38d5395ba0..fdd87d3be6f 100644 --- a/packages/gator-permissions-controller/package.json +++ b/packages/gator-permissions-controller/package.json @@ -85,5 +85,8 @@ "allowScripts": { "@lavamoat/preinstall-always-fail": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/geolocation-controller/package.json b/packages/geolocation-controller/package.json index 3b88aae161b..7dd1291c46b 100644 --- a/packages/geolocation-controller/package.json +++ b/packages/geolocation-controller/package.json @@ -69,5 +69,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/java-tron-up/package.json b/packages/java-tron-up/package.json index ef48c2bbe1f..970daf09796 100644 --- a/packages/java-tron-up/package.json +++ b/packages/java-tron-up/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/json-rpc-engine/package.json b/packages/json-rpc-engine/package.json index 3e1e058b7fd..f4c2720b39f 100644 --- a/packages/json-rpc-engine/package.json +++ b/packages/json-rpc-engine/package.json @@ -85,5 +85,8 @@ "allowScripts": { "@lavamoat/preinstall-always-fail": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/json-rpc-middleware-stream/package.json b/packages/json-rpc-middleware-stream/package.json index 38ba3824d8e..a38691d5025 100644 --- a/packages/json-rpc-middleware-stream/package.json +++ b/packages/json-rpc-middleware-stream/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/keyring-controller/package.json b/packages/keyring-controller/package.json index 00f6292276d..65ff1eeda91 100644 --- a/packages/keyring-controller/package.json +++ b/packages/keyring-controller/package.json @@ -96,5 +96,8 @@ "ethereumjs-wallet>ethereum-cryptography>keccak": false, "ethereumjs-wallet>ethereum-cryptography>secp256k1": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/kyc-controller/package.json b/packages/kyc-controller/package.json index 6f2ba26d73e..a138aeeebf1 100644 --- a/packages/kyc-controller/package.json +++ b/packages/kyc-controller/package.json @@ -84,5 +84,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/local-node-utils/package.json b/packages/local-node-utils/package.json index 73439d0f407..e78b4de6532 100644 --- a/packages/local-node-utils/package.json +++ b/packages/local-node-utils/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/logging-controller/package.json b/packages/logging-controller/package.json index aea0f576d2a..0b927899f61 100644 --- a/packages/logging-controller/package.json +++ b/packages/logging-controller/package.json @@ -70,5 +70,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/message-manager/package.json b/packages/message-manager/package.json index 392203e3ed1..896ea7fff56 100644 --- a/packages/message-manager/package.json +++ b/packages/message-manager/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/messenger-cli/package.json b/packages/messenger-cli/package.json index 44af3c2f2d5..d01703b2fd7 100644 --- a/packages/messenger-cli/package.json +++ b/packages/messenger-cli/package.json @@ -77,5 +77,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/messenger/package.json b/packages/messenger/package.json index 5b41e9a6363..cbd6d126e11 100644 --- a/packages/messenger/package.json +++ b/packages/messenger/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/money-account-api-data-service/package.json b/packages/money-account-api-data-service/package.json index b6328da67ac..f7c9fae6661 100644 --- a/packages/money-account-api-data-service/package.json +++ b/packages/money-account-api-data-service/package.json @@ -73,5 +73,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/money-account-balance-service/package.json b/packages/money-account-balance-service/package.json index 0182b6acf26..d12e036f46a 100644 --- a/packages/money-account-balance-service/package.json +++ b/packages/money-account-balance-service/package.json @@ -78,5 +78,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/money-account-controller/package.json b/packages/money-account-controller/package.json index 0a079c41439..a5c5e272bb2 100644 --- a/packages/money-account-controller/package.json +++ b/packages/money-account-controller/package.json @@ -75,5 +75,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/money-account-upgrade-controller/package.json b/packages/money-account-upgrade-controller/package.json index a5ec5147f12..e82511568f5 100644 --- a/packages/money-account-upgrade-controller/package.json +++ b/packages/money-account-upgrade-controller/package.json @@ -78,5 +78,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/money-account-utils/package.json b/packages/money-account-utils/package.json index 3bd190ea10a..32b8df81833 100644 --- a/packages/money-account-utils/package.json +++ b/packages/money-account-utils/package.json @@ -71,5 +71,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/multichain-account-service/package.json b/packages/multichain-account-service/package.json index f4b530ee6f5..0cca933a93f 100644 --- a/packages/multichain-account-service/package.json +++ b/packages/multichain-account-service/package.json @@ -95,5 +95,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/multichain-api-middleware/package.json b/packages/multichain-api-middleware/package.json index e95f705b4b2..dad9f0cac8a 100644 --- a/packages/multichain-api-middleware/package.json +++ b/packages/multichain-api-middleware/package.json @@ -80,5 +80,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/multichain-network-controller/package.json b/packages/multichain-network-controller/package.json index 605c66df08a..d06e678a21b 100644 --- a/packages/multichain-network-controller/package.json +++ b/packages/multichain-network-controller/package.json @@ -81,5 +81,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/multichain-transactions-controller/package.json b/packages/multichain-transactions-controller/package.json index ee10c54b413..f020a90e997 100644 --- a/packages/multichain-transactions-controller/package.json +++ b/packages/multichain-transactions-controller/package.json @@ -80,5 +80,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/name-controller/package.json b/packages/name-controller/package.json index dd64986a9ff..5834b653d57 100644 --- a/packages/name-controller/package.json +++ b/packages/name-controller/package.json @@ -72,5 +72,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/network-connection-banner-controller/package.json b/packages/network-connection-banner-controller/package.json index e90cd7b0b64..6f3b9e8dc62 100644 --- a/packages/network-connection-banner-controller/package.json +++ b/packages/network-connection-banner-controller/package.json @@ -75,5 +75,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/network-controller/package.json b/packages/network-controller/package.json index fb9fd431248..7473cffc68b 100644 --- a/packages/network-controller/package.json +++ b/packages/network-controller/package.json @@ -99,5 +99,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/network-enablement-controller/package.json b/packages/network-enablement-controller/package.json index 0da752f96f6..7e964cf748f 100644 --- a/packages/network-enablement-controller/package.json +++ b/packages/network-enablement-controller/package.json @@ -77,5 +77,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/notification-services-controller/package.json b/packages/notification-services-controller/package.json index 2479f1280ca..21c90ebd0e3 100644 --- a/packages/notification-services-controller/package.json +++ b/packages/notification-services-controller/package.json @@ -110,5 +110,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/package-template/package.json b/packages/package-template/package.json index 5f8f17e171d..357c834e39d 100644 --- a/packages/package-template/package.json +++ b/packages/package-template/package.json @@ -65,5 +65,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/passkey-controller/package.json b/packages/passkey-controller/package.json index d9e3d06b6a0..e661c30b564 100644 --- a/packages/passkey-controller/package.json +++ b/packages/passkey-controller/package.json @@ -76,5 +76,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/permission-controller/package.json b/packages/permission-controller/package.json index d1b641dd70a..a6c0662436f 100644 --- a/packages/permission-controller/package.json +++ b/packages/permission-controller/package.json @@ -77,5 +77,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/permission-log-controller/package.json b/packages/permission-log-controller/package.json index 1e33e390bc3..01c1466efb0 100644 --- a/packages/permission-log-controller/package.json +++ b/packages/permission-log-controller/package.json @@ -73,5 +73,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/perps-controller/package.json b/packages/perps-controller/package.json index a23c4827b3f..7ec028e566e 100644 --- a/packages/perps-controller/package.json +++ b/packages/perps-controller/package.json @@ -107,5 +107,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/phishing-controller/package.json b/packages/phishing-controller/package.json index a72b60bf2c7..caaa0181588 100644 --- a/packages/phishing-controller/package.json +++ b/packages/phishing-controller/package.json @@ -78,5 +78,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/platform-api-docs/package.json b/packages/platform-api-docs/package.json index 813daaaee6c..34d68bb3103 100644 --- a/packages/platform-api-docs/package.json +++ b/packages/platform-api-docs/package.json @@ -77,5 +77,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/polling-controller/package.json b/packages/polling-controller/package.json index ec5b0b28dc4..78abd022a4e 100644 --- a/packages/polling-controller/package.json +++ b/packages/polling-controller/package.json @@ -69,5 +69,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/preferences-controller/package.json b/packages/preferences-controller/package.json index c91f143bf61..031578da2eb 100644 --- a/packages/preferences-controller/package.json +++ b/packages/preferences-controller/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/profile-metrics-controller/package.json b/packages/profile-metrics-controller/package.json index 9a47f7d490d..a713a761b53 100644 --- a/packages/profile-metrics-controller/package.json +++ b/packages/profile-metrics-controller/package.json @@ -83,5 +83,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/profile-sync-controller/package.json b/packages/profile-sync-controller/package.json index ca758ff8447..eab48b1c203 100644 --- a/packages/profile-sync-controller/package.json +++ b/packages/profile-sync-controller/package.json @@ -122,5 +122,8 @@ }, "lavamoat": { "allowScripts": {} + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/ramps-controller/package.json b/packages/ramps-controller/package.json index affe20a050e..25f492e5ea6 100644 --- a/packages/ramps-controller/package.json +++ b/packages/ramps-controller/package.json @@ -75,5 +75,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/rate-limit-controller/package.json b/packages/rate-limit-controller/package.json index 4fdd0125a02..b91470f8b9c 100644 --- a/packages/rate-limit-controller/package.json +++ b/packages/rate-limit-controller/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/react-data-query/package.json b/packages/react-data-query/package.json index d6ff4dd4d52..edc9c3b13b0 100644 --- a/packages/react-data-query/package.json +++ b/packages/react-data-query/package.json @@ -84,5 +84,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/remote-feature-flag-controller/package.json b/packages/remote-feature-flag-controller/package.json index 87fb2ddf15d..978d614178f 100644 --- a/packages/remote-feature-flag-controller/package.json +++ b/packages/remote-feature-flag-controller/package.json @@ -73,5 +73,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/sample-controllers/package.json b/packages/sample-controllers/package.json index 31958792c1c..27adaaf718d 100644 --- a/packages/sample-controllers/package.json +++ b/packages/sample-controllers/package.json @@ -75,5 +75,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/seedless-onboarding-controller/package.json b/packages/seedless-onboarding-controller/package.json index f9252d82fcb..e6ac6f5ae29 100644 --- a/packages/seedless-onboarding-controller/package.json +++ b/packages/seedless-onboarding-controller/package.json @@ -90,5 +90,8 @@ "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography>keccak": false, "@metamask/keyring-controller>ethereumjs-wallet>ethereum-cryptography>secp256k1": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/selected-network-controller/package.json b/packages/selected-network-controller/package.json index de182a44c6c..c91da98f487 100644 --- a/packages/selected-network-controller/package.json +++ b/packages/selected-network-controller/package.json @@ -77,5 +77,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/sentinel-api-service/package.json b/packages/sentinel-api-service/package.json index 4170c7826e8..cff9048be78 100644 --- a/packages/sentinel-api-service/package.json +++ b/packages/sentinel-api-service/package.json @@ -73,5 +73,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/shield-controller/package.json b/packages/shield-controller/package.json index ff054c406f1..c400674c325 100644 --- a/packages/shield-controller/package.json +++ b/packages/shield-controller/package.json @@ -86,5 +86,8 @@ "allowScripts": { "@lavamoat/allow-scripts>@lavamoat/preinstall-always-fail": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/signature-controller/package.json b/packages/signature-controller/package.json index ae18e11a9c0..51b3757c53d 100644 --- a/packages/signature-controller/package.json +++ b/packages/signature-controller/package.json @@ -80,5 +80,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/smart-transactions-controller/package.json b/packages/smart-transactions-controller/package.json index 3155dfef59a..f6dbb305c93 100644 --- a/packages/smart-transactions-controller/package.json +++ b/packages/smart-transactions-controller/package.json @@ -86,5 +86,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/snap-account-service/package.json b/packages/snap-account-service/package.json index 759bb70b787..0124fb1e778 100644 --- a/packages/snap-account-service/package.json +++ b/packages/snap-account-service/package.json @@ -79,5 +79,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/social-controllers/package.json b/packages/social-controllers/package.json index 18f0dda5e42..657b5b8bc05 100644 --- a/packages/social-controllers/package.json +++ b/packages/social-controllers/package.json @@ -72,5 +72,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/solana-test-validator-up/package.json b/packages/solana-test-validator-up/package.json index e819cdf765f..19bfe23a9a0 100644 --- a/packages/solana-test-validator-up/package.json +++ b/packages/solana-test-validator-up/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/stellar-quickstart-up/package.json b/packages/stellar-quickstart-up/package.json index 09b7da0742c..574bca15cd2 100644 --- a/packages/stellar-quickstart-up/package.json +++ b/packages/stellar-quickstart-up/package.json @@ -64,5 +64,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/storage-service/package.json b/packages/storage-service/package.json index 6bec01b37a0..bd658563da6 100644 --- a/packages/storage-service/package.json +++ b/packages/storage-service/package.json @@ -68,5 +68,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/subscription-controller/package.json b/packages/subscription-controller/package.json index 05c40432854..5ee9790072f 100644 --- a/packages/subscription-controller/package.json +++ b/packages/subscription-controller/package.json @@ -88,5 +88,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index ad448a12a81..1a0fa47fed0 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -108,5 +108,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/transaction-pay-controller/package.json b/packages/transaction-pay-controller/package.json index 3e4aa5a739d..c67ef333193 100644 --- a/packages/transaction-pay-controller/package.json +++ b/packages/transaction-pay-controller/package.json @@ -88,5 +88,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/user-operation-controller/package.json b/packages/user-operation-controller/package.json index 6b6830eed6b..52e8673e1df 100644 --- a/packages/user-operation-controller/package.json +++ b/packages/user-operation-controller/package.json @@ -88,5 +88,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/utils/package.json b/packages/utils/package.json index f48bba450df..3ff60d088fe 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -96,5 +96,8 @@ "eslint-plugin-import-x>unrs-resolver": false, "jest>@jest/core>jest-haste-map>@parcel/watcher": false } + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/wallet-cli/package.json b/packages/wallet-cli/package.json index 483f4c19747..d1fcece2699 100644 --- a/packages/wallet-cli/package.json +++ b/packages/wallet-cli/package.json @@ -90,5 +90,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/wallet-framework-docs/package.json b/packages/wallet-framework-docs/package.json index def2244ef23..5a2b466d0a7 100644 --- a/packages/wallet-framework-docs/package.json +++ b/packages/wallet-framework-docs/package.json @@ -69,5 +69,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/packages/wallet/package.json b/packages/wallet/package.json index fc39cea7501..9ce8041e888 100644 --- a/packages/wallet/package.json +++ b/packages/wallet/package.json @@ -88,5 +88,8 @@ }, "engines": { "node": "^22.14.0 || ^24" + }, + "scriptsConfig": { + "#default": "lavamoat/scripts.strict.json" } } diff --git a/yarn.config.cjs b/yarn.config.cjs index 3f432bf980f..557d86efdca 100644 --- a/yarn.config.cjs +++ b/yarn.config.cjs @@ -332,6 +332,12 @@ module.exports = defineConfig({ await expectCodeowner(workspace, workspaceBasename); } } + + expectWorkspaceField( + workspace, + 'scriptsConfig.#default', + 'lavamoat/scripts.strict.json', + ); } // All version ranges in `dependencies` and `devDependencies` for the same From df7418bbb8de8e210d71f8935774c90161f23e6c Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Mon, 28 Sep 2026 14:32:47 +0200 Subject: [PATCH 2/4] Bump Node version for local development to 26.9.0 --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 6f4247a6255..fceb4529e54 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -26 +26.9.0 From f3d7404c588d5069d7a15ed281774accc0ea5f7b Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Mon, 28 Sep 2026 14:39:52 +0200 Subject: [PATCH 3/4] Fix postinstall command --- lavamoat/scripts.yarn.json | 15 ++++++++ package.json | 3 +- yarn.lock | 76 +++++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 lavamoat/scripts.yarn.json diff --git a/lavamoat/scripts.yarn.json b/lavamoat/scripts.yarn.json new file mode 100644 index 00000000000..9ac9e4447eb --- /dev/null +++ b/lavamoat/scripts.yarn.json @@ -0,0 +1,15 @@ +{ + "notes": "Use this one ONLY for scripts that are only creating nested Yarn processes, e.g., a composition of multiple other scripts via `yarn something && yarn something-else`.", + "nodeOptions": { + "--disable-warning": "SecurityWarning", + "--permission": true, + "--allow-fs-read": ["/"], + "--allow-fs-write": ["./"], + "--allow-child-process": true, + "--allow-net": false, + "--allow-worker": false, + "--allow-addons": false, + "--allow-wasi": false, + "--allow-inspector": false + } +} diff --git a/package.json b/package.json index 6824772ac75..c79aa5dc3dd 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@actions/core": "^3.0.1", "@actions/github": "^9.1.1", "@jest/globals": "^30.4.1", - "@lavamoat/allow-scripts": "^3.4.3", + "@lavamoat/allow-scripts": "^5.1.0", "@lavamoat/preinstall-always-fail": "^2.1.0", "@metamask/auto-changelog": "^6.2.1", "@metamask/create-release-branch": "^4.2.2", @@ -144,6 +144,7 @@ }, "scriptsConfig": { "#default": "lavamoat/scripts.strict.json", + "postinstall": "lavamoat/scripts.yarn.json", "skills:postinstall": "lavamoat/scripts.skills.json" } } diff --git a/yarn.lock b/yarn.lock index 4b30d9ea485..bfe3dadddbe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5309,6 +5309,17 @@ __metadata: languageName: node linkType: hard +"@lavamoat/aa@npm:^5.0.1": + version: 5.0.1 + resolution: "@lavamoat/aa@npm:5.0.1" + dependencies: + resolve: "npm:1.22.12" + bin: + lavamoat-ls: src/cli.js + checksum: 10/a93db450b850dde46e5ae12383086bc85244c00c2e380fe04f5c59d1d064a6329c3d7eed3d3e15c926a72c6d72976716d2164fee8c8b00254b03a68ce9c9963f + languageName: node + linkType: hard + "@lavamoat/allow-scripts@npm:^3.4.3": version: 3.4.3 resolution: "@lavamoat/allow-scripts@npm:3.4.3" @@ -5325,6 +5336,22 @@ __metadata: languageName: node linkType: hard +"@lavamoat/allow-scripts@npm:^5.1.0": + version: 5.1.0 + resolution: "@lavamoat/allow-scripts@npm:5.1.0" + dependencies: + "@lavamoat/aa": "npm:^5.0.1" + "@npmcli/run-script": "npm:10.0.4" + bin-links: "npm:4.0.4" + npm-normalize-package-bin: "npm:3.0.1" + type-fest: "npm:4.41.0" + yargs: "npm:17.7.3" + bin: + allow-scripts: src/cli.js + checksum: 10/8667aad4c2505796744f7276df7eaa8f155523525c1554a62123f65d35cd6450ae1d73d62670eb1bd851c0fe62ca827d5c65058464682358cef79b72b5081966 + languageName: node + linkType: hard + "@lavamoat/preinstall-always-fail@npm:^2.1.0": version: 2.1.0 resolution: "@lavamoat/preinstall-always-fail@npm:2.1.0" @@ -6449,7 +6476,7 @@ __metadata: "@actions/core": "npm:^3.0.1" "@actions/github": "npm:^9.1.1" "@jest/globals": "npm:^30.4.1" - "@lavamoat/allow-scripts": "npm:^3.4.3" + "@lavamoat/allow-scripts": "npm:^5.1.0" "@lavamoat/preinstall-always-fail": "npm:^2.1.0" "@metamask/auto-changelog": "npm:^6.2.1" "@metamask/create-release-branch": "npm:^4.2.2" @@ -9925,6 +9952,19 @@ __metadata: languageName: node linkType: hard +"@npmcli/run-script@npm:10.0.4": + version: 10.0.4 + resolution: "@npmcli/run-script@npm:10.0.4" + dependencies: + "@npmcli/node-gyp": "npm:^5.0.0" + "@npmcli/package-json": "npm:^7.0.0" + "@npmcli/promise-spawn": "npm:^9.0.0" + node-gyp: "npm:^12.1.0" + proc-log: "npm:^6.0.0" + checksum: 10/dd5f92aa6c50761c125eb836432497edfe57a32ddde175218167515bc8f54ba82b7fa8b89b8f73eda69c3a88d1ffe97e14080b316aefdddc264c450e24c32c8b + languageName: node + linkType: hard + "@oclif/core@npm:^4.10.5": version: 4.11.4 resolution: "@oclif/core@npm:4.11.4" @@ -25163,7 +25203,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.22.11": +"resolve@npm:1.22.12, resolve@npm:^1.22.11": version: 1.22.12 resolution: "resolve@npm:1.22.12" dependencies: @@ -25190,7 +25230,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.22.11#optional!builtin": +"resolve@patch:resolve@npm%3A1.22.12#optional!builtin, resolve@patch:resolve@npm%3A^1.22.11#optional!builtin": version: 1.22.12 resolution: "resolve@patch:resolve@npm%3A1.22.12#optional!builtin::version=1.22.12&hash=9bd1a5" dependencies: @@ -28573,6 +28613,21 @@ __metadata: languageName: node linkType: hard +"yargs@npm:17.7.3, yargs@npm:^17.0.1, yargs@npm:^17.7.1, yargs@npm:^17.7.2, yargs@npm:^17.7.3": + version: 17.7.3 + resolution: "yargs@npm:17.7.3" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10/a3826798c03b159e139d0580a3b2733953889a9a1bac8e4e1ca7a1a249b55315b213c323a6a1dbdb305f6e59496a9eaa810742c87e34abcf1a0584d8f59212a1 + languageName: node + linkType: hard + "yargs@npm:^13.3.0": version: 13.3.2 resolution: "yargs@npm:13.3.2" @@ -28591,21 +28646,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.0.1, yargs@npm:^17.7.1, yargs@npm:^17.7.2, yargs@npm:^17.7.3": - version: 17.7.3 - resolution: "yargs@npm:17.7.3" - dependencies: - cliui: "npm:^8.0.1" - escalade: "npm:^3.1.1" - get-caller-file: "npm:^2.0.5" - require-directory: "npm:^2.1.1" - string-width: "npm:^4.2.3" - y18n: "npm:^5.0.5" - yargs-parser: "npm:^21.1.1" - checksum: 10/a3826798c03b159e139d0580a3b2733953889a9a1bac8e4e1ca7a1a249b55315b213c323a6a1dbdb305f6e59496a9eaa810742c87e34abcf1a0584d8f59212a1 - languageName: node - linkType: hard - "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" From 7290bca7cdc16837f0350b4d74c21d3620d94a44 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Mon, 28 Sep 2026 14:48:28 +0200 Subject: [PATCH 4/4] Update runner plugin to latest version --- lavamoat/.runner-plugin.cjs | 216 ++++++++++++++++++++++++++++-------- oxlint.config.ts | 1 + 2 files changed, 173 insertions(+), 44 deletions(-) diff --git a/lavamoat/.runner-plugin.cjs b/lavamoat/.runner-plugin.cjs index 9acee99fda5..f0ba135f44f 100755 --- a/lavamoat/.runner-plugin.cjs +++ b/lavamoat/.runner-plugin.cjs @@ -44,15 +44,20 @@ module.exports = { } const pkgJson = workspace.manifest.raw - const binFolder = - extra.env.BERRY_BIN_FOLDER || `node_modules${path.sep}.bin` + // Abundance of caution. It seems yarn is not adding + // any node_modules/.bin locations to the PATH by default. + const binFolder = `node_modules${path.sep}.bin` + const berryBin = extra.env.BERRY_BIN_FOLDER const wrapper = makeRunScriptWrapper( { scriptName, scriptPayload: extra.script, - projectRoot: extra.cwd, + projectRoot: project.cwd, pathBinMatcher: (fragment) => { + if (berryBin && fragment === berryBin) { + return true + } return fragment.endsWith(binFolder) }, customizePermissionsConfig: addMandatoryReads, @@ -66,12 +71,14 @@ module.exports = { pathDelimiter: path.delimiter, tmpdir, realpathSync: fs.realpathSync, + lstatSync: fs.lstatSync, + readlinkSync: fs.readlinkSync, } ) - // extra.env is a reference to the mutable object, but a different variable - // containing that reference is used within execute, so we must amend not - // replace it. + // extra.env is a reference to the mutable object, but a + // different variable containing that reference is used within + // execute, so we must amend not replace it. const newEnv = wrapper.processEnv(extra.env) for (const key of Object.keys(extra.env)) { delete extra.env[key] @@ -96,7 +103,7 @@ function addMandatoryReads(configOptions, _env) { } ;; -/// +/// /** * @param {MakeRunScriptWrapperOptions} param0 @@ -112,7 +119,15 @@ function makeRunScriptWrapper( customizePermissionsConfig, readScriptsConfig, }, - { readFileSync, pathJoin, pathDelimiter, tmpdir, realpathSync } + { + readFileSync, + pathJoin, + pathDelimiter, + tmpdir, + realpathSync, + lstatSync, + readlinkSync, + } ) { const DEFAULT_PERMISSION_KEY = '#default' @@ -121,11 +136,80 @@ function makeRunScriptWrapper( return JSON.parse(readFileSync(filePath, 'utf8')) } + /** + * Additively composes two configuration objects. Arrays are concatenated, and + * nested objects are recursively merged. + * + * @param {any} parent + * @param {any} config + */ + function additiveCompose(parent, config) { + const composed = { ...parent, ...config } + for (const key of Object.keys(parent)) { + if (key in config) { + if (Array.isArray(parent[key]) || Array.isArray(config[key])) { + composed[key] = [parent[key], config[key]].flat() + } else if (typeof config[key] === 'object') { + composed[key] = additiveCompose(parent[key], config[key]) + } + } + } + return composed + } + + /** + * Reads and processes a config file + * + * @param {string} filePath - The path to the config file + * @param {number} [depth] - The recursion depth for extend + * @returns {Record} - The processed configuration object + */ + function readScriptConfig(filePath, depth = 0) { + const conf = readJsonFile(filePath) + if (typeof conf !== 'object' || conf === null || depth > 10) { + throw Error( + `Failed to load config.${depth > 10 ? ' (maximum extend depth exceeded)' : ''}` + ) + } + const { extends: parentPath, ...config } = conf + if (!parentPath) { + return config + } + const parent = readScriptConfig( + pathJoin(filePath, '..', parentPath), + depth + 1 + ) + + return additiveCompose(parent, config) + } + + /** + * @param {Record} configs + * @param {string} scriptName + * @returns {string | undefined} + */ + function prefixMatch(configs, scriptName) { + const keys = Object.keys(configs) + const matchingKeys = keys + .filter((k) => k.endsWith('*')) + .filter((k) => scriptName.startsWith(k.slice(0, -1))) + + if (matchingKeys.length === 0) { + return undefined + } + // longest prefix match wins + const bestMatch = matchingKeys.reduce((a, b) => + a.length > b.length ? a : b + ) + return configs[bestMatch] + } + /** * @param {object} opts * @param {Record | undefined} opts.scriptsConfig * @param {string} [opts.scriptName] * @param {string} opts.projectRoot + * @returns {{ config: Record; name?: string }} */ function readConfig({ scriptsConfig, @@ -133,22 +217,21 @@ function makeRunScriptWrapper( projectRoot, }) { if (!scriptsConfig) { - return {} + return { config: {} } } const configName = - scriptsConfig[scriptName] || scriptsConfig[DEFAULT_PERMISSION_KEY] + scriptsConfig[scriptName] || + prefixMatch(scriptsConfig, scriptName) || + scriptsConfig[DEFAULT_PERMISSION_KEY] // config needs to be optional, because it's opt-in first and specifying a default turns it opt-out. if (!configName) { - return {} + return { config: {} } } const configPath = pathJoin(projectRoot, configName) let conf try { - conf = readJsonFile(configPath) - if (typeof conf !== 'object' || conf === null) { - throw Error(`Expected an object, got ${typeof conf}`) - } + conf = readScriptConfig(configPath) } catch (err) { const message = err instanceof Error ? err.message : String(err) throw Error( @@ -156,7 +239,10 @@ function makeRunScriptWrapper( { cause: err } ) } - return conf + return { + config: conf, + name: configName, + } } /** @@ -197,25 +283,46 @@ function makeRunScriptWrapper( // 2. tmp write - crossplatform if (configOptions['--allow-fs-tmp'] === true) { delete configOptions['--allow-fs-tmp'] - if (configOptions['--allow-fs-write']) { - if (typeof configOptions['--allow-fs-write'] === 'string') { - configOptions['--allow-fs-write'] = [ - configOptions['--allow-fs-write'], - ] - } - if (configOptions['--allow-fs-write'] === true) { - return // none of this matters + const tmp = tmpdir() + let tmpRealPath = tmp + try { + tmpRealPath = realpathSync(tmp) + } catch { + // if realpathSync fails, it's been restricted by permissions + try { + const stats = lstatSync(tmp) + if (stats.isSymbolicLink()) { + tmpRealPath = readlinkSync(tmp) + } + } catch { + // silence the error and continue with no separate tmpRealPath } - } else { - // do this for both undefined and false - configOptions['--allow-fs-write'] = [] } - const tmp = tmpdir() - configOptions['--allow-fs-write'].push(tmp) - // because macos is being weird - const tmpRealPath = realpathSync(tmp) - if (tmpRealPath !== tmp) { - configOptions['--allow-fs-write'].push(tmpRealPath) + // write doesn't grant read, sadly + for (const perm of ['write', 'read']) { + const allowOption = `--allow-fs-${perm}` + if (configOptions[allowOption]) { + if (configOptions[allowOption] === true) { + continue // all of fs allowed, nothing to add + } + if (typeof configOptions[allowOption] === 'string') { + // need to expand to multiple paths + configOptions[allowOption] = [configOptions[allowOption]] + } + if (!Array.isArray(configOptions[allowOption])) { + throw Error( + `Unexpected type for ${allowOption}: ${typeof configOptions[allowOption]}` + ) + } + } else { + // do this for both undefined and false + configOptions[allowOption] = [] + } + configOptions[allowOption].push(tmp) + // because macos is being weird + if (tmpRealPath !== tmp) { + configOptions[allowOption].push(tmpRealPath) + } } } } @@ -239,14 +346,30 @@ function makeRunScriptWrapper( /** * Checks the config obtained from package.json and puts it in as NODE_OPTIONS * - * @param {string | undefined} existingOptions * @param {ConfigOptions} configOptions * @param {NodeJS.ProcessEnv} env */ - function installNodeOptions(existingOptions, configOptions, env) { + function installNodeOptions(configOptions, env) { + const existingOptions = env.NODE_OPTIONS + const inLavaMoatEnvAlready = !!env.LAVAMOAT_RUN_CONF + if (!configOptions) { return existingOptions || '' } + // Calls to run can be nested, so existing NODE_OPTIONS are not to be preserved. + // If end user needs to set some options, let them put those in the script config json too. + // If this becomes an issue, we could use a separate env var to distinguish between options we set and options that were there already. + + // If we're not nested, but there are existing options, it's safe to warn the user without being annoying. + if ( + !inLavaMoatEnvAlready && + existingOptions && + existingOptions.length > 0 + ) { + console.error( + `[LavaMoat] Warning: Replacing existing NODE_OPTIONS. Move them to the relevant JSON file in lavamoat/ if they were intentional.` + ) + } customizePermissionsConfig(configOptions, env) @@ -254,7 +377,7 @@ function makeRunScriptWrapper( const confOption = makeFlagsFromConfig(configOptions) - return `${existingOptions || ''} ${confOption.trim()}`.trim() + return confOption.trim() } /** @@ -332,15 +455,23 @@ function makeRunScriptWrapper( filteredFragments.push(fragment) } } - // Why would there be multiple bin fragments? In a npm workspace, local bin and workspace root bin is added - filteredFragments.push(...nodeModulesBinFragments) + // This should preserve order of items. + const uniqueNodeModulesBinFragments = Array.from( + new Set(nodeModulesBinFragments) + ) + + // Why would there even be multiple bin fragments? ecause + // npm happily adds entries for hypothetical node_modules/.bin + // in all parent dirs + filteredFragments.push(...uniqueNodeModulesBinFragments) + return filteredFragments.join(pathDelimiter) } return { processEnv: (existingEnv) => { const scriptsConfig = readScriptsConfig(projectRoot) - const config = readConfig({ + const { config, name: configName } = readConfig({ scriptsConfig, scriptName, projectRoot, @@ -355,12 +486,9 @@ function makeRunScriptWrapper( const fixedEnv = { ...filterEnv(existingEnv, lavamoatDir), + LAVAMOAT_RUN_CONF: configName, PATH: envPathOpinions(existingPath), - NODE_OPTIONS: installNodeOptions( - existingEnv.NODE_OPTIONS, - config.nodeOptions, - existingEnv - ), + NODE_OPTIONS: installNodeOptions(config.nodeOptions, existingEnv), } return fixedEnv }, diff --git a/oxlint.config.ts b/oxlint.config.ts index ec85f4d616e..6d23d4dfaae 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -16,6 +16,7 @@ export default createConfig({ '.platform-api-docs/**', '.skills-cache/**', '.yarn/**', + 'lavamot/**', 'merged-packages/**', 'packages/wallet-framework-docs/site/build/**', ],