This guide shows how to let repository owners choose which approved NPM private registry to use (e.g., dev vs. release or internal-only vs. virtual public mirror/cache) by opting into a preset while securely managing all tokens and endpoints at the platform level.
Why this matters
-
Developer flexibility: Repos can switch between approved registries (e.g., dev/release) without Ops changes.
-
Security first: Tokens never live in repo config; they are centrally injected and redacted.
-
Consistency: All repos use vetted registries with consistent
.npmrcdefinitions. -
Minimal friction: Opt-in via an
extendspreset; no service restarts or global edits required.
Configuration overview
-
Define environment variables for each approved registry endpoint and token (e.g., dev and release) on the Renovate worker.
-
Map environment variables to Renovate
secretsinconfig.jsand define.npmrcstrings from them. -
Set a secure default (e.g., release registry) in global config using
npmrc,packageRules. -
Publish one preset per registry that overrides
npmrcandregistryUrls(viapackageRules) to point to the alternate registry. -
Repo owners opt in by extending the desired preset, effectively routing package lookup to the alternate registry only for their repo.
Step 1: Runtime environment (examples)
Kubernetes (Helm values.yaml):
renovateWorker:
extraEnvVars:
- name: NPM_REGISTRY_DEV
value: "<https://company.jfrog.io/artifactory/api/npm/npm-dev/>"
- name: NPM_REGISTRY_DEV_TOKEN
valueFrom:
secretKeyRef:
name: mend-renovate-worker
key: artifactoryToken_dev
- name: NPM_REGISTRY_RELEASE
value: "<https://company.jfrog.io/artifactory/api/npm/npm-release/>"
- name: NPM_REGISTRY_RELEASE_TOKEN
valueFrom:
secretKeyRef:
name: mend-renovate-worker
key: artifactoryToken_rel
Notes:
-
Keep tokens only in your secret store. Confirm secret value has no trailing whitespace/newlines (e.g., use
echo -nwhen encoding to base64).
Step 2: Global config.js — break down
2.1 Secrets
Expose the runtime environment variables via secrets so they can be safely referenced in presets using {{ secrets.* }}.
module.exports = {
secrets: {
NPM_REGISTRY_DEV: process.env.NPM_REGISTRY_DEV,
NPM_REGISTRY_DEV_TOKEN: process.env.NPM_REGISTRY_DEV_TOKEN,
NPM_REGISTRY_RELEASE: process.env.NPM_REGISTRY_RELEASE,
NPM_REGISTRY_RELEASE_TOKEN: process.env.NPM_REGISTRY_RELEASE_TOKEN,
// npmrc strings built from the above
NPMRC_DEV: `registry=${process.env.NPM_REGISTRY_DEV}\n${process.env.NPM_REGISTRY_DEV.replace('https:', '')}:_authToken=${process.env.NPM_REGISTRY_DEV_TOKEN}`,
NPMRC_RELEASE: `registry=${process.env.NPM_REGISTRY_RELEASE}\n${process.env.NPM_REGISTRY_RELEASE.replace('https:', '')}:_authToken=${process.env.NPM_REGISTRY_RELEASE_TOKEN}`
},
2.2 npmrc
Define a global default .npmrc that all repos inherit unless they opt into an alternate preset.
npmrc: "{{ secrets.NPMRC_RELEASE }}",
2.3 Package rules
Set default packageRules so Renovate resolves npm packages against the default registry by default.
packageRules: [
{
matchDatasources: ["npm"],
matchManagers: ["npm"],
registryUrls: [process.env.NPM_REGISTRY_RELEASE]
}
],
2.4 Host rules
Provide tokens for all approved registries so Renovate can authenticate when resolving dependencies.
hostRules: [
{
hostType: "npm",
matchHost: process.env.NPM_REGISTRY_DEV,
token: process.env.NPM_REGISTRY_DEV_TOKEN
},
{
hostType: "npm",
matchHost: process.env.NPM_REGISTRY_RELEASE,
token: process.env.NPM_REGISTRY_RELEASE_TOKEN
}
]
};
Step 3: Create one preset per approved NPM registry
Example preset for the dev registry (dev-registry.json) in your shared renovate-config repo:
{
"$schema": "<https://docs.renovatebot.com/renovate-schema.json>",
"npmrc": "{{ secrets.NPMRC_DEV }}",
"packageRules": [
{
"matchDatasources": ["npm"],
"matchManagers": ["npm"],
"registryUrls": ["{{ secrets.NPM_REGISTRY_DEV }}"]
}
]
}
-
npmrc: switches the active registry and sets the token via secrets.
-
packageRules: ensures Renovate resolves npm packages from the dev registry while this preset is active.
Create similar presets for other approved registries (e.g., release-registry.json if you want an explicit one).
Step 4: Repo opt-in via extends
Any repository can choose a different registry by extending the preset:
{
"$schema": "<https://docs.renovatebot.com/renovate-schema.json>",
"extends": [
"config:recommended",
"local>your-scm-org/renovate-config:dev-registry"
]
}
Only repos that opt in will use the alternate registry, otherwise, the default is used.
Security and governance
-
Secrets never in repos: Tokens are injected via environment and referenced through
secretsonly. -
Approved endpoints only: Presets reference known approved URLs. Developers cannot inject arbitrary registry hosts.
-
Visibility: Presets are viewable by repo owners in the shared config repo.
-
Scoped credentials: Use separate tokens per registry and scope them to least privilege.
-
Rotation-friendly: Rotate tokens centrally; repos inherit updated secrets automatically.
Troubleshooting tips
-
Auth errors: Verify secret values (no trailing newline). You can decode the K8s Secret and
od -cto spot hidden characters. -
Wrong registry: Confirm the repo actually extends the intended preset and Renovate logs show the chosen
registryUrls. -
404s: Ensure package exists in the selected registry (dev vs. release content can differ).