Skip to content

CodeArtifact authentication works, but token is not available to cargo credential-provider #14172

@eriedl

Description

@eriedl

Is there an existing issue for this?

  • I have searched the existing issues

Package ecosystem

cargo

Package manager version

1.93.0

Language version

1.93.0

Manifest location and content before the Dependabot update

No response

dependabot.yml content

version: 2

registries:
  # See: https://docs.github.com/en/code-security/how-tos/secure-your-supply-chain/manage-your-dependency-security/guidance-for-the-configuration-of-private-registries-for-dependabot#cargo
  codeartifact:
    type: cargo-registry
    registry: <myregistry>
    url: https://<myregistry>.d.codeartifact.us-east-1.amazonaws.com/cargo/rust/
    token: "${{ secrets.CODEARTIFACT_TOKEN }}"

updates:
  - package-ecosystem: cargo
    directory: "/"
    registries:
      - codeartifact
    schedule:
      interval: weekly
      time: "08:00"
      timezone: America/Los_Angeles
    reviewers:
      - <removed>
    labels:
      - "Flag: Dependencies"
    commit-message:
      prefix: "Dependabot"
    ignore:
      - dependency-name: "*"
        update-types: [ "version-update:semver-patch", "version-update:semver-minor" ]

Updated dependency

No response

What you expected to see, versus what you actually saw

This issue might be related to #14094. However, we see different error messages and behavior.

We can see that dependabot can authenticate with the token provided via secrets injection with CodeArtifact:

2026-02-12T22:22:01.3948080Z   proxy | 2026/02/12 22:22:01 [022] GET https://<myregistry>.d.codeartifact.us-east-1.amazonaws.com:443/cargo/rust/config.json
2026-02-12T22:22:01.3950270Z 2026/02/12 22:22:01 [022] * authenticating cargo registry request (url: https://<myregistry>.d.codeartifact.us-east-1.amazonaws.com/cargo/rust/)
2026-02-12T22:22:01.6184021Z   proxy | 2026/02/12 22:22:01 [022] 200 https://<myregistry>.d.codeartifact.us-east-1.amazonaws.com:443/cargo/rust/config.json
2026-02-12T22:22:01.7386547Z updater | 2026/02/12 22:22:01 INFO <job_1242542417> Started process PID: 1468 with command: {} git config --global credential.helper '!/home/dependabot/common/lib/dependabot/../../bin/git-credential-store-immutable --file /home/dependabot/dependabot-updater/tmp/20260212-1085-l5yec7/dependabot_20260212-1085-zys51l/git.store' {}
2026-02-12T22:22:01.7453915Z updater | 2026/02/12 22:22:01 INFO <job_1242542417> Process PID: 1468 completed with status: pid 1468 exit 0
2026-02-12T22:22:01.7458521Z updater | 2026/02/12 22:22:01 INFO <job_1242542417> Total execution time: 0.01 seconds

Our understanding is that the CodeArtifact token will be exposed to cargo via the known ENV CARGO_REGISTRIES_<MYREGISTRY>_TOKEN and the configured credential-provider should be cargo:token. However, we still see errors when cargo tries to pull internal crates indicating that the CodeArtifact token is not available to cargo via the ENV.

2026-02-13T05:48:53.1490726Z   proxy | 2026/02/13 05:48:53 [060] POST /update_jobs/1242806953/record_update_job_error
2026-02-13T05:48:53.2153316Z   proxy | 2026/02/13 05:48:53 [060] 204 /update_jobs/1242806953/record_update_job_error
2026-02-13T05:48:53.2238341Z updater | 2026/02/13 05:48:53 INFO <job_1242806953> Handled error whilst updating <redacted>-util-sentry: dependency_file_not_resolvable {message: "Updating `<myregistry>` index\n  Credential cargo:token get <myregistry>\n  Credential cargo:token-from-stdout ./scripts/get_codeartifact_auth_token.sh get <myregistry>\nerror: failed to get `async-trait` as a dependency of package `app-queue v0.1.0 (dependabot_tmp_dir/crates/app-queue)`\n\nCaused by:\n  failed to query replaced source registry `crates-io`\n\nCaused by:\n  credential provider `cargo:token-from-stdout ./scripts/get_codeartifact_auth_token.sh` failed action `get`\n\nCaused by:\n  failed to spawn credential process\n\nCaused by:\n  No such file or directory (os error 2)"}

Now, we tried various things to see if it's a configuration error on our end. We were able to validate the cargo configuration in both our CI/CD flows as well as for local development. the config.toml looks something like this:

[registries.<myregistry>]
index = "sparse+https://<myregistry>.d.codeartifact.us-east-1.amazonaws.com/cargo/rust/"

[registry]
# It seems this is not very reliable in some situations and thus being ignored by dependabot as we're see public crates still being pulled from crates.io?
default = "<myregistry>"
# Later entries have higher precedence. Thus, the second provider is the dependabot scenario where it takes care of the authentication as configured in dependabot.yml. The first provider is for local development.
# See: https://doc.rust-lang.org/cargo/reference/config.html#registryglobal-credential-providers
global-credential-providers = [
    "cargo:token-from-stdout aws codeartifact get-authorization-token --domain <myregistry> --domain-owner <aws_account> --region us-east-1 --query authorizationToken --output text",
    "cargo:token"
]

[source.crates-io]
replace-with = "<myregistry>"

We used global-credential-providers instead of the registry specific credential-provider as that initially also did not work. Based on the logs we could at least tell that the credential provider chain is tried as expected.

Then we tried to get creative and see if we could access CARGO_REGISTRIES_<MYREGISTRY>_TOKEN directly by introducing a script that checks for this variable or would fall back to the AWS CLI for local development, also to no avail:

[registries.<myregistry>]
index = "sparse+https://<myregistry>-<aws_account>.d.codeartifact.us-east-1.amazonaws.com/cargo/rust/"

[registry]
# It seems this is not very reliable in some situations and thus being ignored by dependabot.
default = "<myregistry>"
# Later entries have higher precedence. Thus, the second provider is the dependabot scenario where it takes care of the authentication as configured
# in dependabot.yml. The first provider is for local development.
# See: https://doc.rust-lang.org/cargo/reference/config.html#registryglobal-credential-providers
global-credential-providers = ["cargo:token-from-stdout ./scripts/get_codeartifact_auth_token.sh"]

[source.crates-io]
replace-with = "<myregistry>"

# ------------SNIP get_codeartifact_auth_token.sh----------------

#!/bin/bash

set -e

if [ -n "$CARGO_REGISTRIES_<myregistry>_TOKEN" ]; then
  echo "$CARGO_REGISTRIES_<myregistry>_TOKEN"
else
  aws codeartifact get-authorization-token --domain <myregistry> --domain-owner <aws_account> --region us-east-1 --query authorizationToken --output text
fi

Unrelated, it seems dependabot forces public crates to be pulled from crates.io, probably by setting an ENV that overrides our config.toml.

Native package manager behavior

No response

Images of the diff or a link to the PR, issue, or logs

No response

Smallest manifest that reproduces the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions