Get started
n8n community nodes: publishing with npm provenance

n8n community nodes: publishing with npm provenance

From May 1, 2026, every verified n8n community node must ship with npm provenance built on GitHub Actions. A four-step migration guide with the PDF4.dev worked example.

13 min read

n8n is locking down how community nodes get published. From May 1, 2026, every verified node has to ship with an npm provenance attestation, generated by a GitHub Actions workflow. A local npm publish will no longer cut it for the verified catalog, no matter how careful the maintainer is.

We hit this directly. PDF4.dev publishes the official n8n-nodes-pdf4 community node, and we just migrated. This guide walks through the four-step path any node maintainer can follow, with our own diff as the worked example.

What changes on May 1, 2026

From May 1, 2026, npm provenance becomes a hard requirement for verified n8n community nodes. The package must be built and published from a CI workflow that mints a short-lived OIDC token, signs the artifact via Sigstore, and writes the attestation to the Rekor public transparency log. The starter template that n8n ships pins the deadline directly in its workflow comments: "Starting May 1 2026, n8n requires all community nodes to be published via GitHub Actions with npm provenance statements."

The verified-node program is what flips. Verified nodes are the ones that appear in the n8n in-app catalog and run on n8n Cloud without the maintainer being on the n8n team. Unverified packages will still install via the Community Nodes settings panel on self-hosted instances, but they are off the catalog and off Cloud.

What this means in practice:

Before May 1, 2026After May 1, 2026
Verified nodes can be published from any environment, including a laptop.Verified nodes must be published from GitHub Actions with --provenance.
NPM_TOKEN is the standard auth path.npm Trusted Publishers (OIDC) is the recommended auth path; tokens stay as a fallback.
Provenance is optional, a small percentage of npm packages have it.Provenance is mandatory for the verified catalog.
@n8n/node-cli works at any recent version.@n8n/node-cli 0.23.0 or later is required so npm run release forwards the provenance flag.

The deadline gives every existing verified node about a month from publication of this article to migrate. Every new node submission already has to comply.

Why npm provenance, not just signing

npm provenance is a SLSA-level attestation, not a signature on the tarball. It binds three claims that signing alone does not bind: which source repository the package came from, which commit, and which CI workflow built it. GitHub and npm shipped the feature in April 2023 explicitly to defend against credential-theft attacks like the UAParser.js, rc, and coa compromises, where a stolen NPM_TOKEN was used to push a hostile version of a legitimate package.

The chain works in three stages. GitHub Actions issues an OIDC JWT identifying the exact workflow run. Sigstore's Fulcio CA exchanges that token for a short-lived X.509 code-signing certificate. The Rekor transparency log records the attestation, so anyone can later check that a tarball really did come out of the claimed repository at the claimed commit.

Plain signing fixes none of that. A signed tarball just says "the holder of this private key signed this file". A leaked key signs malware just as cleanly as a real release. Provenance shifts trust away from a long-lived secret and onto the immutable identity of a CI run, which an attacker cannot retroactively forge without compromising both GitHub OIDC and the Sigstore root.

The npm docs are explicit about the limit of this guarantee: "When a package in the npm registry has established provenance, it does not guarantee the package has no malicious code." Provenance proves where code came from, not whether the code is good. That is still a large step forward, because it removes one of the two main attack categories (credential theft and stale-token republish) and forces an attacker to compromise the source repository instead.

For an automation platform like n8n, where a single community node sits inside thousands of self-hosted production workflows, that trust shift is the right baseline.

The four-step migration

Migrating a verified node takes four steps, in order. None of them require new infrastructure, just config and a CLI bump. The full sequence is below; each step has a dedicated section after it.

  1. Configure a Trusted Publisher on npmjs.com so GitHub Actions can publish without a long-lived NPM_TOKEN.
  2. Add the publish.yml workflow from n8n-nodes-starter to .github/workflows/.
  3. Upgrade @n8n/node-cli to 0.23.0 or later so npm run release forwards the provenance flag.
  4. Cut the first signed release by tagging from a clean local checkout.

Step 1: configure npm Trusted Publishers

A Trusted Publisher tells npm "this exact GitHub Actions workflow, in this exact repo, is allowed to publish this package without a token". On npmjs.com, open the package, go to Settings, then Publish access, then Trusted Publishers, click Add a publisher, and pick GitHub Actions. Fill in the repository owner, the repository name, and the workflow filename (publish.yml). Leave the environment field blank unless you use GitHub Environments.

Once Trusted Publishers is set, the OIDC token GitHub mints inside your workflow is enough to authenticate to npm. You can leave the NPM_TOKEN secret unset in the repo. The starter template's release step is written to handle both cases: it sets the _authToken only if NPM_TOKEN is present, otherwise it falls through to the OIDC exchange.

Step 2: add the publish.yml workflow

Copy the workflow file from n8n-nodes-starter into .github/workflows/publish.yml. The relevant core, with the comments removed, looks like this:

name: Publish
 
on:
  push:
    tags:
      - '*.*.*'
 
jobs:
  publish:
    name: Publish to npm
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 'lts/*'
          cache: 'npm'
      - name: Install dependencies
        run: npm ci
      - name: Release
        run: |
          [ -n "$NPM_TOKEN" ] && npm config set //registry.npmjs.org/:_authToken "$NPM_TOKEN"
          npm run release
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Three lines do the heavy lifting. The tags: ['*.*.*'] filter scopes runs to release tags only. The id-token: write permission unlocks GitHub's OIDC provider for the job. And npm run release is the n8n CLI release script that ends in npm publish --provenance --access public. Everything else is plumbing.

If you prefer v0.2.0-style tags, change the filter to tags: ['v*.*.*']. If your release script does not call npm publish directly, set NPM_CONFIG_PROVENANCE=true in the env block instead, which forces the flag globally.

Step 3: upgrade @n8n/node-cli

Pin the dev dependency to a version that forwards the provenance flag:

npm install --save-dev @n8n/node-cli@latest

The minimum is 0.23.0. The release script in earlier CLI versions does not pass --provenance through to npm publish, so even with the workflow above the package ends up unsigned and verification still fails. The starter publish.yml comments call this out specifically: "Earlier versions do not support the provenance flag passed by npm run release in CI, and the publish step will fail."

Verify the upgrade landed:

npm list @n8n/node-cli

The output should show 0.23.0 or higher.

Step 4: cut the first signed release

Run npm run release from a clean checkout on main. The n8n release script lints, builds, prompts for the next version, updates the changelog, commits, tags, and pushes. The pushed tag fires the workflow, which mints the OIDC token, signs via Sigstore, publishes to npm, and writes the attestation to Rekor.

Open the Actions tab to confirm the run is green. Then open the package page on npmjs.com. A green Provenance badge appears next to the version with a link out to the GitHub Actions run that built it. That badge is the visible end of a Sigstore attestation chain, and it is what n8n's verification scanner will look for from May 1, 2026 onward.

Inside our migration: how PDF4.dev shipped n8n-nodes-pdf4 with provenance

Our migration was a one-evening change. The starting point was a freshly scaffolded n8n-nodes-pdf4 repo with four operations (Render From Template, Render From HTML, List Templates, Get Template), zero runtime dependencies, and a hand-written publish.yml that pre-dated the May 1 deadline.

The original workflow already had the right shape, but it relied on NPM_TOKEN and called npm publish directly:

- name: Publish (with provenance)
  run: npm publish --provenance --access public
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

This worked, but it kept the long-lived token in repo secrets and skipped the n8n CLI's release flow, which means we had to bump versions, generate a changelog, and tag by hand. The migration replaced both. We swapped the publish step for the starter template's release block, which calls npm run release and lets the n8n CLI do version bump, changelog, commit, tag, and push in one interactive command:

- name: Release
  run: |
    [ -n "$NPM_TOKEN" ] && npm config set //registry.npmjs.org/:_authToken "$NPM_TOKEN"
    npm run release
  env:
    NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

We added a Trusted Publisher entry on npmjs.com pointing at pdf4-dev/n8n-nodes-pdf4 and publish.yml. After that, the NPM_TOKEN secret in GitHub became a fallback, not the primary path. We also bumped @n8n/node-cli from a floating * to a real pin so we can guarantee 0.23.0+ in CI. Total diff: under 30 lines across package.json and .github/workflows/publish.yml.

The first signed release went out cleanly on the next tag push. The npm package page shows the Provenance badge, the Rekor entry resolves, and the n8n in-app catalog accepted the new build.

Verifying provenance worked

Three checks confirm a release is signed correctly. Each one looks at a different layer of the chain.

npm CLI. Run npm view <package>@<version> and look for dist.attestations. The field returns a URL pointing at the npm-hosted attestation bundle, plus a predicateType of https://slsa.dev/provenance/v1. If the field is missing, the package was published without provenance and verification will fail.

npm audit signatures. Inside any project that depends on the package, run:

npm audit signatures

The output reports verified registry signatures and verified attestations across the dependency tree. A line like audited 1 package with provenance confirms the chain validates end-to-end against Sigstore's keys.

Rekor lookup. The transparency log at rekor.sigstore.dev returns the original attestation by hash. The npm package page links to it via the green Provenance badge, and the JSON payload includes the source repository URL, the commit SHA, and the GitHub Actions workflow run ID. Anyone, including n8n's verification scanner, can replay this lookup and confirm the package came from the claimed source.

For the n8n side, the Creator Portal on n8n's verification dashboard runs the same checks automatically the next time a verified node publishes a new version. A green check next to the version means the scanner found a valid Sigstore attestation linking back to a GitHub Actions run on the registered repo.

Common pitfalls

The migration is short, but four failure modes show up often enough to call out.

Missing id-token: write. The most common failure. Without this permission in the workflow, GitHub does not mint the OIDC token, the Sigstore exchange skips, and npm publish --provenance errors with id-token: write permission is required. Add it under permissions: at the job level, not the top of the file, so other jobs default to read-only.

Branch protection blocking the release commit. The n8n CLI release script commits the version bump straight to the working branch. If main requires PR review, the local push fails before the tag is created and the workflow never runs. Either release from a release branch, or grant the repo's release process a bypass. Do not loosen branch protection for everyone.

Trusted Publisher misconfigured. The workflow filename in npm's Trusted Publisher entry is matched literally. publish.yml and publish.yaml are different. The owner field is case-sensitive on the npm side too, even though GitHub usernames are not. If the OIDC exchange fails with a 403, double-check both before regenerating the token.

Monorepo path issues. If the n8n node is not at the repo root, actions/checkout only checks out the top level by default. Add a working-directory to every step or set defaults.run.working-directory at the job level so npm ci, the build, and npm publish all resolve relative to the package root. The npm repository field in package.json must also point at the subpath using the directory property, otherwise provenance attestation rejects the publish because the source location does not match.

The starter publish.yml from n8n-nodes-starter already handles all four cases for a single-package repo. For monorepos, fork it as a starting point and adjust working directories.

What this means for the broader n8n marketplace

The community node ecosystem is large and growing fast. The awesome-n8n index lists 5,834 nodes as of January 20, 2026, with around 18 new nodes added per day on average. Not all of these are verified, but the verified subset is where the supply-chain risk concentrates: those are the ones the in-app catalog promotes, the ones n8n Cloud runs, and the ones a workflow author is most likely to drop into a production pipeline without auditing.

Forcing provenance on that subset closes the easiest attack path on the platform. An attacker who steals a maintainer's NPM_TOKEN after May 1 cannot push a hostile version to the verified catalog, because the catalog will reject any package without a valid Sigstore attestation pointing at the registered GitHub Actions workflow. To get malware into the catalog, the attacker has to compromise the source repository itself, which is a much higher bar (and one that branch protection, code review, and required signed commits can defend against independently).

The cost on maintainers is small. The migration is one workflow file, one CLI bump, and one Trusted Publisher entry. The n8n-nodes-starter repo bakes the right configuration in, so every new node scaffolded after May 1 is provenance-ready by default. The only real friction is for maintainers who never used a CI pipeline, which the May 1 cutoff converts from "should set up CI eventually" to "must set up CI by Friday".

Provenance does not solve every supply-chain problem. A compromised maintainer account on GitHub still pushes signed-but-malicious code, and a typosquat under a fresh name is still a typosquat. But it removes the credential-theft category of attack from the verified catalog, which is the single largest source of npm supply-chain incidents over the last five years. For an automation platform that runs other people's workflows on its own infrastructure, that trade is overwhelmingly worth making.

If you maintain a verified n8n community node, the work is small and the deadline is firm. Migrate before May 1, 2026, and let GitHub mint the tokens for you.

Start generating PDFs

Build PDF templates with a visual editor. Render them via API from any language in ~300ms.