Development7 min read

Securing Your npm CI Supply Chain After AsyncAPI

In July 2026, several AsyncAPI project packages were published to npm with valid OIDC signatures — standard detection tools raised no alerts. The incident demonstrated that a CI pipeline relying solely on lockfile or signature checks remains vulnerable to upstream compromise.

What the AsyncAPI incident changed

Over two weeks in July 2026, five AsyncAPI package versions circulated with signed OIDC provenance. The attackers had compromised the publishing pipeline, not the signing key. The result: npm audit signatures returned a clean result, and dependency managers raised no alerts. A signature proves the integrity of the package at publication time, not the integrity of the process that produced it.

Concrete measures to put in place

  • --frozen-lockfile policy — prevent any silent modification of package-lock.json in CI (npm ci enforces this natively; --frozen-lockfile for yarn/pnpm).
  • Hash verification in CI — add a job that compares SHA-512 hashes from the lockfile against the npm registry.
  • Automated SCA — integrate a software composition analysis scanner (OWASP Dependency-Check, Trivy, Snyk) as a blocking CI step.
  • SLSA provenance level 2 minimum — generate and attach SLSA attestations when publishing; verify critical packages carry them when consuming.
  • CI image digest pinning — pin each Docker image to its sha256 digest rather than a floating tag.
  • Alerts on unplanned new versions — configure Dependabot or Renovate to notify on any version published outside your usual update window.

What the lockfile guarantees — and what it does not

The package-lock.json records the exact version and hash of each resolved dependency. It prevents a silent version bump on a subsequent npm install. What it does not do: verify that the matching package content has not changed on the registry side, or that the pipeline which produced the package was itself sound.

Hardening your CI pipeline step by step

01

Switch to `npm ci` and ban `npm install` in CI

Replace every npm install with npm ci. The command refuses to run if package-lock.json is absent or diverges from package.json. Add --ignore-scripts if your dependency tree contains unaudited third-party postinstall hooks.

02

Enable `npm audit` in blocking mode

Add npm audit --audit-level=high after npm ci and before the build. In GitHub Actions, the step fails if a high or critical severity result is detected.

03

Verify hashes with `npm audit signatures`

Since npm 8.8, npm audit signatures verifies that each installed package has a valid signature registered in the registry. Run it after npm ci.

04

Integrate an SCA scanner (Trivy or OWASP Dependency-Check)

Add a dedicated SCA job to your CI workflow. Trivy analyses package-lock.json directly (trivy fs --scanners vuln .). Configure it to fail on CVEs with CVSS score above 7.

05

Consume and emit SLSA attestations

For your own published packages, enable SLSA provenance in your publish workflow (GitHub Actions slsa-framework/slsa-github-generator).

06

Pin CI actions and images to their sha256 digest

Replace floating tags with sha256 digests in your workflow files. A floating tag may point to a different image after a registry compromise.

Never patch a dependency directly in production by editing node_modules by hand: the lockfile would diverge, and the next CI deployment would reintroduce the original package. Every fix goes through the versioned lockfile, replayed by CI.

Integration into your hosted Git workflow

These controls are pipeline steps, not manual habits: they belong in your ci.yml or .gitlab-ci.yml, triggered on every push and pull request. On a self-hosted repository (Gitea, GitLab CE), the same recipes apply. Protect your main branch with a conditional merge rule gating on a green CI.

Isolated CI environments for your build pipelines

Deploy your CI runners on a dedicated Cloud VPS: network isolation, full control of system dependencies, and no shared resources with other tenants.

Need help?

Browse our help center and FAQ, or write to our team — support in French, English and Arabic.