Skip to content

Azure Workload Identity: Repository secret 'azureTenantId' ignored due to injected environment variables in multi-tenant setup #26008

@lieberlois

Description

@lieberlois

Checklist:

  • I've searched in the docs and FAQ for my answer: https://bit.ly/argocd-faq.
  • I've included steps to reproduce the bug.
  • I've pasted the output of argocd version.

Describe the bug

When using Azure Workload Identity in a multi-tenant environment, ArgoCD fails to switch between tenants for different OCI/Helm repositories. Despite configuring different azureTenantId values in the Repository Secrets, the argocd-repo-server consistently uses the Tenant ID injected into the Pod's environment variables by the Azure Workload Identity mutating webhook.

To Reproduce

  1. Deploy ArgoCD with Workload Identity enabled for the argocd-repo-server.
  2. The Azure Webhook injects AZURE_TENANT_ID (Tenant A) and AZURE_CLIENT_ID into the pod.
  3. Configure a Repository Secret for an ACR in a different tenant (Tenant B), setting:
useAzureWorkloadIdentity: "true"
azureTenantId: <Tenant-B-ID>  # this is where the ACR lives
clientId: <Identity-ID-from-Tenant-A> (Cross-tenant trust established via Federated Credentials - App Registration in Tenant A + Enterprise App in Tenant B).

Attempt to connect to the repository.

Expected behavior

ArgoCD should prioritize the azureTenantId and clientId specified in the Repository Secret over the global Pod environment variables to allow cross-tenant repository access within a single repo-server instance.

Actual behavior

ArgoCD fails with a 401 Unauthorized error. Logs indicate: failed to get Azure access token after challenge: failed to get refresh token: 401 Unauthorized.

Investigation via curl inside the pod confirms that manual token requests to Tenant B using the ServiceAccount token (OIDC) work perfectly when the Tenant B endpoint is targeted. However, ArgoCD appears to ignore the azureTenantId from the secret because the Azure SDK for Go prioritizes the AZURE_TENANT_ID environment variable over programmatically provided values.

Screenshots

Version

argocd: v3.2.1+8c4ab63
  BuildDate: 2025-12-01T09:28:49Z
  GitCommit: 8c4ab63a9c72b31d96c6360514cda6254e7e6629
  GitTreeState: clean
  GoVersion: go1.25.4
  Compiler: gc
  Platform: linux/amd64
argocd-server: v3.2.1+8c4ab63
  BuildDate: 2025-12-01T09:28:49Z
  GitCommit: 8c4ab63a9c72b31d96c6360514cda6254e7e6629
  GitTreeState: clean
  GoVersion: go1.25.4
  Compiler: gc
  Platform: linux/amd64
  Kustomize Version: could not get kustomize version: exec: "kustomize": executable file not found in $PATH
  Helm Version: v3.19.2+g8766e71
  Kubectl Version: v0.34.0
  Jsonnet Version: v0.21.0

Logs

grpc.service=repository.RepoServerService grpc.start_time="2026-01-15T12:28:56Z" grpc.time_ms=232.106 peer.address="10.244.11.60:44596" protocol=grpc

argocd-repo-server-555fd856f8-2xmm8 repo-server time="2026-01-15T12:28:56Z" level=error msg="finished call" grpc.code=Unknown grpc.component=server grpc.error="error testing repository connectivity: failed to get password for helm registry: failed to get Azure access token after challenge: failed to get refresh token: 401 Unauthorized" grpc.method=TestRepository grpc.method_type=unary grpc.request.deadline="2026-01-15T12:29:56Z"

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriage/pendingThis issue needs further triage to be correctly classified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions