Installation is an execution boundary
A dependency can run during installation, a build, a test, or an ordinary import. The useful security question is therefore concrete: which downloaded code can run, and which credentials, files, network destinations, and publishing permissions can it reach?
A seven-day release delay reduces exposure to a newly poisoned version while the ecosystem investigates it. It cannot make an old package trustworthy, repair an already compromised runner, or protect a separate installer. This guide uses pnpm 11.19-compatible settings checked on October 23, 2026. The examples and exercises are design guidance, not a claim that the reader's environment has been tested.
Put the delay in the workspace contract
For a pnpm 11.19 workspace, set the following in the root pnpm-workspace.yaml:
minimumReleaseAge: 10080
minimumReleaseAgeStrict: true
minimumReleaseAgeIgnoreMissingTime: false
trustLockfile: false
blockExoticSubdeps: true
strictDepBuilds: true
trustPolicy: no-downgrade10080 is seven days in minutes. The delay covers direct and transitive dependencies. Strict mode rejects a range with no eligible version; missing publication timestamps also fail with the configuration above. trustLockfile: false keeps age and trust verification active for existing entries. --frozen-lockfile serves a different purpose: it prevents rewriting the lockfile. no-downgrade checks whether publication trust evidence has weakened; it does not inspect program behavior. Exact contracts and version availability are in pnpm's dependency-resolution documentation.
Keep the package-manager version exact in packageManager, and review the tool used to provision it. A project policy cannot protect a different npm, pip, Docker pull, or downloaded shell command. Look for these paths in local setup, CI, deploy scripts, and documentation.
Avoid blanket age exclusions. If a release is too young, leave the update pending and use a verified eligible version or disable the affected feature. If that leaves an exposed vulnerability, record the remaining exposure and make a specific mitigation decision. Silently accepting the new release defeats the requested delay; silently keeping the vulnerable release defeats the security objective.
Allow only the install scripts that are needed
A package with an install script needs a separate decision from a package that merely satisfies the version policy. Use allowBuilds to approve reviewed artifacts and retain strictDepBuilds: true so unknown scripts fail installation. A version selector narrows the approval:
# Illustrative shape: replace this with your reviewed package and version.
allowBuilds:
"your-reviewed-native-addon@1.2.3": trueThe placeholder is not a package recommendation. Do not copy it as a working allowlist. An unversioned approval covers later versions too. Global build approval would also cover scripts introduced by future transitive updates. Conversely, denying every script may break native tools, so review the actual script and decide whether the build needs it. See the pnpm build-settings contract.
Script controls reduce one execution path. A malicious module imported by a test or production process can still run. Keep installation and test jobs away from release credentials even after the scripts are reviewed.
Review what changed, then update
Start with the installed graph and current advisories. Select stable versions published at least seven days earlier; prefer a compatible patch or minor update when it fixes the issue. If a fix only exists in a new major, test that migration explicitly. “Newest in the old major” is not evidence that a vulnerability is fixed.
Review the manifest and lockfile together. Inspect new transitive packages, source or maintainer changes where observable, integrity changes, Git/tarball dependencies, install scripts, and overrides. A small direct-version change can introduce a large new execution graph.
A practical verification sequence is:
pnpm install --frozen-lockfile
pnpm audit
# Then run the affected applications' check, test, and build commands.Run it using the pinned package manager in an isolated environment without production secrets. A registry outage is an uncompleted audit, not a clean audit. A failed age check should identify the rejected version and its publication time. Do not “fix” the failure by turning off the checks.
CI input must not inherit release authority
The 2025 Nx s1ngularity postmortem describes a chain from an untrusted pull-request title through a privileged workflow into a malicious publish. The lesson is to trace data into execution and credentials, including jobs after the initial check.
Pin reviewed Actions to full commit SHAs, inspect their nested dependencies, and give jobs only the permissions they need. Keep untrusted PR execution separate from a job that receives deploy or publish credentials. Treat artifacts and caches created by untrusted jobs as untrusted inputs when a privileged job consumes them. Passing a title through an environment variable prevents direct shell interpolation, but does not make code from the PR safe to run with a release token.
PyPI's December 2024 Ultralytics analysis documents poisoned publication through CI cache manipulation and later use of an older publishing token. A trusted publishing identity says which workflow published an artifact; it cannot prove that the workflow and its inputs were uncompromised. Retiring obsolete credentials and separating release caches matter alongside provenance.
The LiteLLM October 21, 2026 report states that poisoned 1.107.0 artifacts reached PyPI and Docker while the ordinary source tag lacked the malicious files. Its investigation was still in progress when this guide was checked. This is a reason to verify the distributed artifact and each installer path, rather than infer safety from a clean source tag or a stable image label.
Turn the policy into observable outcomes
Use a disposable test project or controlled registry fixture. The following is a test plan; it has not been executed against the reader's infrastructure.
| Controlled condition | Expected outcome |
|---|---|
| Stable package version published over seven days ago | Installation may proceed if every other check passes |
| Direct dependency published one day ago | Installation fails |
| New transitive dependency published one day ago | Installation fails |
| Existing lockfile entry is too young | Frozen installation fails the age check |
| Registry omits publication time | Installation fails explicitly |
| Dependency introduces an unreviewed install script | Installation fails without executing that script |
| Unauthorized PR tries to reach release credentials | Credentials are unavailable and release cannot start |
Check both the exit status and the absence of the prohibited effect. For the script fixture, use a harmless marker file in a disposable directory and assert that it was not created. Keep such fixtures out of production dependencies.
An agent-assisted review can use this compact instruction:
Trace manifest, lockfile, install scripts, CI events, artifacts, caches, and deploy permissions. For each reachable risk, state the attacker-controlled input, execution point, credential or side effect, and precondition. Reproduce it with harmless local data, repair the boundary, and test rejection plus the legitimate path. Keep audit failures and unrun checks visible.
If a poisoned package has already executed, changing the version is only one recovery step. Identify the executed artifact, isolate the environment, revoke reachable credentials, rebuild from a clean base, and follow the incident owner's guidance. Preserve enough redacted evidence to understand the exposure before deleting the affected runner or cache.
MENTAL MODEL / REASONING ORDER
From an announcement to your own decision.
Compare the announcement with the conditions in the paper and official documentation.
Sources
Publication dates belong to the source; access dates record when it was checked. Community observations are separate from official statements.
01