Skip to content

Cargo

The proxy implements the Cargo sparse registry protocol.

Endpoint: sparse+<proxy-url>/cargo/

Authentication: the API key, sent as the Authorization header. Cargo passes the stored token through verbatim, so the token value has to include the Bearer prefix itself.

Cargo does not have a mirror setting. Instead, crates.io is replaced as a source, in .cargo/config.toml:

[source.crates-io]
replace-with = "shieldedstack"
[source.shieldedstack]
registry = "sparse+<proxy-url>/cargo/"
[registries.shieldedstack]
index = "sparse+<proxy-url>/cargo/"
[registry]
global-credential-providers = ["cargo:token"]

Both the [source.*] and [registries.*] entries are needed: the first redirects crates.io resolution, the second is what the credential provider attaches a token to.

Terminal window
cargo login --registry shieldedstack "Bearer YOUR_API_KEY_HERE"

The Bearer prefix is part of the stored value, not something Cargo adds.

cargo login writes to CARGO_HOME, normally ~/.cargo/credentials.toml. That file is a secret and must not be committed.

For CI and other ephemeral environments, skip the credentials file entirely:

Terminal window
export CARGO_REGISTRIES_SHIELDEDSTACK_TOKEN="Bearer ${SHIELDEDSTACK_API_KEY}"
cargo fetch

Use HTTPS wherever the token is sent.

.cargo/config.toml holds no secret and should be committed as shown, so every checkout resolves through the proxy. Supply the token at runtime through CARGO_REGISTRIES_SHIELDEDSTACK_TOKEN rather than committing ~/.cargo/credentials.toml.

Terminal window
cargo fetch

The fetched crates appear under Packages in the Portal, attributed to the project name on the API key.

crates.io treats a crate’s name as case-insensitive and - and _ as the same character, so serde_json, serde-json and Serde_Json are one crate. A filter on any of them is saved and shown as serde-json and matches every spelling. The swap is one for one: serde__json is a different name, and dots are not folded. See Package names for how every ecosystem compares names.

401 or 403. The most common cause is a token stored without the literal Bearer prefix. Check CARGO_REGISTRIES_SHIELDEDSTACK_TOKEN or the stored credential.

Crates still come from crates.io. Confirm [source.crates-io] has replace-with = "shieldedstack" and that the sparse index entry is present.

cargo login cannot store or read a token. Confirm cargo:token is in global-credential-providers.

After key rotation. Replace the environment variable, or rerun cargo login --registry shieldedstack "Bearer YOUR_NEW_API_KEY".