Consumer Auth — @bloomsparkagency/core via GitHub Packages
@bloomsparkagency/core is distributed through GitHub Packages (npm registry at https://npm.pkg.github.com/). Because GitHub Packages requires authentication even for read-only access, consumers must configure an auth token before running npm install or pnpm install.
Option A: GITHUB_TOKEN (GitHub Actions)
When running inside a GitHub Actions workflow that belongs to the same organization as this package, use the built-in GITHUB_TOKEN — no additional secrets are needed.
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://npm.pkg.github.com
scope: '@bloomsparkagency'
- name: Install dependencies
run: npm install
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}The actions/setup-node step writes the registry and auth stanza to ~/.npmrc automatically when registry-url and scope are set, so you do not need a checked-in .npmrc for CI.
Option B: Fine-grained PAT (developer machines)
1. Create a GitHub Personal Access Token
Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens and create a token with at minimum:
| Permission | Access |
|---|---|
| Packages | Read |
Classic tokens need only the read:packages scope.
2. Add an .npmrc to your project root
@bloomsparkagency:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
always-auth=trueNever hard-code the token value. Use the ${NODE_AUTH_TOKEN} placeholder and supply the value through an environment variable.
3. Export the token in your shell
export NODE_AUTH_TOKEN=ghp_your_token_hereAdd this to your shell profile (~/.zshrc, ~/.bashrc, or ~/.profile) so it persists across sessions.
4. Install the package
# npm
npm install @bloomsparkagency/core
# pnpm
pnpm add @bloomsparkagency/core
# yarn
yarn add @bloomsparkagency/coreOption C: OIDC token exchange (AWS CodeBuild / GitLab CI / CircleCI)
CI systems that issue OIDC JWTs (AWS CodeBuild, GitLab CI, CircleCI) can exchange the short-lived OIDC token for a GitHub App installation access token without storing long-lived PATs as secrets.
Use tools/oidc-pat-exchange.mjs — a zero-dependency Node.js ESM script that performs the RS256-signed GitHub App JWT flow and prints NODE_AUTH_TOKEN=<token> to stdout.
Required environment variables
| Variable | Description |
|---|---|
OIDC_TOKEN | OIDC JWT issued by your CI provider |
GITHUB_APP_ID | Numeric GitHub App ID |
GITHUB_APP_PRIVATE_KEY | PEM-encoded RSA private key for the App |
GITHUB_INSTALLATION_ID | Installation ID for the target organization |
AWS CodeBuild example
# buildspec.yml
env:
variables:
GITHUB_APP_ID: "12345"
GITHUB_INSTALLATION_ID: "67890"
secrets-manager:
GITHUB_APP_PRIVATE_KEY: arn:aws:secretsmanager:us-east-1:123456789:secret:github-app-key
phases:
install:
runtime-versions:
nodejs: 20
commands:
- export OIDC_TOKEN=$(curl -s -H "Authorization: Bearer $AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" http://169.254.170.2 | jq -r .Token)
- eval $(node tools/oidc-pat-exchange.mjs)
- npm installGitLab CI example
install:
id_tokens:
OIDC_TOKEN:
aud: github-packages
script:
- eval $(node tools/oidc-pat-exchange.mjs)
- npm install
variables:
GITHUB_APP_ID: "12345"
GITHUB_INSTALLATION_ID: "67890"
GITHUB_APP_PRIVATE_KEY: $GITHUB_APP_PRIVATE_KEY_SECRETCircleCI example
jobs:
install:
steps:
- run:
name: Exchange OIDC token for GitHub App token
command: |
eval $(node tools/oidc-pat-exchange.mjs)
npm install
environment:
GITHUB_APP_ID: "12345"
GITHUB_INSTALLATION_ID: "67890"How it works
- Validates all required env vars are present; exits 1 with a message if any are missing.
- Decodes the OIDC JWT (base64url) and checks the
expclaim is not expired; exits 1 if expired. - Generates a GitHub App JWT signed with RS256 (
iat: now-60,exp: now+600). - Calls
POST https://api.github.com/app/installations/${GITHUB_INSTALLATION_ID}/access_tokens. - Prints
NODE_AUTH_TOKEN=<token>to stdout for use witheval.
Verifying package provenance
All @bloomsparkagency/* packages are published with npm provenance attestation. This links each published tarball to the exact GitHub Actions workflow run and source commit that produced it.
Run the following after install to verify every package was built from this repository:
npm audit signaturesA passing result confirms no package was tampered with between the CI build and the registry.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
401 Unauthorized | Token missing or expired | Re-generate PAT; check NODE_AUTH_TOKEN is exported |
403 Forbidden | Token lacks read:packages scope | Add the scope to the PAT |
404 Not Found | Wrong registry URL in .npmrc | Verify the .npmrc stanza matches the example above |
ENEEDAUTH | No .npmrc found | Add .npmrc to the project root |
| OIDC script exits 1 with "expired" | OIDC JWT TTL is too short | Re-fetch the token immediately before running the script |
| OIDC script exits 1 with "GitHub API returned 401" | App JWT signing failed | Verify GITHUB_APP_PRIVATE_KEY is a valid PEM RSA key |
