Proxy Endpoints
All paths are relative to <proxy-url>, the base URL of the package proxy. Reproduce each one
exactly, trailing slash included or omitted as shown: the proxy routes every ecosystem identically, but
the clients differ over whether the configured value is a directory to append to or a base they add
their own leading slash to.
| Ecosystem | Endpoint | Authentication | Upstream |
|---|---|---|---|
| NuGet | /nuget/v3/index.json |
Basic, key as password | api.nuget.org |
| npm | /npm/ |
Bearer | registry.npmjs.org |
| PyPI | /pip/ |
Basic, key as password | pypi.org, files.pythonhosted.org |
| Maven | /maven/ |
Basic, key as password | repo1.maven.org |
| Go | /go |
Basic, in the GOPROXY URL |
proxy.golang.org |
| Cargo | /cargo/ |
Authorization header, Bearer prefix included in the stored token |
index.crates.io, crates.io |
| RubyGems | /rubygems |
Basic, key as password | rubygems.org |
| Dart | /dart |
Bearer | pub.dev |
| Composer | /composer |
Basic, key as password | repo.packagist.org, codeload.github.com |
| Hex | /hex |
Basic, key as password | repo.hex.pm |
| Container images | /v2/<registry>/ at the host root |
Basic, key as password | docker.io, ghcr.io, quay.io, mcr.microsoft.com, cgr.dev, dhi.io |
Authentication
Section titled “Authentication”The proxy accepts the API key two ways, and clients pick whichever their ecosystem uses:
- Basic, usually with the key as the password. The username is not checked; if the password is empty, the proxy falls back to a non-empty username (used by some NuGet clients).
- Bearer, with the key as the token.
Missing or malformed credentials receive 401 and a WWW-Authenticate challenge. A well-formed credential containing an invalid or expired key receives 403 on non-Dart routes. Dart routes instead return 401 with a pub-format error: authentication_required for missing/malformed credentials or invalid_token for an invalid key.
The API key determines the workspace and project used for proxy requests. Proxy clients do not need to send tenant or workspace headers.
Notes per ecosystem
Section titled “Notes per ecosystem”Cargo uses the sparse protocol, so the configured value is sparse+<proxy-url>/cargo/ rather than the bare path. Cargo forwards the stored token verbatim, so the Bearer prefix has to be part of the token value.
Go has no credential store for module proxies, so the key is embedded in GOPROXY. Go refuses credentials over HTTP, so this endpoint requires HTTPS in any authenticated configuration.
npm supports audit requests with POST under /npm/-/npm/v1/security/, served from the same upstream.
PyPI serves package files from a second upstream: /pip/packages/ proxies files.pythonhosted.org, while /pip/ serves the simple index.
Cargo serves the sparse index and registry downloads under /cargo/, and the crates.io API under /cargo/api/. Both routes currently accept GET, HEAD, OPTIONS, and TRACE.
Maven proxies Maven Central. The Gradle Plugin Portal is a separate repository and is not served by this route.
Composer resolves metadata from Packagist but downloads archives from the code host. The proxy rewrites GitHub archive URLs to /composer/dist/gh/ and strips the source entry, so neither the original download URL nor a Git clone can bypass it. Packagist publishes GitHub’s api.github.com archive endpoint, which answers a redirect and is rate limited to 60 unauthenticated requests an hour; the proxy resolves straight to codeload.github.com so the transfer stays inside the proxy and is not rate limited. Archives hosted outside GitHub are not served today. Composer security-advisory requests are also proxied with POST under /composer/api/security-advisories/. --prefer-source, a composer.lock generated before the proxy was configured, and vcs, package, path or artifact repositories declared in composer.json all resolve independently of the configured repository and never reach the proxy.
Dart honours PUB_HOSTED_URL. Dependencies declaring an explicit hosted: URL, and Git, path, and SDK dependencies, resolve independently of it and never reach the proxy.
Hex passes signed registry metadata and package archives through unchanged from repo.hex.pm. Mix and Rebar3 dependencies resolved from a public, Git, or path source do not use this route.
Container images are served at /v2/ at the root of the proxy host, because container runtimes address a registry at its host rather than under a path. The registry is the first segment of the image name (/v2/docker.io/library/nginx/...), and only the registries listed in the table are served. Manifests, blobs, and the OCI referrers API (/v2/<registry>/<repository>/referrers/<digest>) are served; pushes are refused. Image layers are handed to the client as the registry’s short-lived signed download URLs in redirect mode, or streamed through the proxy in passthrough mode.