If you publish packages, your release path is the entry point attackers want. Secure the accounts that can publish, use short-lived credentials from CI, require review before release, and publish provenance so consumers can see how a build was made. Eight checks cover the basics.
The checklist
- Two-factor authentication on every publishing account. The npm documentation says publishing requires either two-factor authentication on the account or a granular token with the bypass option enabled. Prefer the first. Security keys and passkeys are the strongest options GitHub lists.
- Use granular tokens only where needed, scoped to specific packages, with an expiry date. The npm documentation notes legacy tokens were removed in November 2025 and only granular tokens are supported.
- Prefer trusted publishing. Both npm and PyPI describe exchanging short-lived identity tokens from CI instead of storing a long-lived publishing token. PyPI states its minted tokens last 15 minutes. Check each registry's requirements, since npm lists minimum CLI and Node versions and supported CI providers.
- Publish from CI only, so a laptop compromise cannot ship a release.
- Require review for release changes: protected branches, required approvals and code owner review for workflow and release files. GitHub's protected branch settings include required pull request reviews and required status checks.
- Generate provenance. The npm documentation says provenance links a package to its source code and build instructions, signed through Sigstore and logged in a public transparency ledger. It also states provenance does not guarantee a package has no malicious code, only a verifiable link to where it was built.
- Keep an access list and review it quarterly. Remove people who have left or moved on.
- Write a compromise runbook before you need it: how to unpublish or deprecate, how to notify users, and how to rotate credentials.
Why provenance is not a seal
Treat provenance as evidence, not a verdict. It tells consumers where the build ran. It cannot tell them the maintainer's intent. If the account is taken over and the attacker publishes through your legitimate pipeline, the provenance can still look valid.
Common mistakes
- A long-lived token left in repository secrets after trusted publishing is set up. Remove it.
- Release workflows that run on pull requests from forks.
- One token that can publish every package in the organization.
- A recovery email on a lapsed domain or an unmonitored mailbox.
Where Safeguard fits
Safeguard's policies and gates, asset discovery and evidence automation help you show which projects exist and what checks apply before release. Account security and registry settings remain with you and your registry.
Quick check
Does trusted publishing remove all token risk?
It removes the stored long-lived publishing token. The workflow itself must still be protected, because it is now the trusted identity.
Should every package have provenance?
It helps consumers verify the build, so it is worth enabling where your CI and registry support it.
Sources
- npm Docs: About two-factor authentication
- npm Docs: About access tokens
- npm Docs: Trusted publishing
- npm Docs: Generating provenance statements
- PyPI Docs: Trusted Publishers
- GitHub Docs: About protected branches
Last reviewed: 19 October 2026.