Skip to main content
Skip table of contents

Selecting NPM Private Registries at Repository Level in Renovate Using Presets

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 .npmrc definitions.

  • Minimal friction: Opt-in via an extends preset; no service restarts or global edits required.

Configuration overview

  1. Define environment variables for each approved registry endpoint and token (e.g., dev and release) on the Renovate worker.

  2. Map environment variables to Renovate secrets in config.js and define .npmrc strings from them.

  3. Set a secure default (e.g., release registry) in global config using npmrc, packageRules.

  4. Publish one preset per registry that overrides npmrc and registryUrls (via packageRules) to point to the alternate registry.

  5. 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):

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 -n when 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.* }}.

JS
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.

JS
  npmrc: "{{ secrets.NPMRC_RELEASE }}",

2.3 Package rules

Set default packageRules so Renovate resolves npm packages against the default registry by default.

JS
  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.

JS
  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:

JSON
{
  "$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:

JSON
{
  "$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 secrets only.

  • 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 -c to 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).

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.