Safeguard
Developer Tools•

How should pip authenticate to a private index: URL, netrc or keyring?

pip accepts credentials in the index URL, from a netrc file or from the keyring. A comparison of the three for laptops and CI in a small team.

Safeguard Security Team
3 min read

For laptops, prefer the keyring or a netrc file kept outside the repository. For CI, inject a token at run time from your secret store. Putting credentials in the index URL works, but the URL tends to land in config files, shell history and logs, so use it carefully.

The three options in pip

The pip authentication documentation describes three routes.

First, credentials in the index URL, in the form user and password before the host. Single token indexes use the token as the username with no password. Special characters in the credential must be percent-encoded.

Second, a netrc file. If the URL has no credentials, pip looks up the hostname in the user's netrc file. The docs say only ASCII is allowed and passwords cannot contain whitespace or non-printable characters.

Third, the keyring. It is enabled with a keyring provider option that accepts auto, disabled, import or subprocess. The keyring package must be installed separately from pip, which can create a bootstrapping problem. The subprocess mode needs a username in the URL.

Comparison for a small team

MethodWhere the secret livesStrengthsWatch out for
Credentials in URLConfig file, environment or command lineSimple, works everywhereEasy to leak into logs and history
netrcA file in the home directoryKeeps the URL cleanFile permissions, plain text on disk
KeyringOS credential storeNot in plain filesNeeds extra package, can hang tools that hide output

The docs do not explicitly warn against URL credentials, but the reasoning is ordinary. Anything that prints the URL prints the secret.

Practical setup

For a developer laptop:

  1. Install the keyring package in the tool environment you use for pip.
  2. Store the credential once under your username.
  3. Set the keyring provider in pip config or through its environment variable.

For CI:

  1. Create a read-only token for the mirror, scoped to the repositories the job needs.
  2. Store it in the CI secret store, not the repository.
  3. Write a netrc file at job start or set the index URL variable from the secret, then remove it at job end.
  4. Mask the value in logs.
  5. Rotate on a schedule and whenever a maintainer with access leaves.

Setting the provider to not prompt also matters. The docs note that with no-input set, automatic mode skips the keyring, and that forcing keyring use can make wrapper tools appear to hang because they hide pip's output.

Check what leaks

Run your install with verbose logging in a scratch job and read the output. If the full index URL with credentials appears, change the method or add masking. Also check your container build logs, since a build argument holding a URL can be stored in image history.

Where Safeguard fits

Safeguard's SBOM and dependency scanning works from project inventory and does not need your registry credentials to list what a project depends on. A free scan is at gold.safeguard.sh/scan.

Quick check

Is a token in the index URL safer than a password?

A scoped token limits damage if it leaks, but the leak risk from the URL itself is the same.

Why did my pip command hang after enabling keyring?

Wrapper tools can hide the prompt keyring waits on. The pip docs mention this for tools such as pipx and Pipenv.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.