This guide explains how to publish qlaw-cli to npm using npm Trusted Publishers with GitHub Actions OIDC authentication.
This repository uses npm Trusted Publishing, a modern, secure approach that eliminates the need for long-lived npm tokens. Instead, GitHub Actions uses OIDC (OpenID Connect) to authenticate with npm automatically during workflow runs.
- ✅ No npm tokens to manage or rotate
- ✅ Cryptographically signed, short-lived credentials
- ✅ Reduced risk of credential leakage
- ✅ Automatic provenance attestation for supply chain security
- ✅ Authentication tied to specific workflows and repositories
Before you can publish the package, you need to configure npm Trusted Publishing on npmjs.com.
-
Ensure the package exists on npm (for first-time setup)
- If
qlaw-clidoesn't exist yet, you'll need to do an initial manual publish with your npm account:npm login npm publish --access public
- Alternatively, create the package on npmjs.com without publishing
- If
-
Configure Trusted Publisher on npmjs.com
- Log in to npmjs.com
- Go to your package page: https://www.npmjs.com/package/qlaw-cli
- Click on Settings tab
- Scroll to Publishing access or Trusted Publishers section
- Click Add trusted publisher
- Select GitHub Actions as the CI/CD provider
- Enter the following details:
- Organization or user:
Qredence - Repository:
qlaw-cli - Workflow filename:
publish.yml - Environment name (optional):
release(if you want to restrict to the release environment)
- Organization or user:
- Click Save
-
Verify Configuration
- The workflow file already has the correct permissions:
permissions: id-token: write # Enable OIDC authentication contents: write # Create releases/tags
- The publish command already includes
--provenanceand--access publicflags
- The workflow file already has the correct permissions:
Once trusted publishing is configured on npmjs.com, the workflow will automatically publish to npm when:
- Code is pushed to the
mainbranch, OR - The workflow is manually triggered via workflow_dispatch
- The version in
package.jsondoesn't already exist on npm
-
Update the version in
package.json:npm version patch # or minor, or major -
Commit and push to main:
git add package.json git commit -m "chore: bump version to X.Y.Z" git push origin main -
The GitHub Action will:
- Check if the version exists on npm
- If not, publish using OIDC authentication (no token needed!)
- Generate provenance attestation
- Create a GitHub release
- Tag the release
You can also trigger the workflow manually:
- Go to Actions tab in GitHub
- Select "Publish Package" workflow
- Click "Run workflow"
- Select branch (usually
main) - Click "Run workflow"
For the very first publish of qlaw-cli:
- Create the package on npmjs.com (without publishing)
- Configure trusted publishing (see above)
- Run the GitHub Actions workflow
- The workflow will publish using OIDC authentication
- Manually publish once from your local machine:
npm login npm publish --access public
- Configure trusted publishing on npmjs.com (see above)
- All future publishes will use GitHub Actions with OIDC
When the workflow runs:
- GitHub generates a short-lived OIDC token that proves the workflow's identity
- The workflow calls
npm publish --provenance --access public - npm receives the OIDC token and verifies it matches the trusted publisher configuration
- If valid, npm allows the publish and generates a provenance attestation
- The package is published with cryptographic proof of its origin
No npm token is stored in GitHub Secrets - authentication happens automatically via OIDC.
Cause: Trusted publishing is not configured on npmjs.com
Solution:
- Verify you've added the trusted publisher configuration on npmjs.com
- Double-check the repository name, organization, and workflow filename match exactly
- Ensure
id-token: writepermission is set in the workflow (it already is)
Error: "Not found - 'qlaw-cli@X.Y.Z' is not in this registry"
This error shows up in two scenarios:
- Package truly does not exist yet – npm is telling you it has never seen
qlaw-clibefore. - Trusted Publishing is not wired up for this package – npm deliberately responds with 404 for untrusted identities, even if the package exists (as a privacy safeguard).
Fix when the package is new:
- Do an initial manual publish from a logged-in npm account:
npm publish --access public - OR create the package shell on npmjs.com first
- Then enable trusted publishing so GitHub can take over
Fix when the package already exists but the workflow still sees 404:
- On npmjs.com go to Package → Settings → Trusted Publishers
- Add a GitHub Actions trusted publisher with:
- Organization/user:
Qredence - Repository:
qlaw-cli - Workflow filename:
publish.yml - (Optional) Environment:
release
- Organization/user:
- Save the configuration, then rerun the workflow. npm will now issue the provenance-aware token and the publish will succeed.
Cause: The GitHub repository/workflow doesn't match the trusted publisher configuration
Solution:
- Verify the trusted publisher settings on npmjs.com
- Check that organization name is
Qredence(exact match, case-sensitive) - Check that repository name is
qlaw-cli(exact match) - Check that workflow filename is
publish.yml - If using environment name, ensure it's set to
release
Cause: The version already exists on npm
Solution: The workflow automatically skips publishing if the version exists. Bump the version in package.json and try again.
Every package published via this workflow includes a provenance attestation that proves:
- Which GitHub repository published it
- Which workflow file was used
- The exact commit SHA
- When it was published
- The build environment details
Users can verify authenticity with:
npm audit signatures- Short-lived credentials (valid only for the workflow run)
- No static tokens to leak or compromise
- Authentication tied to specific repository and workflow
- Cryptographically verifiable publishing provenance
The --provenance flag ensures transparency in the software supply chain by:
- Recording where the package was built
- Linking the package to its source code
- Enabling verification of package authenticity
- Meeting SLSA (Supply Chain Levels for Software Artifacts) requirements
Follow Semantic Versioning:
- MAJOR: Breaking changes (e.g., 0.1.2 → 1.0.0)
- MINOR: New features, backward compatible (e.g., 0.1.2 → 0.2.0)
- PATCH: Bug fixes (e.g., 0.1.2 → 0.1.3)
Use npm version commands:
npm version patch # 0.1.2 → 0.1.3
npm version minor # 0.1.2 → 0.2.0
npm version major # 0.1.2 → 1.0.0