Skip to content

cargo: strip per-registry credential-provider from .cargo/config.toml#14356

Closed
jeffwidman wants to merge 1 commit intomainfrom
fix-cargo-private-registry-auth
Closed

cargo: strip per-registry credential-provider from .cargo/config.toml#14356
jeffwidman wants to merge 1 commit intomainfrom
fix-cargo-private-registry-auth

Conversation

@jeffwidman
Copy link
Member

Summary

Fix cargo private registry authentication failures when .cargo/config.toml contains per-registry credential-provider settings.

Fixes #14354
Related: #14094, #14030

Problem

PR #14340 disabled Cargo's global credential providers by setting CARGO_REGISTRY_GLOBAL_CREDENTIAL_PROVIDERS="", relying on the dependabot proxy for all private registry auth. However, this only affects the global default.

When a user's .cargo/config.toml contains per-registry credential-provider settings:

[registries.artifactory]
index = "sparse+https://example.com/api/cargo/cargo-local/index/"
credential-provider = "cargo:token"

Cargo ignores the global empty string and invokes the per-registry provider, which looks for CARGO_REGISTRIES_{NAME}_TOKEN env vars that no longer exist (removed in #14030), causing:

Credential cargo:token get artifactory-remote
no token found for `artifactory-remote`

Solution

Strip credential-provider lines from .cargo/config.toml before writing it to the temporary working directory. This ensures Cargo makes plain HTTP requests that the dependabot proxy can intercept and authenticate.

Changes

  • helpers.rb: Added sanitize_cargo_config method that strips credential-provider lines from config content
  • lockfile_updater.rb: Sanitize cargo config before writing to temp directory
  • version_resolver.rb: Same as lockfile_updater.rb
  • helpers_spec.rb: Tests covering various credential-provider patterns (none, single, multiple, mixed, varied whitespace)

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request.
  • I have ensured that the code is well-documented and easy to understand.

PR #14340 disabled Cargo's global credential providers by setting
CARGO_REGISTRY_GLOBAL_CREDENTIAL_PROVIDERS to an empty string, relying on the
dependabot proxy for all private registry authentication. However, this only
affects the global default -- per-registry `credential-provider` settings in
the user's `.cargo/config.toml` override the global setting.

When a user's config contains lines like:
  [registries.my-registry]
  credential-provider = "cargo:token"

Cargo ignores the global empty string and invokes the per-registry provider,
which looks for CARGO_REGISTRIES_{NAME}_TOKEN env vars that no longer exist
(removed in #14030), causing 'no token found' errors.

Fix by stripping `credential-provider` lines from .cargo/config.toml before
writing it to the temporary working directory. This ensures Cargo makes plain
HTTP requests that the dependabot proxy can intercept and authenticate.

Fixes #14354
Copilot AI review requested due to automatic review settings March 3, 2026 21:07
@jeffwidman jeffwidman requested a review from a team as a code owner March 3, 2026 21:07
@github-actions github-actions bot added the L: rust:cargo Rust crates via cargo label Mar 3, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the Cargo ecosystem to avoid private-registry authentication failures caused by per-registry credential-provider entries in .cargo/config.toml, ensuring Dependabot relies on the proxy-based auth path.

Changes:

  • Add Helpers.sanitize_cargo_config to remove credential-provider directives from Cargo config content.
  • Sanitize .cargo/config.toml before writing it into the temporary working directory in both the lockfile updater and version resolver flows.
  • Add RSpec coverage for config sanitization behavior across common formatting variants.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
cargo/lib/dependabot/cargo/helpers.rb Adds sanitize_cargo_config helper used to strip credential-provider lines from Cargo config content.
cargo/lib/dependabot/cargo/file_updater/lockfile_updater.rb Applies sanitization when writing .cargo/config.toml into the temp repo for lockfile updating.
cargo/lib/dependabot/cargo/update_checker/version_resolver.rb Applies the same sanitization when writing .cargo/config.toml for version resolution.
cargo/spec/dependabot/cargo/helpers_spec.rb Adds specs validating the sanitization behavior for multiple config layouts/whitespace variants.

# causing Cargo to look up tokens via CARGO_REGISTRIES_{NAME}_TOKEN env vars. Since the dependabot proxy
# handles authentication by intercepting HTTP requests, we need to strip these so Cargo makes plain
# requests that the proxy can decorate with credentials.
config_content.gsub(/^\s*credential-provider\s*=.*$/, "")
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

The implementation strips any line starting with credential-provider, regardless of whether it’s in a [registries.*] section. Either tighten the sanitization to only affect per-registry config (as described in the comment) or update the comment/docs to reflect that this removes all credential-provider settings in the file.

Suggested change
config_content.gsub(/^\s*credential-provider\s*=.*$/, "")
current_section = nil
sanitized_lines = config_content.lines.each_with_object([]) do |line, kept|
if line =~ /^\s*\[(.+?)\]\s*$/
current_section = Regexp.last_match(1)
end
if current_section&.start_with?("registries.") && line =~ /^\s*credential-provider\s*=/
next
end
kept << line
end
sanitized_lines.join

Copilot uses AI. Check for mistakes.
Comment on lines 309 to +310
FileUtils.mkdir_p(File.dirname(T.must(config).name))
File.write(T.must(config).name, T.must(config).content)
File.write(T.must(config).name, Helpers.sanitize_cargo_config(T.must(T.must(config).content)))
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

This T.must(T.must(config).content) nesting makes the write path harder to read. Consider assigning config_file = T.must(config) and content = T.must(config_file.content) (or similar) before calling sanitize_cargo_config so the nil assertions are clearer.

See below for a potential fix:

          config_file = T.must(config)
          FileUtils.mkdir_p(File.dirname(config_file.name))
          config_content = T.must(config_file.content)
          sanitized_content = Helpers.sanitize_cargo_config(config_content)
          File.write(config_file.name, sanitized_content)

Copilot uses AI. Check for mistakes.
Comment on lines 220 to +221
FileUtils.mkdir_p(File.dirname(T.must(config).name))
File.write(T.must(config).name, T.must(config).content)
File.write(T.must(config).name, Helpers.sanitize_cargo_config(T.must(T.must(config).content)))
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

This T.must(T.must(config).content) nesting makes the write path harder to read. Consider assigning config_file = T.must(config) and content = T.must(config_file.content) (or similar) before calling sanitize_cargo_config so the nil assertions are clearer.

See below for a potential fix:

          config_file = T.must(config)
          config_content = T.must(config_file.content)

          FileUtils.mkdir_p(File.dirname(config_file.name))
          File.write(config_file.name, Helpers.sanitize_cargo_config(config_content))

Copilot uses AI. Check for mistakes.
@jeffwidman
Copy link
Member Author

@jeffwidman jeffwidman closed this Mar 3, 2026
@jeffwidman jeffwidman deleted the fix-cargo-private-registry-auth branch March 3, 2026 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L: rust:cargo Rust crates via cargo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cargo: no token found for Artifactory

2 participants