"Public packages got auto-updated with Dependabot. But the internal npm registry, Artifactory, and ECR private images don't get updated" — a wall you always hit in enterprise. The cause decomposes into two. Does authentication (credentials) not pass, or is there no network reachability (network)? These two have completely different fixes.
This article comprehensively covers private-registry support at the implementation level, as a topic of the Dependabot production-operations guide. From per-type authentication to OIDC and self-hosted runners, it explains with settings usable as-is.
Rules for this article: the
registriestypes, authentication fields, and OIDC support are based on the GitHub official documentation (as of June 2026). Never hardcode credentials in the repository; pass them with Dependabot secrets. Always confirm the latest in the official private-registry configuration before production.
0. The two walls: authentication and reachability
| Wall | Symptom | How to clear it |
|---|---|---|
| Authentication | private_source_authentication_failure | The registries block + Dependabot secrets |
| Reachability | private_source_not_reachable / timed_out | A self-hosted runner (place the runner on the private network) |
A cloud managed registry (CodeArtifact, Artifact Registry, Artifactory SaaS) is a public endpoint + authentication, so only the "authentication wall." A registry unreachable from the internet, like inside a VPC, also needs to clear the "reachability wall." First discern which you have.
1. The basics of the registries block
Define registries at the top level of dependabot.yml and link it from each updates job.
version: 2
registries:
my-npm:
type: npm-registry
url: https://npm.example.com
token: ${{secrets.DEPENDABOT_NPM_TOKEN}} # ← Dependabot シークレットを参照
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
registries:
- my-npm # このジョブで使うレジストリ
Most important: what
${{secrets.NAME}}references is the Dependabot-dedicated secret store. The location is Settings → Secrets and variables → Dependabot (repository or organization). It's separate from regular Actions secrets, and Dependabot jobs can't see Actions secrets. This is a design to prevent "a compromised dependency stealing secrets via CI." Secrets are encrypted before reaching GitHub and stay encrypted until the moment Dependabot uses them.
2. Authentication reference by type
The usable authentication fields are fixed per type (official). Here's a table of the commonly used ones.
type | Main authentication fields | replaces-base | Note |
|---|---|---|---|
npm-registry | username/password or token | ✓ | npm/yarn/pnpm |
docker-registry | username/password, or static AWS auth for ECR | ✓ | Container images |
maven-repository | username/password, or OIDC (tenant-id/client-id) | ✓ | Maven/Gradle |
python-index | username/password, token, or OIDC | ✓ | pip/uv/poetry |
nuget-feed | username/password, token, or OIDC | ✗ | .NET |
rubygems-server | username/password or token | ✓ | Bundler |
composer-repository | username/password | — | PHP (GitHub PAT OK) |
cargo-registry | token (optionally registry) | — | Rust |
terraform-registry | token | — | Terraform |
git | username/password | — | Git-sourced dependencies |
helm-registry | username/password | — | HTTP Basic auth only, no OCI |
hex-organization | organization/key | — | Elixir |
hex-repository | repo/url/auth-key (optionally public-key-fingerprint) | — | Elixir self-hosted repo |
goproxy-server | username/password | — | Go module proxy |
pub-repository | url/token | — | Dart/Flutter |
replaces-base: truespecifies "use this private registry as the default instead of the public registry (e.g. registry.npmjs.org)." Use it when you want an internal mirror to be the sole fetch source.
3. GitHub Packages is "special" (no registries needed)
GitHub Packages / GitHub Container Registry (ghcr.io) don't need a registries entry written.
Official: "Dependabot can auto-authenticate with
GITHUB_TOKEN. This uses the same 'Manage Actions access' grant that GitHub Actions workflows use. No PAT or registry entry independabot.ymlis needed."
So internal packages placed in the same organization's GitHub Packages become update targets with zero additional configuration. Access is managed by the repository's "Manage Actions access." This is one of the biggest benefits of leaning into the GitHub ecosystem.
4. "Don't place static tokens" with OIDC
Static tokens/passwords come with the hassle of revocation management, leakage risk, and inventory. With an OIDC (OpenID Connect)-capable registry, you can authenticate with short-lived federation tokens and design it so you store no long-term secrets.
The OIDC-capable ones the official docs list are as follows.
- AWS CodeArtifact
- Azure DevOps Artifacts
- Cloudsmith
- Google Cloud Artifact Registry
- JFrog Artifactory
The form using tenant-id / client-id in maven-repository / python-index / nuget-feed, etc., applies. For both security and cost efficiency (reduced key-management operational load), make OIDC the first choice where possible. It's the same philosophy as keyless CI/CD.
5. Cloud-by-cloud examples
5.1 AWS CodeArtifact (npm / pip)
version: 2
registries:
codeartifact-npm:
type: npm-registry
url: https://my-domain-111122223333.d.codeartifact.ap-northeast-1.amazonaws.com/npm/my-repo/
token: ${{secrets.DEPENDABOT_CODEARTIFACT_TOKEN}}
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
registries: ["codeartifact-npm"]
CodeArtifact also supports OIDC, so where possible lean to OIDC federation rather than a static token.
5.2 Amazon ECR (Docker, static AWS auth)
registries:
ecr:
type: docker-registry
url: 111122223333.dkr.ecr.ap-northeast-1.amazonaws.com
username: ${{secrets.DEPENDABOT_AWS_ACCESS_KEY_ID}}
password: ${{secrets.DEPENDABOT_AWS_SECRET_ACCESS_KEY}}
docker-registry can use static AWS auth for pulling from ECR (a read-only least-privilege IAM is recommended). For Docker-base-image-update operations, head to the Docker base-image update guide.
5.3 JFrog Artifactory (npm example)
registries:
artifactory-npm:
type: npm-registry
url: https://artifactory.example.com/artifactory/api/npm/npm-virtual
username: ${{secrets.DEPENDABOT_ARTIFACTORY_USER}}
password: ${{secrets.DEPENDABOT_ARTIFACTORY_TOKEN}}
replaces-base: true
Artifactory supports OIDC too. The stricter the governance requirements, the more it's worth choosing OIDC.
6. The reachability wall: self-hosted runners
So far it's about "authentication." A registry reachable only inside a VPC / internal network simply doesn't reach from GitHub-hosted runners. In this case, run Dependabot on a self-hosted runner.
6.1 When it becomes necessary
- An internet-private internal Artifactory / Nexus / private PyPI / internal Go proxy
- CodeArtifact / Artifact Registry reachable only via a VPC endpoint
6.2 The key points of setup (official)
- Prerequisites: Dependabot enabled, GitHub Actions enabled.
- Prepare the runner: register a self-hosted runner at the repository or organization level.
- Meet the environment requirements: an execution environment where Dependabot jobs run (the needed tools, network).
- Attach the
dependabotlabel: for a single repository, thedependabotlabel; for an organization, the prescribed label.
A gotcha (must-read): when you enable this feature, Dependabot jobs run only on runners with the
dependabotlabel. Forgetting the label is a serious pitfall where jobs keep queuing forever (= it looks like nothing happens). Always verify "does a labeled runner truly exist" before enabling.
6.3 Network and security design
- Network: the runner can reach both GitHub and the target registry. Arrange the firewall/proxy allowlist.
- Isolation: a self-hosted runner is an execution environment where Dependabot can touch outside the trust boundary (the updated dependencies). Isolate it from other uses and operate it at least privilege (both network and credentials). Don't run it where it can touch production secrets.
7. Security checklist
- All credentials in Dependabot secrets (not in Actions secrets, not hardcoded)
- OIDC for capable registries (CodeArtifact / Azure Artifacts / Cloudsmith / Artifact Registry / Artifactory) to eliminate static tokens
- Tokens at least privilege, read-only (only the scope needed to fetch updates)
- Use
GITHUB_TOKENauto-authentication for GitHub Packages, don't create extra PATs - Self-hosted runners isolated, at least privilege, verify the
dependabotlabel - On an auth error, isolate with the four-category error codes
8. FAQ
Q. Where do I put the registries token? A. In Dependabot secrets (Settings → Secrets and variables → Dependabot). It's a separate store from Actions secrets, and Dependabot jobs can't reference Actions secrets.
Q. Do internal GitHub Packages packages also need a registries definition?
A. No. Dependabot auto-authenticates with GITHUB_TOKEN. Access is managed by "Manage Actions access."
Q. I don't want to place static tokens. A. With an OIDC-capable registry (CodeArtifact / Azure Artifacts / Cloudsmith / Google Artifact Registry / JFrog Artifactory), OIDC federation lets you avoid storing long-term secrets.
Q. I configured it but get private_source_not_reachable.
A. It's not authentication but a reachability problem. For a private-network registry, stand up a self-hosted runner and attach the dependabot label to it (without the label, jobs queue indefinitely).
Q. May I share the self-hosted runner with my usual CI runner? A. Not recommended. Operate the Dependabot one isolated, at least privilege, in an environment that can't touch production secrets.