Authenticate to Private Cargo Registries
Authenticate to private Cargo registries using Vouch
Vouch replaces the plaintext token in ~/.cargo/credentials.toml with tokens derived from your hardware-backed session – short-lived, never written to disk, and revoked when your session ends. Vouch implements the Cargo credential provider protocol (opens in new tab), so it works with any registry that supports Bearer token authentication.
TL;DR
- Prerequisites: Getting Started → this page.
- Admin, once: confirm your private registry meets the registry server requirements (Bearer token authentication).
- Each developer:
vouch setup cargo --configure, thencargo buildandcargo publishauthenticate automatically.
Prerequisites
Before configuring the Cargo integration, make sure you have:
- Cargo installed via rustup (opens in new tab) (version 1.74 or later, which includes credential provider protocol support)
- A private Cargo registry that supports Bearer token authentication
Step 1 – Configure Cargo Credential Provider
Developer taskRun the setup command to install the Vouch credential provider for Cargo:
vouch setup cargo
This prints the Cargo configuration that will be added. To apply it automatically:
vouch setup cargo --configure
To configure a specific named registry:
vouch setup cargo --registry my-private-registry --configure
The command adds the following to your ~/.cargo/config.toml:
[registry]
global-credential-providers = ["vouch"]
[registries.my-private-registry]
index = "sparse+https://cargo.example.com/index/"
credential-provider = ["vouch"]
The global-credential-providers setting registers Vouch as the default credential provider for all registries. You can also configure it per-registry using the credential-provider key under a specific [registries.*] section.
Step 2 – Use Cargo normally
Developer taskIf you are not logged in, run vouch login — one YubiKey tap starts an 8-hour session that every command below uses automatically.
With the credential provider configured and an active session, Cargo commands work without any extra flags or manual token management:
# Build a project that depends on private crates
cargo build
# Publish a crate to your private registry
cargo publish --registry my-private-registry
# Add a dependency from a private registry
cargo add my-crate --registry my-private-registry
# Update dependencies including private ones
cargo update
Vouch handles authentication transparently. You do not need to run cargo login or set any environment variables.
Private Registry Configuration
To use a private Cargo registry with Vouch, you need to define the registry in your Cargo configuration. Add the following to your project’s .cargo/config.toml or your global ~/.cargo/config.toml:
[registries.my-private-registry]
index = "sparse+https://cargo.example.com/index/"
credential-provider = ["vouch"]
If your Cargo.toml references dependencies from the private registry:
[dependencies]
my-crate = { version = "1.0", registry = "my-private-registry" }
Cargo will automatically call the Vouch credential provider when it needs to fetch or publish crates from this registry.
Registry server requirements
Admin taskThe private registry must support:
- Sparse index protocol (recommended) or Git index protocol
- Bearer token authentication via the
AuthorizationHTTP header - The token format issued by Vouch (a signed JWT)
Consult your registry server’s documentation to confirm Bearer token support.
How it works
When Cargo needs to authenticate to a private registry, it delegates to the Vouch credential provider:
- Cargo requests a token – Cargo calls the Vouch credential provider binary when it needs to authenticate to a configured private registry.
- Vouch exchanges your session – The credential provider contacts the Vouch server and exchanges your active hardware-backed session for a registry-scoped Bearer token.
- Token derived from your session – The token (a signed JWT) is scoped to the specific registry, expires when your session ends, and is never written to disk.
- Cargo authenticates – The Bearer token is sent to the registry as part of the HTTP request, and the operation proceeds.
Troubleshooting
Not authenticated
error: failed to get token for registry `my-private-registry`
caused by: not logged in to registry `my-private-registry`
- Verify you have an active Vouch session:
vouch login - Check that the Vouch agent is running:
vouch status - Confirm the credential provider is configured for the registry: inspect
~/.cargo/config.tomland verify thecredential-providerkey is set to["vouch"].
Cargo not using Vouch
If Cargo prompts you for a token or uses a different credential provider:
- Check your Cargo configuration for conflicting credential provider settings:
cargo config get registry.global-credential-providers - Ensure no
CARGO_REGISTRY_TOKENorCARGO_REGISTRIES_*_TOKENenvironment variables are set, as these override credential providers:env | grep CARGO_REGISTR - Re-run
vouch setup cargo --configureto ensure the configuration is correct.
Unsupported protocol version
error: credential provider `vouch` failed: unsupported credential provider protocol version
The Cargo credential provider protocol requires Cargo 1.74 or later. Check your Cargo version:
cargo --version
If your version is older than 1.74, update via rustup:
rustup update stable
Token not cached
If Vouch appears to request a new token for every Cargo operation (causing delays):
- This is expected behavior. Vouch derives tokens from your active session on each request rather than caching them to disk. The overhead is under 100ms.
- If latency is a concern, ensure the Vouch agent is running (
vouch status), as it keeps your session in memory for fast token derivation.
Multiple credential providers
If you have multiple credential providers configured and they conflict:
Check the provider order in
~/.cargo/config.toml:[registry] global-credential-providers = ["vouch", "cargo:token"]Cargo tries providers in order. Place
vouchfirst to ensure it is used before any fallback providers.To use Vouch for only specific registries, remove it from
global-credential-providersand set it per-registry instead:[registries.my-private-registry] credential-provider = ["vouch"]