GitHub Actions Secrets Configuration Guide
Complete guide for configuring secrets required by OpenPets GitHub Actions workflows.
Quick Reference
Set Token Locally (for testing)
# 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 ~/.npmrcAdd to GitHub (for CI/CD)
- Generate Granular Access Token at: https://www.npmjs.com/settings/[username]/tokens
- Packages: Read and write
- Organizations: Read and write
- Add to GitHub: Settings → Secrets → Actions → New repository secret
- Name:
NPM_TOKEN - Value: Your token (starts with
npm_...)
- Name:
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:
- Generate a new Granular Access Token (see instructions below)
- Update the
NPM_TOKENGitHub secret - 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 mainpublish-single-pet.yml- Manual pet publishingpublish.yml- General publish workflow
How to get an NPM Token:
Log in to npm
bashnpm loginOr visit: https://www.npmjs.com/login
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)
- Token name:
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
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
@openpetsorganization
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
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_...
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)
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@openpetsscope - 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_TOKENwhen rotating
Configuring Secrets in GitHub
Step 1: Navigate to Repository Settings
- Go to your GitHub repository:
https://github.com/[username]/openpets - Click Settings (top navigation)
- In the left sidebar, navigate to Secrets and variables → Actions
Step 2: Add Repository Secret
- Click "New repository secret"
- Enter the secret details:
- Name:
NPM_TOKEN - Value: Paste your npm token (starts with
npm_...)
- Name:
- 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:
permissions:
contents: read # Read repository contents
packages: write # Write to GitHub Packages
id-token: write # OIDC token generationNote: 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:
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
@openpetsorganization - Have publish permissions for the organization
3. Grant Organization Access
If you own the organization:
npm access grant read-write openpets:developers [username]4. Verify Organization Access
npm access list collaborators @openpets
npm owner ls @openpets/semantic-scholarSetting Token in CLI
Method 1: Direct .npmrc Configuration (Recommended for Testing)
Set the token directly in your npm configuration file:
# 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 ~/.npmrcMethod 2: Project-Specific .npmrc
For project-specific configuration (NOT recommended - can leak secrets):
# In your project root (e.g., /openpets)
echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" > .npmrc
# CRITICAL: Ensure .npmrc is in .gitignore
echo ".npmrc" >> .gitignoreWARNING: Never commit .npmrc with tokens to git!
Method 3: Environment Variable (Temporary)
Set token as environment variable for current session:
# 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}" > ~/.npmrcMethod 4: Interactive Login (Alternative)
Instead of using tokens, you can log in interactively:
# Log in with username/password (uses 2FA if enabled)
npm login
# Verify login
npm whoamiNote: Interactive login creates a token automatically in ~/.npmrc.
Testing Token Locally
Before setting up GitHub Actions, test your token locally:
Test 1: Verify Authentication
# 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 expiredTest 2: Verify Organization Access
# 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 lsTest 3: Test Package Build
# 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-*.tgzTest 4: Dry Run Publish
# Test publish without actually publishing
npm publish --dry-run
# Should show what would be published without errorsClean Up After Testing
# 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 ~/.npmrcSecurity 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
- Monitor npm package downloads for anomalies
- Check npm audit logs: https://www.npmjs.com/settings/[username]/audit-log
- Review GitHub Actions logs for failed authentications
Troubleshooting
Error: "Access token expired or revoked"
Solution:
- Generate a new npm token (see above)
- Update GitHub secret
NPM_TOKENwith new value - 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:
- Verify you're a member of
@openpetsorganization - Verify token has publish permissions
- 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.ymlworkflow now includesid-token: writepermission - If you forked before this fix, pull latest changes
Workflow doesn't trigger
Check:
- Workflow file is in
.github/workflows/ - Workflow has correct trigger conditions (
on: push: branches: [main]) - You pushed to the correct branch
- Check Actions tab for disabled workflows
Npm Token Types Comparison
| Token Type | Status | Use Case | CI/CD | Provenance | Expiry |
|---|---|---|---|---|---|
| Classic | ❌ DEPRECATED | Manual publishing | ❌ No | ❌ No | Revoked |
| Automation | ❌ DEPRECATED | CI/CD | ✅ Yes | ✅ Yes | Revoked |
| Granular | ✅ CURRENT | All uses (REQUIRED) | ✅ Yes | ✅ Yes | 30-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
- Token management: https://docs.npmjs.com/about-access-tokens
- Publishing with provenance: https://docs.npmjs.com/generating-provenance-statements
- Organization management: https://docs.npmjs.com/organizations
GitHub Documentation
- Encrypted secrets: https://docs.github.com/en/actions/security-guides/encrypted-secrets
- Workflow permissions: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
- OIDC tokens: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
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
@openpetsorganization - [ ] 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_TOKENto 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:
- Check this guide's troubleshooting section
- Review GitHub Actions logs in the Actions tab
- Verify npm token permissions
- Check npm audit logs for authentication issues
- Open an issue in the repository with error details
Never share your npm token in issues or support requests!