Skip to content

Add Azure Cloud Name support for sovereign cloud environments (e.g. AzureChinaCloud)#65

Merged
RobinDuhan merged 6 commits intojfrog:mainfrom
chongwang87:feature/azure-china
Apr 17, 2026
Merged

Add Azure Cloud Name support for sovereign cloud environments (e.g. AzureChinaCloud)#65
RobinDuhan merged 6 commits intojfrog:mainfrom
chongwang87:feature/azure-china

Conversation

@chongwang87
Copy link
Copy Markdown
Contributor

@chongwang87 chongwang87 commented Apr 13, 2026

This PR adds support for configuring the Azure Cloud Name, enabling the credential provider to work in sovereign cloud environments such as Azure China (AzureChinaCloud) in addition to the default Azure public cloud.

Changes

Go application (internal/)

  • Added azure_cloud_name configuration parameter to the provider
  • Introduced getAzureADEndpoint() to resolve the correct Azure AD login endpoint based on cloud name (e.g. login.microsoftonline.com for public, login.partner.microsoftonline.cn for China)
  • Updated GetAzureOIDCToken to use the cloud-specific endpoint for token exchange

Helm chart (helm/)

  • Added azure_cloud_name to values.yaml and the provider ConfigMap template
  • Updated configmap-setup.yaml to handle download URLs containing query strings (e.g. SAS tokens) — arch suffix is now inserted before the query string instead of appended to the end

Documentation (AZURE.md)

  • Added a new Step 1 to guide users on identifying their Azure cloud name and setting the correct endpoints (Microsoft Graph, Active Directory) based on a cloud-specific reference table
  • Moved existing steps forward accordingly

Testing

  • Tested end-to-end on Azure China (AKS) with nodepool managed identity authentication against JFrog Artifactory

Sample Helm chart values (Azure China)

providerConfig:
  - name: jfrog-credentials-provider
    artifactoryUrl: <JFROG_URL>
    matchImages:
      - "*.<JFROG_URL>"
    defaultCacheDuration: 5h
    tokenAttributes:
      enabled: false
    azure:
      enabled: true
      azure_cloud_name: AzureChinaCloud
      azure_tenant_id: "00000000-0000-0000-0000-000000000000"
      azure_app_client_id: "00000000-0000-0000-0000-000000000000"
      azure_nodepool_client_id: "00000000-0000-0000-0000-000000000000"
      azure_app_audience: "api://AzureADTokenExchangeChina"
      jfrog_oidc_provider_name: "<OIDC_PROVIDER_NAME>"

rbac:
  create: true

Below are logs captured from kubelet

[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Fetching environment variable:cloud_provider
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] cloud_provider from env:
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Checking if cloud provider is AWS
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] TOKEN_URL :http://169.254.169.254/latest/api/token
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Checking if cloud provider is Azure
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Azure metadata server response status code: 200
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Checking if cloud provider is Google
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Google metadata server response status code: 404
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] jfrog provider is in the config, and is not triggered by the watcher
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Merged config written to /var/lib/kubelet/credential-provider-config.yaml
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:41 logger.go:40: [INFO] Watcher: waiting 5 seconds grace period before monitoring kubelet
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:46 logger.go:40: [INFO] Watcher: kubelet active (5/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:51 logger.go:40: [INFO] Watcher: kubelet active (10/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:54:56 logger.go:40: [INFO] Watcher: kubelet active (15/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:01 logger.go:40: [INFO] Watcher: kubelet active (20/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:06 logger.go:40: [INFO] Watcher: kubelet active (25/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:11 logger.go:40: [INFO] Watcher: kubelet active (30/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:16 logger.go:40: [INFO] Watcher: kubelet active (35/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:21 logger.go:40: [INFO] Watcher: kubelet active (40/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:26 logger.go:40: [INFO] Watcher: kubelet active (45/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:31 logger.go:40: [INFO] Watcher: kubelet active (50/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:36 logger.go:40: [INFO] Watcher: kubelet active (55/60 seconds elapsed)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:41 logger.go:40: [INFO] Watcher: kubelet healthy for full timeout period
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:41 logger.go:40: [INFO] Config backed up to /var/lib/kubelet/credential-provider-config.yaml.jfrog
[JFROG CREDENTIALS PROVIDER] 2026/04/13 06:55:41 logger.go:40: [INFO] Watcher: created post-success backup of kubelet config
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Running JFrog Credentials provider...
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] request.Image :xxx.JFROG_URL/alpine
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] getting envs - artifactoryUrl :JFROG_URL
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:cloud_provider
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] cloud_provider from env:
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:disable_provider_autoupdate
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Found environment variable:disable_provider_autoupdate=true
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Auto-update functionality is disabled. Skipping auto-update process.
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Checking if cloud provider is AWS
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] TOKEN_URL :http://169.254.169.254/latest/api/token
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Checking if cloud provider is Azure
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Azure metadata server response status code: 200
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Checking if cloud provider is Google
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Google metadata server response status code: 404
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Detected Azure cloud provider
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:azure_app_client_id
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Found environment variable:azure_app_client_id=00000000-0000-0000-0000-000000000000
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:azure_cloud_name
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Found environment variable:azure_cloud_name=AzureChinaCloud
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:azure_tenant_id
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Found environment variable:azure_tenant_id=00000000-0000-0000-0000-000000000000
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:azure_app_audience
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Found environment variable:azure_app_audience=api://AzureADTokenExchangeChina
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:azure_nodepool_client_id
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Found environment variable:azure_nodepool_client_id=00000000-0000-0000-0000-000000000000
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Fetching environment variable:jfrog_oidc_provider_name
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:44: [DEBUG] Found environment variable:jfrog_oidc_provider_name=OIDC_PROVIDER_NAME
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] getting envs - azureAppClientId: 00000000-0000-0000-0000-000000000000, azureAppCloudName: AzureChinaCloud, azureNo
depoolClientId: 00000000-0000-0000-0000-000000000000, azureAppTenantId: 00000000-0000-0000-0000-000000000000, azureAppAudience: api://AzureADTokenExchangeChina, jfrogOidcProviderName:
OIDC_PROVIDER_NAME
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Service Account Token obtained using Node Identity (VM Service Account)
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] constructing identityTokenResult
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] Using Azure AD endpoint: https://login.partner.microsoftonline.cn for cloud: AzureChinaCloud
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] RT oidc token url :https://JFROG_URL/access/api/v1/oidc/token
[JFROG CREDENTIALS PROVIDER] 2026/04/13 07:04:50 logger.go:40: [INFO] JFrog Username used for pull :JFROG_USERNAME

@chongwang87 chongwang87 requested a review from a team April 13, 2026 07:29
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 13, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

I have read the CLA Document and I hereby sign the CLA
@chongwang87 chongwang87 force-pushed the feature/azure-china branch from 2877413 to 5eb5199 Compare April 13, 2026 07:32
@chongwang87
Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

Comment thread helm/templates/configmap-setup.yaml Outdated
Comment thread helm/values.yaml Outdated
Comment thread examples/azure-values.yaml Outdated
Comment thread internal/provider/provider.go Outdated
Comment thread terraform-ci/azure_identity.tf Outdated
@chongwang87
Copy link
Copy Markdown
Contributor Author

#53

Comment thread helm/templates/configmap-provider.yaml
@chongwang87
Copy link
Copy Markdown
Contributor Author

Hi @RobinDuhan & @shahiinn , anything else to enhance?
May I know what's the release cycle and estimate when this PR can be merge and release?
Thanks.

@chongwang87 chongwang87 requested a review from RobinDuhan April 15, 2026 15:21
@RobinDuhan
Copy link
Copy Markdown
Contributor

Hey @chongwang87 , just checking again. I think we are mostly good to go.

Comment thread AZURE.md Outdated
@RobinDuhan
Copy link
Copy Markdown
Contributor

@chongwang87 Looks good besides that one comment on the ReadMe. Do you mind just verifying again, if you haven't already, since the PR did change quite a bit from the initial state?

I think we are good to merge this tomorrow. We can release it early next week, Monday/Tuesday.

@chongwang87 chongwang87 requested a review from RobinDuhan April 15, 2026 18:11
@RobinDuhan RobinDuhan merged commit e517e0f into jfrog:main Apr 17, 2026
1 check passed
@chongwang87 chongwang87 deleted the feature/azure-china branch April 17, 2026 06:09
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.

3 participants