npm stage publish
A maintainer runs npm stage publish and the registry parks a private candidate. Drydock reviews that tarball and pins risk signals to the diff before the maintainer completes npm's 2FA confirmation.
Package review before publish
Between your last code review and the public registry sit build scripts, bundler output, and CI credentials. Drydock holds the release while it is still private, diffs the exact artifact against the last published version, and pins every finding to a changed line. You make the final call.
npm stage publishpypi / npm / vs code workflow gatesno publish credential
What a review looks like
A condensed report. Select a file in the release tree to walk the diff.
4.2.0 → 4.3.017 files4 changedcomplete
package.json| 3 | 3 | "version": "4.3.0", | |
| 4 | 4 | "main": "lib/index.js", | |
| 5 | 5 | "scripts": { | |
| 6 | 6 | "build": "tsc -p .", | |
| 7 | + | "postinstall": "node lib/install.js", | |
| 7 | 8 | "test": "vitest" | |
| 8 | 9 | }, |
postinstall now executes during every npm install, invoking lib/install.js, a file new in this release. Select it in the tree to see why this release is blocked.
Sponsored by
Why review a publish
A pull request review checks the source tree. The registry serves something else: a built artifact that can carry install hooks, minified bundles, and files that never lived in git, published with a credential that may not belong to the person you think. Once a version is live it is immutable and installed within minutes. The last useful checkpoint sits between the finished artifact and the registry — and that is the one almost nobody looks at.
2018publish rights handed over
A volunteer co-maintainer published a wallet-drainer aimed at Copay. The payload existed only in the npm tarball — the GitHub repository never showed it.
2021hijacked npm account
Three malicious versions carried a cryptominer and a credential stealer. The repository was untouched; only the published artifacts were compromised.
2022maintainer's own publish
A legitimate credential shipped a payload that overwrote files based on the installer's IP address. Nothing about the account looked wrong.
2025phished maintainer
One phishing email compromised 18 packages with about two billion combined weekly downloads. The crypto-stealing versions were live for hours before anyone diffed them.
None of these appeared in a pull request. Every one shipped through a publish nobody reviewed.
How it works
A maintainer stages an npm publish, or a GitHub Environment gate pauses the publish job after CI uploads built artifacts. The candidate stays private while Drydock can inspect it.
Drydock compares the candidate with the last published version, flags risky deltas like install scripts, process execution, network access, credential reads, and new binaries, then anchors each finding to the diff. Package contents are never executed.
Approve the npm publish yourself with 2FA, or approve or reject the gated GitHub job from the workbench. Drydock gives you the review; it never publishes and never holds your publish credential.
How it hooks in
A maintainer runs npm stage publish and the registry parks a private candidate. Drydock reviews that tarball and pins risk signals to the diff before the maintainer completes npm's 2FA confirmation.
For PyPI, VS Code extensions, or npm workflows that do not stage, a GitHub Environment pauses the publish job after CI uploads the release artifact. Drydock reviews the upload, the maintainer approves or rejects, and, if approved, the job continues with its own credential.
Safeguards
Scoped tokens only fetch release evidence. Publish credentials stay in npm or GitHub Actions, not in Drydock.
Reports keep redacted review evidence instead of raw release archives.
Maintainers make the release decision: npm 2FA for a stage publish or the CI gate for workflow releases.
Get started
Stage an npm publish or add a workflow gate to your release job. Setup takes minutes, and from then on every version gets a second pair of eyes before it can ship.
free for open-source maintainersread-only tokensyou keep the final approval