Loop icon
Download icon
Get icon
Script icon
If icon
SlackIncomingWebhook icon
Set icon
Schedule icon

Catch Hijacked npm Releases of Your Dependencies Before You Upgrade

Check new releases of your npm dependencies hourly and alert in Slack on a new publisher, lost provenance, new install scripts or maintainer changes.

Categories
Infrastructure

In 2025, chalk, debug and hundreds of other npm packages shipped malicious releases after their maintainers' tokens were phished or stolen, and the Shai-Hulud worm spread through postinstall scripts. Those releases looked different from the normal ones: published from a laptop instead of CI, without a provenance attestation, sometimes by a new account, often with a new install script. Vulnerability scanners only flag them after an advisory exists.

This blueprint watches the latest release of each package you depend on through the public npm registry and compares every new release with the one before. It alerts the owning team when a release:

  • is published by a different npm user than the previous release;
  • has no provenance attestation when the previous one had;
  • is published with a token when the previous one used trusted publishing;
  • adds a preinstall, install or postinstall script, or new dependencies.

Maintainers being added or removed are reported too, with or without a release.

How it works

For each entry in packages (Loop, four at a time):

  1. fetch_latest downloads the manifest behind the latest dist-tag.
  2. load_previous reads the facts recorded for the last release seen, from the Kestra KV store.
  3. evaluate extracts the publisher, provenance, trusted publishing, install scripts, dependencies and maintainers, and lists the risk signals.
  4. if_notify skips Slack when there is nothing to report.
  5. alert_owner posts the release facts and the risk signals, with a link to the release on npm.
  6. remember_release stores the facts for the next comparison, after the alert.

The first run records each package's current release. Signals are reported from the next release on.

Prerequisites

  • A Slack Incoming Webhook. The npm registry is public and needs no key.

Secrets

  • SLACK_WEBHOOK_URL: Slack Incoming Webhook URL for alerts and failures.

In the open-source edition, secrets are environment variables on the Kestra container, prefixed with SECRET_ and base64-encoded. See how to manage secrets.

Inputs

  • packages (JSON): list of {"name", "owner"} objects. Start with your direct dependencies and the packages that run code at install time.
  • notify_every_release (BOOL, default false): also post releases without risk signals.

Quick start

  1. Add the Slack secret and list your packages (for example from package.json).
  2. Execute the flow once to record the current releases.
  3. Enable hourly. When a risky release appears, hold upgrades (or pin the previous version) until the maintainers confirm it.

A signal is not proof of compromise: projects do move to new CI setups. It means a person should look before the release reaches your lockfile. Pair this with an install delay such as pnpm's minimumReleaseAge so there is time to look.

Outputs

  • {{ outputs.evaluate.vars }} per iteration: state (version, publisher, provenance, trusted_publisher, install_scripts, dependencies, maintainers), risks, new_release.
  • KV entries npm_watch_<package> (npm_watch_scoped-<scope>-<name> for scoped packages): the facts of the last release seen.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.