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
| Method | Where the secret lives | Strengths | Watch out for |
|---|---|---|---|
| Credentials in URL | Config file, environment or command line | Simple, works everywhere | Easy to leak into logs and history |
| netrc | A file in the home directory | Keeps the URL clean | File permissions, plain text on disk |
| Keyring | OS credential store | Not in plain files | Needs 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:
- Install the keyring package in the tool environment you use for pip.
- Store the credential once under your username.
- Set the keyring provider in pip config or through its environment variable.
For CI:
- Create a read-only token for the mirror, scoped to the repositories the job needs.
- Store it in the CI secret store, not the repository.
- Write a netrc file at job start or set the index URL variable from the secret, then remove it at job end.
- Mask the value in logs.
- 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.