Skip to content

GitHub Actions Secrets Configuration Guide

Complete guide for configuring secrets required by OpenPets GitHub Actions workflows.

Quick Reference

Set Token Locally (for testing)

bash
# Set token in .npmrc
echo "//registry.npmjs.org/:_authToken=YOUR_TOKEN" > ~/.npmrc
chmod 600 ~/.npmrc

# Verify
npm whoami
npm access list packages @openpets

# Clean up after testing
rm ~/.npmrc

Add to GitHub (for CI/CD)

  1. Generate Granular Access Token at: https://www.npmjs.com/settings/[username]/tokens
    • Packages: Read and write
    • Organizations: Read and write
  2. Add to GitHub: Settings → Secrets → Actions → New repository secret
    • Name: NPM_TOKEN
    • Value: Your token (starts with npm_...)

Overview

The OpenPets repository uses GitHub Actions for automated validation, testing, and publishing. These workflows require certain secrets to be configured in your GitHub repository settings.

NPM Security Update (2024-2025)

IMPORTANT: npm has deprecated Classic and Automation tokens. All tokens must now be Granular Access Tokens with:

  • Maximum 90-day expiration (tokens must be rotated regularly)
  • Two-factor authentication required by default
  • Fine-grained permissions for packages and organizations

If your workflows are failing with "Access token expired or revoked", you need to:

  1. Generate a new Granular Access Token (see instructions below)
  2. Update the NPM_TOKEN GitHub secret
  3. Set a reminder to rotate the token before expiration

Required Secrets

1. NPM_TOKEN (CRITICAL)

Purpose: Authenticate with npm registry to publish packages to the @openpets scope

Required for workflows:

  • auto-publish.yml - Auto-publishes changed pets on merge to main
  • publish-single-pet.yml - Manual pet publishing
  • publish.yml - General publish workflow

How to get an NPM Token:

  1. Log in to npm

    bash
    npm login

    Or visit: https://www.npmjs.com/login

  2. Generate a Granular Access Token

    • Go to https://www.npmjs.com/settings/[your-username]/tokens
    • Click "Generate New Token" → Select "Granular Access Token"
    • Fill in the General section:
      • Token name: Pets deployment (or your preferred name)
      • Description: Optional description of what this token is for
      • Check "Bypass two-factor authentication (2FA)" to allow CI/CD publishing without OTP prompts
      • Allowed IP ranges: Leave empty (optional, for additional security)
  3. Configure Packages and Scopes Permissions (CRITICAL)

    • Under "Packages and scopes" section:
    • Click the "Permissions" dropdown
    • Select "Read and write" (required for publishing)
    • This grants permission to publish to packages under your account
  4. Configure Organizations Permissions (CRITICAL)

    • Under "Organizations" section:
    • Click the "Permissions" dropdown
    • Select "Read and write" (required for @openpets scope)
    • This grants permission to publish to the @openpets organization
  5. Set Expiration

    • Under "Expiration" section:
    • Default is 30 days (npm now requires tokens to expire)
    • Choose your preferred expiration (30, 60, or 90 days max)
    • IMPORTANT: You'll need to regenerate and update GitHub secrets before expiration
  6. Generate Token

    • Click "Generate token" button at the bottom
    • CRITICAL: Copy the token immediately - it won't be shown again!
    • Token will start with npm_...
  7. Token Requirements Summary

    • Token type: Granular Access Token (Classic/Automation tokens are deprecated)
    • Packages permissions: Read and write
    • Organizations permissions: Read and write (for @openpets scope)
    • 2FA bypass: Enabled (required for CI/CD publishing without OTP)
    • Expiration: 30-90 days (required by npm)
  8. Verify Token Permissions

    bash
    # Test the token locally (IMPORTANT: Test before adding to GitHub)
    echo "//registry.npmjs.org/:_authToken=YOUR_TOKEN" > ~/.npmrc
    npm whoami
    # Should output your npm username
    
    # Verify organization access (CRITICAL for @openpets publishing)
    npm access list packages @openpets
    # Should list packages you have access to, or succeed without error
    
    # Clean up test token from local machine
    rm ~/.npmrc

Common Issues:

  • Access token expired or revoked → Token expired (max 90 days), regenerate and update GitHub secret
  • 403 Forbidden → Token doesn't have "Read and write" permissions for Organizations
  • 404 Not Found → Token doesn't have access to @openpets scope - check Organizations permissions
  • Provenance generation requires "write" access to "id-token" → Workflow permission issue (see below)

Token Rotation Reminder:

  • ⚠️ Granular tokens expire after 30-90 days
  • Set a calendar reminder to regenerate before expiration
  • Update GitHub secret NPM_TOKEN when rotating

Configuring Secrets in GitHub

Step 1: Navigate to Repository Settings

  1. Go to your GitHub repository: https://github.com/[username]/openpets
  2. Click Settings (top navigation)
  3. In the left sidebar, navigate to Secrets and variablesActions

Step 2: Add Repository Secret

  1. Click "New repository secret"
  2. Enter the secret details:
    • Name: NPM_TOKEN
    • Value: Paste your npm token (starts with npm_...)
  3. Click "Add secret"

Step 3: Verify Secret is Set

  • The secret should appear in the list as NPM_TOKEN
  • You won't be able to view the value again (only update or delete)
  • Workflows will now have access to this secret via ${{ secrets.NPM_TOKEN }}

Workflow Permissions

In addition to secrets, workflows need specific permissions configured.

Required Permissions (Already Configured)

The auto-publish.yml workflow requires:

yaml
permissions:
  contents: read      # Read repository contents
  packages: write     # Write to GitHub Packages
  id-token: write     # OIDC token generation

Note: Provenance (--provenance) is not currently used because the repository is private. npm provenance requires a public source repository. The id-token: write permission is retained for future use if the repo becomes public.


Optional Secrets

GITHUB_TOKEN (Automatic)

Purpose: GitHub automatically provides this token to workflows

No configuration needed - GitHub Actions automatically creates a GITHUB_TOKEN for each workflow run.

Usage in workflows:

yaml
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Permissions: Determined by repository settings and workflow configuration


Npm Organization Setup

To publish to the @openpets scope, ensure:

1. Organization Exists

Visit: https://www.npmjs.com/org/openpets

2. User Permissions

Your npm account must be:

  • A member of the @openpets organization
  • Have publish permissions for the organization

3. Grant Organization Access

If you own the organization:

bash
npm access grant read-write openpets:developers [username]

4. Verify Organization Access

bash
npm access list collaborators @openpets
npm owner ls @openpets/semantic-scholar

Setting Token in CLI

Set the token directly in your npm configuration file:

bash
# Create/update .npmrc in your home directory
echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" > ~/.npmrc

# Or append to existing .npmrc
echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" >> ~/.npmrc

# Set proper permissions (important for security)
chmod 600 ~/.npmrc

Method 2: Project-Specific .npmrc

For project-specific configuration (NOT recommended - can leak secrets):

bash
# In your project root (e.g., /openpets)
echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" > .npmrc

# CRITICAL: Ensure .npmrc is in .gitignore
echo ".npmrc" >> .gitignore

WARNING: Never commit .npmrc with tokens to git!

Method 3: Environment Variable (Temporary)

Set token as environment variable for current session:

bash
# Set for current shell session
export NPM_TOKEN="your_npm_token_here"

# Configure npm to use it
npm config set //registry.npmjs.org/:_authToken=${NPM_TOKEN}

# Or use directly with npm commands
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc

Method 4: Interactive Login (Alternative)

Instead of using tokens, you can log in interactively:

bash
# Log in with username/password (uses 2FA if enabled)
npm login

# Verify login
npm whoami

Note: Interactive login creates a token automatically in ~/.npmrc.


Testing Token Locally

Before setting up GitHub Actions, test your token locally:

Test 1: Verify Authentication

bash
# After setting token in CLI (see "Setting Token in CLI" above)
npm whoami
# Should output: your-npm-username

# If this fails, your token is invalid or expired

Test 2: Verify Organization Access

bash
# Check you have access to @openpets organization
npm access list packages @openpets

# Check who can publish to a specific package
npm owner ls @openpets/semantic-scholar

# List all organizations you belong to
npm org ls

Test 3: Test Package Build

bash
# Navigate to a pet directory
cd pets/semantic-scholar

# Create a tarball (doesn't publish, just packages)
npm pack
# Should create: openpets-semantic-scholar-x.x.x.tgz

# Inspect what will be published
tar -tzf openpets-semantic-scholar-*.tgz

# Clean up
rm openpets-semantic-scholar-*.tgz

Test 4: Dry Run Publish

bash
# Test publish without actually publishing
npm publish --dry-run

# Should show what would be published without errors

Clean Up After Testing

bash
# Remove token from local machine (IMPORTANT for security)
rm ~/.npmrc

# Or remove just the auth line
sed -i '' '/registry.npmjs.org\/:_authToken/d' ~/.npmrc

# Verify token is removed
cat ~/.npmrc

Security Best Practices

1. Token Security

  • ✅ Use Granular Access tokens for CI/CD (not Classic tokens)
  • ✅ Store tokens only in GitHub Secrets (never in code)
  • ✅ Rotate tokens every 90 days
  • ✅ Revoke tokens immediately if compromised
  • ✅ Use separate tokens for different services

2. Access Control

  • ✅ Limit token scope to minimum required permissions
  • ✅ Use organization-level tokens when possible
  • ✅ Review token access regularly
  • ❌ Never commit tokens to git (pre-commit hooks prevent this)
  • ❌ Never share tokens via Slack/email

3. Monitoring


Troubleshooting

Error: "Access token expired or revoked"

Solution:

  1. Generate a new npm token (see above)
  2. Update GitHub secret NPM_TOKEN with new value
  3. Re-run failed workflow

Error: "404 Not Found - PUT https://registry.npmjs.org/@openpets%2Fpet-name"

Cause: Token doesn't have access to @openpets scope

Solution:

  1. Verify you're a member of @openpets organization
  2. Verify token has publish permissions
  3. Check: npm access list packages @openpets

Error: "Provenance generation requires write access to id-token permission"

Solution: Already fixed in commit 96d69ad

  • The auto-publish.yml workflow now includes id-token: write permission
  • If you forked before this fix, pull latest changes

Workflow doesn't trigger

Check:

  1. Workflow file is in .github/workflows/
  2. Workflow has correct trigger conditions (on: push: branches: [main])
  3. You pushed to the correct branch
  4. Check Actions tab for disabled workflows

Npm Token Types Comparison

Token TypeStatusUse CaseCI/CDProvenanceExpiry
Classic❌ DEPRECATEDManual publishing❌ No❌ NoRevoked
Automation❌ DEPRECATEDCI/CD✅ Yes✅ YesRevoked
Granular✅ CURRENTAll uses (REQUIRED)✅ Yes✅ Yes30-90 days

IMPORTANT: As of npm's security update, Classic and Automation tokens have been revoked. You MUST use Granular Access Tokens with:

  • Packages permissions: Read and write
  • Organizations permissions: Read and write (for @openpets)
  • Expiration: Maximum 90 days (you'll need to rotate tokens regularly)

Additional Resources

npm Documentation

GitHub Documentation

OpenPets Documentation

  • Publishing workflow: .github/workflows/auto-publish.yml
  • Security scan: scripts/security-scan.ts
  • Pre-commit hooks: .husky/pre-commit

Quick Setup Checklist

For new repository maintainers:

  • [ ] Create npm account at https://www.npmjs.com/signup
  • [ ] Request access to @openpets organization
  • [ ] Generate Granular Access Token at https://www.npmjs.com/settings/[username]/tokens
    • [ ] Set Packages and scopes permissions to "Read and write"
    • [ ] Set Organizations permissions to "Read and write"
    • [ ] Choose expiration (30-90 days)
    • [ ] Check "Bypass 2FA" (required for CI/CD publishing)
  • [ ] Test token locally: npm whoami
  • [ ] Verify organization access: npm access list packages @openpets
  • [ ] Add NPM_TOKEN to GitHub repository secrets
  • [ ] Verify workflow permissions include id-token: write
  • [ ] Test by publishing a pet or triggering workflow manually
  • [ ] Monitor Actions tab for successful runs
  • [ ] Set calendar reminder to rotate token before expiration (30-90 days)

Support

If you encounter issues:

  1. Check this guide's troubleshooting section
  2. Review GitHub Actions logs in the Actions tab
  3. Verify npm token permissions
  4. Check npm audit logs for authentication issues
  5. Open an issue in the repository with error details

Never share your npm token in issues or support requests!