Skip to content

feat: support cargo:token-from-stdout in private registries#2528

Merged
NobodyXu merged 5 commits intocargo-bins:mainfrom
garysassano:token-from-stdout-provider
Apr 8, 2026
Merged

feat: support cargo:token-from-stdout in private registries#2528
NobodyXu merged 5 commits intocargo-bins:mainfrom
garysassano:token-from-stdout-provider

Conversation

@garysassano
Copy link
Copy Markdown
Contributor

Addresses #2312

Summary

This PR adds phase-2 private registry authentication support to cargo-binstall.

In this PR, "phase 2" means extending the existing private-registry auth support from cargo:token to Cargo's built-in cargo:token-from-stdout provider, without yet taking on the full external credential-process surface area.

Concretely, phase 2 includes:

  • cargo:token-from-stdout
  • credential-alias resolution for cargo:token-from-stdout
  • Cargo-compatible provider selection and precedence
  • preserving --registry / --index during cargo install fallback

Phase 2 still does not include:

  • generic external credential-process providers using Cargo's JSON protocol
  • OS-native Cargo credential providers

The main goal is to make private registry flows work in the same cases where cargo install already works with cargo:token-from-stdout, especially for registries like AWS CodeArtifact that mint short-lived tokens on demand through an external command.

What Changed

cargo:token-from-stdout support

  • Refactor private-registry credential selection from a cargo:token boolean check into explicit provider resolution
  • Add support for Cargo's built-in cargo:token-from-stdout provider
  • Support both provider forms Cargo accepts:
    • space-separated string values
    • array values
  • Resolve credential-alias before deciding whether the effective provider enables the token path
  • Respect Cargo's precedence rules:
    • registry-specific env override
    • registry-specific config
    • registry.global-credential-providers, with later entries winning
  • Treat built-in cargo:* provider names as built-ins, not alias targets

Provider execution behavior

  • Execute the configured command and read the token from stdout
  • Match Cargo's single-line token behavior
  • Replace {index_url} in subprocess arguments
  • Set:
    • CARGO_REGISTRY_INDEX_URL
    • CARGO_REGISTRY_NAME_OPT

Fallback behavior

  • Keep the existing fallback fix from phase 1: when cargo-binstall falls back to cargo install, it preserves the selected registry or index instead of silently defaulting back to crates.io

Real Validation

Validated manually against AWS CodeArtifact using a sparse private registry configured with credential-provider = "cargo:token-from-stdout ..." and no pre-stored login requirement.

Validation flow:

  1. Configure a CodeArtifact registry with cargo:token-from-stdout
  2. Verify plain cargo install --registry private-test ...
  3. Verify cargo-binstall --registry private-test ...
  4. Verify cargo-binstall --force falls back using the same private registry

Observed result:

  • plain Cargo succeeded with cargo:token-from-stdout
  • cargo-binstall resolved the crate from CodeArtifact without 401 Unauthorized
  • fallback to cargo install preserved --registry private-test
  • the fallback install completed successfully

Test Commands

cargo test -p cargo-binstall --lib registry_auth
cargo fmt --check

Manual CodeArtifact smoke test:

cargo uninstall codeartifact-smoke || true
cargo install --registry private-test codeartifact-smoke --version 0.1.0
cargo run -p cargo-binstall -- --registry private-test codeartifact-smoke@0.1.0 -y --force

Example registry configuration used for validation:

[registries.private-test]
index = "sparse+https://<domain>-<account>.d.codeartifact.<region>.amazonaws.com/cargo/<repo>/"
credential-provider = [
  "cargo:token-from-stdout",
  "aws", "codeartifact", "get-authorization-token",
  "--domain", "<domain>",
  "--domain-owner", "<account>",
  "--region", "<region>",
  "--query", "authorizationToken",
  "--output", "text",
]

Copy link
Copy Markdown
Member

@NobodyXu NobodyXu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Got one question for doc of {index_url}, one feedback that CARGO env might not set, and one feedback on code

@garysassano garysassano force-pushed the token-from-stdout-provider branch from 704c670 to c1362a4 Compare April 6, 2026 14:05
@garysassano garysassano force-pushed the token-from-stdout-provider branch from c1362a4 to fedf4cf Compare April 6, 2026 14:06
Copy link
Copy Markdown
Member

@NobodyXu NobodyXu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, just minor nit on doc and a missing optimization

Copy link
Copy Markdown
Member

@NobodyXu NobodyXu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've just identified a bug in line splitting on windows due to missing \r\n handling, and then some feedback on code

Copy link
Copy Markdown
Member

@NobodyXu NobodyXu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM

@NobodyXu NobodyXu added this pull request to the merge queue Apr 8, 2026
Merged via the queue into cargo-bins:main with commit 6ed12bb Apr 8, 2026
25 checks passed
@github-actions github-actions bot mentioned this pull request Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants