Supply chain
npm install runs preinstall, install and postinstall scripts — for the package and for every transitive dependency — with your full privileges, outside the permission engine, outside every isolator, and before the plugin's declared capabilities have even been read.
That was the largest hole in the product, because it sat underneath every gate the framework had built.
Install scripts do not run
Every plugin install now passes --ignore-scripts.
Plugins are ESM modules. They should not need a build step, and one that does is a reason to reject it rather than a reason to relax the flag.
Packages resolve through a signed index
The registry carries a detached Ed25519 signature over exact bytes — no canonicalisation step to keep in sync between signer and verifier — and pins versions, which takes npm's mutable latest tag out of the trust path. Capability manifests are surfaced before install, so what a plugin intends to touch is visible before it lands.
plugins:
registry: https://registry.example.internal/moxxyMOXXY_REGISTRY_URL is the environment equivalent.
What a signature over the index proves
It proves the index has not been altered and that a given name resolves to a given version. It says nothing about what that tarball's code does. The signature and --ignore-scripts are complementary controls, not substitutes.
The manifest is the description of a workstation
plugins.packages in the merged config is a map of what should be installed. Push it from the system scope, or commit it with a project, and it becomes a reviewable, diffable artefact rather than a state each laptop drifted into.
plugins:
packages:
'@moxxy/plugin-channel-slack': '1.4.0'
'@acme/plugin-jira': '2.1.0'moxxy sync # install what is declared and missing
moxxy sync --check # report drift, change nothing, exit 1 if anything is missing$ moxxy sync --check
missing (declared, not installed)
@acme/plugin-jira
extra (installed, not in the manifest)
@moxxy/plugin-browser
exit 1Only missing fails. An extra package is a local decision, and removing something a user installed is their call, so it is reported and never done for them. disabled (installed, but turned off in config) is reported as its own category, because "present but inert" is a different situation from "absent".
--check mutates nothing, which is what makes it safe in a provisioning pipeline or a pre-merge gate.
Where installs land
~/.moxxy/plugins, inside the 0700 moxxy home. Plugins are version-pinned and installed on first use rather than bundled into the binary, which is also why the published CLI is a fraction of the size it used to be.
Capability declarations
Once installed, a plugin's tools declare what they may touch:
isolation: {
capabilities: {
fs: { read: ['$cwd/**'] },
net: { mode: 'allowlist', hosts: ['deploy.internal'] },
env: ['DEPLOY_TOKEN'],
timeMs: 30_000,
},
}Under the enterprise profile those declarations are enforced, undeclared tools are refused, and third-party undeclared tools are refused specifically:
security:
enabled: true
requireDeclaration: true
thirdPartyRequireDeclaration: enforce
strict: true
plugins:
isolator:
default: subprocessSee isolation and capabilities.