Repository: ratify-project/ratify
Pull request #1909 (2024-11-03 11:29:04)

feat: support alibaba cloud rrsa store auth provider 
# Description

## What this PR does / why we need it:
<!--Please include a summary of the changes and relevant context. -->

Support using Alibaba Cloud RAM Roles for Service Accounts([RRSA](https://www.alibabacloud.com/help/en/ack/ack-managed-and-ack-dedicated/user-guide/use-rrsa-to-authorize-pods-to-access-different-cloud-services)) to pull artifacts from a private Alibaba Cloud Container Registry (ACR) with an ACR specific auth token.


## Which issue(s) this PR fixes *(optional, using `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when the PR gets merged)*:
Fixes #

## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [x] Helm Chart Change (any edit/addition/update that is necessary for changes merged to the `main` branch)
- [x] This change requires a documentation update

# How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration

- [x] basic unit test cases to create/enable/provide alibabacloud acr basic auth provider
 
In addition, I  have local built the testing image contains the changes in this PR，and tested in the Alibaba Cloud ACK cluster to verify fetch the signature metadata of a private images in the Aliababa Cloud ACR repository by using the store authProvider based on the new RRSA configuration. The more instructions will be added in the subsequent document PR.

# Checklist:

- [ ] Does the affected code have corresponding tests?
- [ ] Are the changes documented, not just with inline documentation, but also with conceptual documentation such as an overview of a new feature, or task-based documentation like a tutorial? Consider if this change should be announced on your project blog.
- [ ] Does this introduce breaking changes that would require an announcement or bumping the major version?
- [x] Do all new files have appropriate license header?

# Post Merge Requirements
- [ ] MAINTAINERS: manually trigger the "Publish Package" workflow after merging any PR that indicates `Helm Chart Change`


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) Report
Attention: Patch coverage is `53.57143%` with `65 lines` in your changes missing coverage. Please review.

| [Files with missing lines](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) | Patch % | Lines |
|---|---|---|
| [.../authprovider/alibabacloud/alibabacloudacrbasic.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&filepath=pkg%2Fcommon%2Foras%2Fauthprovider%2Falibabacloud%2Falibabacloudacrbasic.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbW1vbi9vcmFzL2F1dGhwcm92aWRlci9hbGliYWJhY2xvdWQvYWxpYmFiYWNsb3VkYWNyYmFzaWMuZ28=) | 48.62% | [47 Missing and 9 partials :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |
| [...hprovider/alibabacloud/alibabacloudacrauthtypes.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&filepath=pkg%2Fcommon%2Foras%2Fauthprovider%2Falibabacloud%2Falibabacloudacrauthtypes.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbW1vbi9vcmFzL2F1dGhwcm92aWRlci9hbGliYWJhY2xvdWQvYWxpYmFiYWNsb3VkYWNyYXV0aHR5cGVzLmdv) | 30.76% | [6 Missing and 3 partials :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |

| [Files with missing lines](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) | Coverage Δ | |
|---|---|---|
| [...kg/common/oras/authprovider/alibabacloud/helper.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&filepath=pkg%2Fcommon%2Foras%2Fauthprovider%2Falibabacloud%2Fhelper.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbW1vbi9vcmFzL2F1dGhwcm92aWRlci9hbGliYWJhY2xvdWQvaGVscGVyLmdv) | `100.00% <100.00%> (ø)` | |
| [...kg/common/oras/authprovider/authproviderfactory.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&filepath=pkg%2Fcommon%2Foras%2Fauthprovider%2Fauthproviderfactory.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbW1vbi9vcmFzL2F1dGhwcm92aWRlci9hdXRocHJvdmlkZXJmYWN0b3J5Lmdv) | `66.66% <100.00%> (+2.38%)` | :arrow_up: |
| [pkg/referrerstore/oras/oras.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&filepath=pkg%2Freferrerstore%2Foras%2Foras.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL3JlZmVycmVyc3RvcmUvb3Jhcy9vcmFzLmdv) | `73.91% <ø> (-7.06%)` | :arrow_down: |
| [...hprovider/alibabacloud/alibabacloudacrauthtypes.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&filepath=pkg%2Fcommon%2Foras%2Fauthprovider%2Falibabacloud%2Falibabacloudacrauthtypes.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbW1vbi9vcmFzL2F1dGhwcm92aWRlci9hbGliYWJhY2xvdWQvYWxpYmFiYWNsb3VkYWNyYXV0aHR5cGVzLmdv) | `30.76% <30.76%> (ø)` | |
| [.../authprovider/alibabacloud/alibabacloudacrbasic.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1909?src=pr&el=tree&filepath=pkg%2Fcommon%2Foras%2Fauthprovider%2Falibabacloud%2Falibabacloudacrbasic.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbW1vbi9vcmFzL2F1dGhwcm92aWRlci9hbGliYWJhY2xvdWQvYWxpYmFiYWNsb3VkYWNyYmFzaWMuZ28=) | `48.62% <48.62%> (ø)` | |

... and [131 files with indirect coverage changes](https://app.codecov.io/gh/ratify-project/ratify/pull/1909/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project)

susanshi: Hi @DahuK ,please also review the lint report and resolve the merge conflict. let us know if you have any questions
DahuK: > Hi @DahuK , thanks so much for adding the alibaba auth provider. The group of us have discussed during the PR review meeting, and here are the notes:
> 
> * we are aiming for unit test coverage at 80%,  would it be possible to add more coverage for alibabacloudacrauthtypes.go and alibabacloudacrbasic.go
> * maybe as a sperate PR, are you looking to add e2e test similar to [azure-test.bats](https://github.com/ratify-project/ratify/blob/dev/test/bats/azure-test.bats)
> * also as a seperate PR, might be good to add to auth provider docs at [supported auth providers ](https://ratify.dev/docs/plugins/store/oras/#supported-providers)


DahuK: > Hi @DahuK , thanks so much for adding the alibaba auth provider. The group of us have discussed during the PR review meeting, and here are the notes:
> 
> * we are aiming for unit test coverage at 80%,  would it be possible to add more coverage for alibabacloudacrauthtypes.go and alibabacloudacrbasic.go
> * maybe as a sperate PR, are you looking to add e2e test similar to [azure-test.bats](https://github.com/ratify-project/ratify/blob/dev/test/bats/azure-test.bats)
> * also as a seperate PR, might be good to add to auth provider docs at [supported auth providers ](https://ratify.dev/docs/plugins/store/oras/#supported-providers)

Thanks your reviewing and sorry for the late response!  
 - I have added some ut for the coverage 
 - For company compliance policies we may not be able to provide our credentials as accesskey/secret, however we may be able to add some e2e bats for local testing in another PR
 - Yes, I will add the provider docs this weekend in another PR


susanshi: Hi @DahuK , thanks for the latest updates, the change looks good. Please resolve the latest go.mod conflicts , this PR is almost ready to merge. @junczhu , @binbin-li  please take a look if conversation are resolved. thanks all
binbin-li: @DahuK the PR is good to go, could you sign the commit following it: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits
DahuK: > @DahuK the PR is good to go, could you sign the commit following it: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits

Thanks! the commit is signed.

Patch:
diff --git a/charts/ratify/README.md b/charts/ratify/README.md
index 7b79647..7dc6ee0 100644
--- a/charts/ratify/README.md
+++ b/charts/ratify/README.md
@@ -93,6 +93,7 @@ Values marked `# DEPRECATED` in the `values.yaml` as well as **DEPRECATED** in t
 | oras.authProviders.awsApiOverride.endpoint         | Overrides ECR endpoint                                                                                                                                                                                                                                                                                                                                                 | ``                                |
 | oras.authProviders.awsApiOverride.partition        | Overrides ECR partition in the endpoint URL                                                                                                                                                                                                                                                                                                                            | `aws`                             |
 | oras.authProviders.awsApiOverride.region           | Overrides ECR region in the endpoint URL                                                                                                                                                                                                                                                                                                                               | ``                                |
+| oras.authProviders.alibabacloudAcrBasicEnabled     | Enables Alibaba Cloud ACR basic authentication provider                                                                                                                                                                                                                                                                                                                | `false`                           |
 | oras.cache.enabled                                 | Enables ORAS store cache for ListReferrers and GetSubjectDescriptor. TTL-based cache may cause inconsistency between cache and data source. Please disable it if strong consistency is required.operations                                                                                                                                                             | `true`                            |
 | oras.cache.ttl                                     | Sets the ttl for ORAS store in seconds. cache                                                                                                                                                                                                                                                                                                                          | `10`                              |
 | provider.tls.crt                                   | Ratify server's tls public certificate                                                                                                                                                                                                                                                                                                                                 | ``                                |
@@ -138,8 +139,10 @@ Values marked `# DEPRECATED` in the `values.yaml` as well as **DEPRECATED** in t
 | azurekeyvault.vaultURI                             | Vault URI for Azure Key Vault                                                                                                                                                                                                                                                                                                                                          | ``                                |
 | azurekeyvault.tenantId                             | Tenant ID of the configured Azure Key Vault resource                                                                                                                                                                                                                                                                                                                   | ``                                |
 | azurekeyvault.certificates                         | An array of certificate objects identified by `name` and `version` (optional) stored in Azure Key Vault                                                                                                                                                                                                                                                                | `[]`                              |
-| azurekeyvault.keys                                 | An array of key objects identified by `name` and `version` (optional) stored in Azure Key Vault                                                                                                                                                                                                                  | `[]`                              |
-| azurekeyvault.refreshInterval                      | time duration to refresh the certificates/keys. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Example: 1h, 30m, 1h30m. If it's not set, the refresh functionality will be disabled.                                                                                                                                                                                                                      | ``                                |
+| azurekeyvault.keys                                 | An array of key objects identified by `name` and `version` (optional) stored in Azure Key Vault                                                                                                                                                                                                                                                                        | `[]`                              |
+| azurekeyvault.refreshInterval                      | time duration to refresh the certificates/keys. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Example: 1h, 30m, 1h30m. If it's not set, the refresh functionality will be disabled.                                                                                                                                                                  | ``                                |
+| alibabacloudAcrConfig.defaultInstanceId            | Default instance ID of the Alibaba Cloud Registry where the target artifacts stored                                                                                                                                                                                                                                                                                    | ``                                |
+| alibabacloudAcrConfig.acrInstancesConfig           | When images need to be pulled from multiple instances of Aliababa Cloud Registry, the instanceName and instanceId of the instances need to be defined separately in the list, e.g.    acrInstancesConfig:<br/>  - instanceName: name1<br/>    instanceId: cri-xxx1<br/>  - instanceName: name2<br/>    instanceId: cri-xxx2<br />                                      | `[]`                              |
 | notationCert                                       | **DEPRECATED** Please switch to `notationCerts` to specify an array of verification certificates. Public certificate/certificate chain used to create inline certstore used by Notation verifier.                                                                                                                                                                      | ``                                |
 | akvCertConfig.enabled                              | **DEPRECATED** Please use `azurekeyvault.enabled` instead. Enables/disables Azure Key Vault certificate store. If you are using a custom chart, certificate store should be referenced through a Verifier CR. References in ConfigMap will not be correctly resolved.                                                                                                  | `false`                           |
 | akvCertConfig.vaultURI                             | **DEPRECATED** Please use `azurekeyvault.vaultURI` instead. Vault URI for AKV configured                                                                                                                                                                                                                                                                               | ``                                |
diff --git a/charts/ratify/templates/store.yaml b/charts/ratify/templates/store.yaml
index 665a75c..07ec36a 100644
--- a/charts/ratify/templates/store.yaml
+++ b/charts/ratify/templates/store.yaml
@@ -34,6 +34,13 @@ spec:
     authProvider:
       name: awsEcrBasic
     {{- end }}
+    {{- if .Values.oras.authProviders.alibabacloudAcrBasicEnabled }}
+    authProvider:
+      name: alibabacloudAcrBasic
+      defaultInstanceId: {{ .Values.alibabacloudAcrConfig.defaultInstanceId }}
+      acrInstancesConfig:
+        {{- toYaml .Values.alibabacloudAcrConfig.acrInstancesConfig | nindent 8 }}
+    {{- end }}
     {{- if .Values.oras.cache.enabled }}
     cacheEnabled: true
     ttl: {{ .Values.oras.cache.ttl }}
diff --git a/charts/ratify/values.yaml b/charts/ratify/values.yaml
index c026ed4..1b9cc4b 100644
--- a/charts/ratify/values.yaml
+++ b/charts/ratify/values.yaml
@@ -82,6 +82,10 @@ azurekeyvault:
   keys: []
   refreshInterval:
 
+alibabacloudAcrConfig:
+  defaultInstanceId:
+  acrInstancesConfig: []
+
 oras:
   useHttp: false
   authProviders:
@@ -94,6 +98,8 @@ oras:
       endpoint: ""
       partition: "" # defaults to aws
       region: ""
+    alibabacloudAcrBasicEnabled: false
+
   cache:
     # Please tune your cache parameters to get better performance on the Oras Store performance.
     enabled: true # ttl-based cache may cause inconsistency between cache and data source, please disable it if strong consistency is required.
diff --git a/errors/errors.go b/errors/errors.go
index 9305f79..8fe451e 100644
--- a/errors/errors.go
+++ b/errors/errors.go
@@ -132,4 +132,11 @@ var (
 		Message:     "operation forbidden",
 		Description: "The requested operation is forbidden. Please verify the permission to the requested resource.",
 	})
+
+	// ErrorCodeConfigInvalid is returned if provided alibabacloud image is invalid.
+	ErrorCodeAlibabaCloudImageInvalid = Register("errcode", ErrorDescriptor{
+		Value:       "ALIBABACLOUD_IMAGE_INVALID",
+		Message:     "image invalid",
+		Description: `Invalid Alibaba Cloud Registry image format. Please verify your image configuration.`,
+	})
 )
diff --git a/go.mod b/go.mod
index 396a408..dbad99c 100644
--- a/go.mod
+++ b/go.mod
@@ -15,6 +15,11 @@ require (
 	github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.2
 	github.com/Azure/go-autorest/autorest/to v0.4.0
 	github.com/AzureAD/microsoft-authentication-library-for-go v1.2.3
+	github.com/alibabacloud-go/cr-20181201/v2 v2.5.0
+	github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10
+	github.com/alibabacloud-go/tea v1.2.2
+	github.com/alibabacloud-go/tea-utils/v2 v2.0.7
+	github.com/aliyun/credentials-go v1.3.10
 	github.com/aws/aws-sdk-go-v2 v1.32.4
 	github.com/aws/aws-sdk-go-v2/config v1.27.43
 	github.com/aws/aws-sdk-go-v2/credentials v1.17.44
@@ -70,17 +75,15 @@ require (
 	github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect
 	github.com/ThalesIgnite/crypto11 v1.2.5 // indirect
 	github.com/agnivade/levenshtein v1.1.1 // indirect
-	github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
+	github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
 	github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect
 	github.com/alibabacloud-go/cr-20181201 v1.0.10 // indirect
 	github.com/alibabacloud-go/darabonba-openapi v0.2.1 // indirect
-	github.com/alibabacloud-go/debug v1.0.0 // indirect
+	github.com/alibabacloud-go/debug v1.0.1 // indirect
 	github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect
 	github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
-	github.com/alibabacloud-go/tea v1.2.1 // indirect
 	github.com/alibabacloud-go/tea-utils v1.4.5 // indirect
 	github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
-	github.com/aliyun/credentials-go v1.3.1 // indirect
 	github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
 	github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.7 // indirect
 	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
diff --git a/go.sum b/go.sum
index a9f30e9..c7be23e 100644
--- a/go.sum
+++ b/go.sum
@@ -76,21 +76,40 @@ github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVK
 github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
 github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
 github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
+github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA=
+github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do24zMOGGqYVWgw0s9NtiylnJglOeEB5UJo=
 github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.2/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
-github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
 github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
+github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 h1:zE8vH9C7JiZLNJJQ5OwjU9mSi4T9ef9u3BURT6LCLC8=
+github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5/go.mod h1:tWnyE9AjF8J8qqLk645oUmVUnFybApTQWklQmi5tY6g=
 github.com/alibabacloud-go/cr-20160607 v1.0.1 h1:WEnP1iPFKJU74ryUKh/YDPHoxMZawqlPajOymyNAkts=
 github.com/alibabacloud-go/cr-20160607 v1.0.1/go.mod h1:QHeKZtZ3F3FOE+/uIXCBAp8POwnUYekpLwr1dtQa5r0=
 github.com/alibabacloud-go/cr-20181201 v1.0.10 h1:B60f6S1imsgn2fgC6X6FrVNrONDrbCT0NwYhsJ0C9/c=
 github.com/alibabacloud-go/cr-20181201 v1.0.10/go.mod h1:VN9orB/w5G20FjytoSpZROqu9ZqxwycASmGqYUJSoDc=
+github.com/alibabacloud-go/cr-20181201/v2 v2.5.0 h1:dfhfzCsgpkC72pAwWyHUwVcjj88UIVaEcQn5dzo+heM=
+github.com/alibabacloud-go/cr-20181201/v2 v2.5.0/go.mod h1:z5UYK7JxXtSqPASUscH9EZYYcEpEl7bvijlGO/OMNSI=
+github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY=
+github.com/alibabacloud-go/darabonba-array v0.1.0/go.mod h1:BLKxr0brnggqOJPqT09DFJ8g3fsDshapUD3C3aOEFaI=
+github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC2NG0Ax+GpOM5gtupki31XE=
+github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8=
+github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
+github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
 github.com/alibabacloud-go/darabonba-openapi v0.1.12/go.mod h1:sTAjsFJmVsmcVeklL9d9uDBlFsgl43wZ6jhI6BHqHqU=
 github.com/alibabacloud-go/darabonba-openapi v0.1.14/go.mod h1:w4CosR7O/kapCtEEMBm3JsQqWBU/CnZ2o0pHorsTWDI=
 github.com/alibabacloud-go/darabonba-openapi v0.2.1 h1:WyzxxKvhdVDlwpAMOHgAiCJ+NXa6g5ZWPFEzaK/ewwY=
 github.com/alibabacloud-go/darabonba-openapi v0.2.1/go.mod h1:zXOqLbpIqq543oioL9IuuZYOQgHQ5B8/n5OPrnko8aY=
+github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.6/go.mod h1:CzQnh+94WDnJOnKZH5YRyouL+OOcdBnXY5VWAf0McgI=
+github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10 h1:GEYkMApgpKEVDn6z12DcH1EGYpDYRB8JxsazM4Rywak=
+github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10/go.mod h1:26a14FGhZVELuz2cc2AolvW4RHmIO3/HRwsdHhaIPDE=
+github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
+github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ=
 github.com/alibabacloud-go/darabonba-string v1.0.0/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
+github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo=
+github.com/alibabacloud-go/darabonba-string v1.0.2/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
 github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
-github.com/alibabacloud-go/debug v1.0.0 h1:3eIEQWfay1fB24PQIEzXAswlVJtdQok8f3EVN5VrBnA=
 github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
+github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA6GSbPg=
+github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
 github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
 github.com/alibabacloud-go/endpoint-util v1.1.1 h1:ZkBv2/jnghxtU0p+upSU0GGzW1VL9GQdZO3mcSUTUy8=
 github.com/alibabacloud-go/endpoint-util v1.1.1/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
@@ -105,19 +124,27 @@ github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeG
 github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
 github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
 github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
-github.com/alibabacloud-go/tea v1.2.1 h1:rFF1LnrAdhaiPmKwH5xwYOKlMh66CqRwPUTzIK74ask=
+github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
 github.com/alibabacloud-go/tea v1.2.1/go.mod h1:qbzof29bM/IFhLMtJPrgTGK3eauV5J2wSyEUo4OEmnA=
+github.com/alibabacloud-go/tea v1.2.2 h1:aTsR6Rl3ANWPfqeQugPglfurloyBJY85eFy7Gc1+8oU=
+github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
 github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
 github.com/alibabacloud-go/tea-utils v1.3.9/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
 github.com/alibabacloud-go/tea-utils v1.4.3/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
 github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA=
 github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
+github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4=
+github.com/alibabacloud-go/tea-utils/v2 v2.0.6/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
+github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0=
+github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
 github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
 github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0=
 github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
 github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
-github.com/aliyun/credentials-go v1.3.1 h1:uq/0v7kWrxmoLGpqjx7vtQ/s03f0zR//0br/xWDTE28=
 github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
+github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM=
+github.com/aliyun/credentials-go v1.3.10 h1:45Xxrae/evfzQL9V10zL3xX31eqgLWEaIdCoPipOEQA=
+github.com/aliyun/credentials-go v1.3.10/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
 github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
 github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
 github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
@@ -781,7 +808,9 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
 golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
 golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
 golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
@@ -825,8 +854,11 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
 golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
+golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
 golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
 golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -872,7 +904,9 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
@@ -884,7 +918,9 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
 golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
 golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
@@ -900,6 +936,7 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
 golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
diff --git a/pkg/common/oras/authprovider/alibabacloud/alibabacloudacrbasic.go b/pkg/common/oras/authprovider/alibabacloud/alibabacloudacrbasic.go
new file mode 100644
index 0000000..780f839
--- /dev/null
+++ b/pkg/common/oras/authprovider/alibabacloud/alibabacloudacrbasic.go
@@ -0,0 +1,211 @@
+/*
+Copyright The Ratify Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package alibabacloud
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"os"
+	"time"
+
+	cr20181201 "github.com/alibabacloud-go/cr-20181201/v2/client"
+	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
+	util "github.com/alibabacloud-go/tea-utils/v2/service"
+	"github.com/alibabacloud-go/tea/tea"
+	"github.com/aliyun/credentials-go/credentials"
+	re "github.com/ratify-project/ratify/errors"
+
+	"github.com/pkg/errors"
+	provider "github.com/ratify-project/ratify/pkg/common/oras/authprovider"
+	"github.com/sirupsen/logrus"
+)
+
+const (
+	EnvRoleArn              = "ALIBABA_CLOUD_ROLE_ARN"
+	EnvOidcProviderArn      = "ALIBABA_CLOUD_OIDC_PROVIDER_ARN"
+	EnvOidcTokenFile        = "ALIBABA_CLOUD_OIDC_TOKEN_FILE"
+	AlibabaCloudACREndpoint = "cr.%s.aliyuncs.com"
+)
+
+type AlibabaCloudAcrBasicProviderFactory struct{} //nolint:revive // ignore linter to have unique type name
+
+type acrInstancesConfig struct {
+	InstanceName string `json:"instanceName"`
+	InstanceID   string `json:"instanceId"`
+}
+
+type alibabacloudAcrBasicAuthProvider struct {
+	acrInstancesConfig map[string]string
+	providerName       string
+	getAcrAuthToken    AcrAuthTokenGetter
+}
+
+type alibabacloudAcrBasicAuthProviderConf struct {
+	Name               string               `json:"name"`
+	DefaultInstanceID  string               `json:"defaultInstanceId"`
+	AcrInstancesConfig []acrInstancesConfig `json:"acrInstancesConfig,omitempty"`
+}
+
+const (
+	alibabacloudAcrAuthProviderName = "alibabacloudAcrBasic"
+)
+
+// init calls Register for AlibabaCloud RRSA Basic Auth provider
+func init() {
+	provider.Register(alibabacloudAcrAuthProviderName, &AlibabaCloudAcrBasicProviderFactory{})
+}
+
+// AcrAuthTokenGetter defines an interface for getting acr authentication token.
+type AcrAuthTokenGetter interface {
+	GetAcrAuthToken(artifact string, acrInstanceConfig map[string]string) (*cr20181201.GetAuthorizationTokenResponseBody, error)
+}
+
+// defaultAcrAuthTokenGetterImpl is the default implementation of getAcrAuthToken.
+type defaultAcrAuthTokenGetterImpl struct{}
+
+func (g *defaultAcrAuthTokenGetterImpl) GetAcrAuthToken(artifact string, acrInstanceConfig map[string]string) (*cr20181201.GetAuthorizationTokenResponseBody, error) {
+	return getAcrAuthToken(artifact, acrInstanceConfig)
+}
+
+// Get ACR auth token from RRSA config
+func getAcrAuthToken(artifact string, acrInstanceConfig map[string]string) (*cr20181201.GetAuthorizationTokenResponseBody, error) {
+	// Verify RRSA ENV is present
+
+	envRoleArn := os.Getenv(EnvRoleArn)
+	envOidcProviderArn := os.Getenv(EnvOidcProviderArn)
+	envOidcTokenFile := os.Getenv(EnvOidcTokenFile)
+
+	if envRoleArn == "" || envOidcProviderArn == "" || envOidcTokenFile == "" {
+		return nil, fmt.Errorf("required environment variables not set, ALIBABA_CLOUD_ROLE_ARN: %s, ALIBABA_CLOUD_OIDC_PROVIDER_ARN: %s, ALIBABA_CLOUD_OIDC_TOKEN_FILE: %s", envRoleArn, envOidcProviderArn, envOidcTokenFile)
+	}
+
+	// registry/region from image
+	registry, err := provider.GetRegistryHostName(artifact)
+	if err != nil {
+		return nil, fmt.Errorf("failed to get registry from image: %w", err)
+	}
+	registryMetaInfo, err := getRegionFromArtifact(registry)
+	if err != nil || registryMetaInfo.Region == "" {
+		return nil, err
+	}
+	region := registryMetaInfo.Region
+	instanceName := registryMetaInfo.InstanceName
+	logrus.Infof("Alibaba Cloud ACR basic artifact=%s, registry=%s, region=%s, instance=%s", artifact, registry, region, instanceName)
+
+	cred, err := credentials.NewCredential(nil)
+	if err != nil {
+		return nil, fmt.Errorf("failed to init alibaba cloud sdk credential: %w", err)
+	}
+	config := &openapi.Config{
+		Credential: cred,
+	}
+	instanceID := acrInstanceConfig[defaultInstance]
+	if insID, ok := acrInstanceConfig[instanceName]; ok {
+		instanceID = insID
+	}
+	if instanceID == "" {
+		return nil, fmt.Errorf("no instance id found for the given artifact")
+	}
+	// Endpoint refer to https://help.aliyun.com/zh/acr/developer-reference/api-cr-2018-12-01-endpoint
+	config.Endpoint = tea.String(fmt.Sprintf(AlibabaCloudACREndpoint, region))
+	config.RegionId = tea.String(region)
+	crClient, err := cr20181201.NewClient(config)
+	if err != nil {
+		return nil, fmt.Errorf("failed to init alibaba cloud acr client: %w", err)
+	}
+
+	getAuthorizationTokenRequest := &cr20181201.GetAuthorizationTokenRequest{}
+	getAuthorizationTokenRequest.InstanceId = tea.String(instanceID)
+	runtime := &util.RuntimeOptions{}
+
+	tokenResponse, err := crClient.GetAuthorizationTokenWithOptions(getAuthorizationTokenRequest, runtime)
+	if err != nil || tokenResponse.Body == nil {
+		return nil, fmt.Errorf("failed to get acr authorization token: %w", err)
+	}
+	return tokenResponse.Body, nil
+}
+
+// Create returns an Alibaba CloudAcrBasicProvider
+func (d *AlibabaCloudAcrBasicProviderFactory) Create(authProviderConfig provider.AuthProviderConfig) (provider.AuthProvider, error) {
+	conf := alibabacloudAcrBasicAuthProviderConf{}
+	authProviderConfigBytes, err := json.Marshal(authProviderConfig)
+	if err != nil {
+		return nil, re.ErrorCodeConfigInvalid.WithError(err).WithComponentType(re.AuthProvider)
+	}
+
+	if err = json.Unmarshal(authProviderConfigBytes, &conf); err != nil {
+		return nil, re.ErrorCodeConfigInvalid.NewError(re.AuthProvider, alibabacloudAcrAuthProviderName, re.AuthProviderLink, err, "failed to parse alibaba cloud auth provider configuration", re.HideStackTrace)
+	}
+	var acrInstancesConfig = make(map[string]string, 0)
+	if len(conf.AcrInstancesConfig) > 0 {
+		for _, ic := range conf.AcrInstancesConfig {
+			acrInstancesConfig[ic.InstanceName] = ic.InstanceID
+		}
+	}
+	//get ACR EE instance id
+	instanceID := conf.DefaultInstanceID
+	if instanceID == "" {
+		instanceID = os.Getenv("ALIBABA_CLOUD_ACR_INSTANCE_ID")
+		if instanceID == "" && len(acrInstancesConfig) == 0 {
+			return nil, re.ErrorCodeEnvNotSet.WithComponentType(re.AuthProvider).WithDetail("no instance ID provided and ALIBABA_CLOUD_ACR_INSTANCE_ID environment variable is empty")
+		}
+	}
+	acrInstancesConfig[defaultInstance] = instanceID
+
+	return &alibabacloudAcrBasicAuthProvider{
+		acrInstancesConfig: acrInstancesConfig,
+		providerName:       alibabacloudAcrAuthProviderName,
+		getAcrAuthToken:    &defaultAcrAuthTokenGetterImpl{},
+	}, nil
+}
+
+// Enabled checks for non-empty AlibabaCloud RAM creds
+func (d *alibabacloudAcrBasicAuthProvider) Enabled(_ context.Context) bool {
+	if d.providerName == "" {
+		logrus.Error("basic Alibaba Cloud ACR providerName was empty")
+		return false
+	}
+
+	return true
+}
+
+// Provide returns the credentials for a specified artifact.
+// Uses AlibabaCloud RRSA to retrieve creds from RRSA credential chain
+func (d *alibabacloudAcrBasicAuthProvider) Provide(ctx context.Context, artifact string) (provider.AuthConfig, error) {
+	if !d.Enabled(ctx) {
+		return provider.AuthConfig{}, re.ErrorCodeConfigInvalid.WithComponentType(re.AuthProvider).WithDetail("Alibaba Cloud RRSA basic auth provider is not properly enabled")
+	}
+
+	// need to first creat or refresh AlibabaCloud ACR credentials
+	authToken, err := d.getAcrAuthToken.GetAcrAuthToken(artifact, d.acrInstancesConfig)
+	if err != nil {
+		return provider.AuthConfig{}, errors.Wrapf(err, "could not get ACR auth token for %s", artifact)
+	}
+	logrus.Debugf("successfully refreshed ACR auth token for %s", artifact)
+
+	// Get ACR basic auth creds from AuthData response
+	tmpUsr := tea.StringValue(authToken.TempUsername)
+	passwd := tea.StringValue(authToken.AuthorizationToken)
+	authConfig := provider.AuthConfig{
+		Username:  tmpUsr,
+		Password:  passwd,
+		Provider:  d,
+		ExpiresOn: time.UnixMilli(tea.Int64Value(authToken.ExpireTime)),
+	}
+
+	return authConfig, nil
+}
diff --git a/pkg/common/oras/authprovider/alibabacloud/helper.go b/pkg/common/oras/authprovider/alibabacloud/helper.go
new file mode 100644
index 0000000..acf2255
--- /dev/null
+++ b/pkg/common/oras/authprovider/alibabacloud/helper.go
@@ -0,0 +1,54 @@
+/*
+Copyright The Ratify Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package alibabacloud
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	re "github.com/ratify-project/ratify/errors"
+)
+
+const (
+	acrNameSuffix   = ".aliyuncs.com"
+	defaultInstance = "defaultInstance"
+)
+
+// examples of valid Alibaba Cloud Registry images:
+// test-registry-vpc.cn-hangzhou.cr.aliyuncs.com
+// test-registry.cn-hangzhou.cr.aliyuncs.com
+var domainPattern = regexp.MustCompile(
+	`^(?:(?P<instanceName>[^.\s]+)-)?registry(?:-intl)?(?:-vpc)?(?:-internal)?(?:\.distributed)?\.(?P<region>[^.]+\-[^.]+)\.(?:cr\.)?aliyuncs\.com`)
+
+type AcrMetaInfo struct {
+	InstanceName string
+	Region       string
+}
+
+func getRegionFromArtifact(artifact string) (*AcrMetaInfo, error) {
+	if !strings.HasSuffix(artifact, acrNameSuffix) {
+		return nil, re.ErrorCodeAlibabaCloudImageInvalid.WithComponentType(re.AuthProvider).WithDetail(fmt.Sprintf("Invalid Alibaba Cloud Registry image %s which does not end with `aliyuncs.com`", artifact))
+	}
+	subItems := domainPattern.FindStringSubmatch(artifact)
+	if len(subItems) != 3 {
+		return nil, re.ErrorCodeAlibabaCloudImageInvalid.WithComponentType(re.AuthProvider).WithDetail("Invalid Alibaba Cloud Registry image format")
+	}
+	return &AcrMetaInfo{
+		InstanceName: subItems[1],
+		Region:       subItems[2],
+	}, nil
+}
diff --git a/pkg/common/oras/authprovider/authproviderfactory.go b/pkg/common/oras/authprovider/authproviderfactory.go
index 08bde42..d641bda 100644
--- a/pkg/common/oras/authprovider/authproviderfactory.go
+++ b/pkg/common/oras/authprovider/authproviderfactory.go
@@ -38,7 +38,6 @@ func Register(name string, factory AuthProviderFactory) {
 	if registered {
 		panic(fmt.Sprintf("auth provider factory named %s already registered", name))
 	}
-
 	builtInAuthProviders[name] = factory
 }
 
diff --git a/pkg/referrerstore/oras/oras.go b/pkg/referrerstore/oras/oras.go
index 64679dd..48f1dc0 100644
--- a/pkg/referrerstore/oras/oras.go
+++ b/pkg/referrerstore/oras/oras.go
@@ -45,8 +45,9 @@ import (
 	"github.com/ratify-project/ratify/pkg/cache"
 	"github.com/ratify-project/ratify/pkg/common"
 	"github.com/ratify-project/ratify/pkg/common/oras/authprovider"
-	_ "github.com/ratify-project/ratify/pkg/common/oras/authprovider/aws"   // register aws auth provider
-	_ "github.com/ratify-project/ratify/pkg/common/oras/authprovider/azure" // register azure auth provider
+	_ "github.com/ratify-project/ratify/pkg/common/oras/authprovider/alibabacloud" // register alibabacloud auth provider
+	_ "github.com/ratify-project/ratify/pkg/common/oras/authprovider/aws"          // register aws auth provider
+	_ "github.com/ratify-project/ratify/pkg/common/oras/authprovider/azure"        // register azure auth provider
 	commonutils "github.com/ratify-project/ratify/pkg/common/utils"
 	"github.com/ratify-project/ratify/pkg/homedir"
 	"github.com/ratify-project/ratify/pkg/metrics"
@@ -57,12 +58,12 @@ import (
 )
 
 const (
-	HTTPMaxIdleConns                       = 100
-	HTTPMaxConnsPerHost                    = 100
-	HTTPMaxIdleConnsPerHost                = 100
-	HTTPRetryMax                           = 5
-	HTTPRetryDurationMinimum time.Duration = 200 * time.Millisecond
-	HTTPRetryDurationMax     time.Duration = 1750 * time.Millisecond
+	HTTPMaxIdleConns         = 100
+	HTTPMaxConnsPerHost      = 100
+	HTTPMaxIdleConnsPerHost  = 100
+	HTTPRetryMax             = 5
+	HTTPRetryDurationMinimum = 200 * time.Millisecond
+	HTTPRetryDurationMax     = 1750 * time.Millisecond
 )
 
 const (


Test patch:
diff --git a/pkg/common/oras/authprovider/alibabacloud/alibabacloudacrbasic_test.go b/pkg/common/oras/authprovider/alibabacloud/alibabacloudacrbasic_test.go
new file mode 100644
index 0000000..fb4293b
--- /dev/null
+++ b/pkg/common/oras/authprovider/alibabacloud/alibabacloudacrbasic_test.go
@@ -0,0 +1,205 @@
+/*
+Copyright The Ratify Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package alibabacloud
+
+import (
+	"context"
+	"os"
+	"testing"
+
+	cr20181201 "github.com/alibabacloud-go/cr-20181201/v2/client"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
+)
+
+const (
+	// #nosec G101 (Ref: https://github.com/securego/gosec/issues/295)
+	testPassword              = "eyJwYXlsb2FkIjoiOThPNTFqemhaUmZWVG"
+	testUserMeta              = `{"instanceId":"cri-xxxxxxx","time":"1730185474000","type":"user","userId":"123456"}`
+	testHost                  = "test-registry.cn-hangzhou.cr.aliyuncs.com"
+	testInvalidHost           = "http://test-registry.cn-hangzhou.cr.aliyuncs.com"
+	testArtifact              = testHost + "/foo:latest"
+	testArtifactWithoutRegion = "test-registry-vpc.cr.aliyuncs.com/foo/test:latest"
+	testInstanceID            = "cri-testing"
+)
+
+// Mock types for external dependencies
+type MockAlibabaCloudAcrAuthTokenGetter struct {
+	mock.Mock
+}
+
+// Mock AlibabaCloudAcrAuthTokenGetter.GetAcrAuthToken
+func (m *MockAlibabaCloudAcrAuthTokenGetter) GetAcrAuthToken(artifact string, acrInstanceConfig map[string]string) (*cr20181201.GetAuthorizationTokenResponseBody, error) {
+	args := m.Called(artifact, acrInstanceConfig)
+	return args.Get(0).(*cr20181201.GetAuthorizationTokenResponseBody), args.Error(1)
+}
+
+// Verifies that alibabacloudAcrBasicAuthProvider is properly constructed by mocking AcrAuthToken
+func mockAuthProvider() alibabacloudAcrBasicAuthProvider {
+	// Setup
+	return alibabacloudAcrBasicAuthProvider{
+		providerName: alibabacloudAcrAuthProviderName,
+	}
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_Create(t *testing.T) {
+	authProviderConfig := map[string]interface{}{
+		"name":              "alibabacloudAcrBasic",
+		"defaultInstanceId": testInstanceID,
+	}
+
+	factory := AlibabaCloudAcrBasicProviderFactory{}
+	_, err := factory.Create(authProviderConfig)
+
+	if err != nil {
+		t.Fatalf("create failed %v", err)
+	}
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_CreateWithoutInstanceId(t *testing.T) {
+	authProviderConfig := map[string]interface{}{
+		"name": "alibabacloudAcrBasic",
+	}
+	factory := AlibabaCloudAcrBasicProviderFactory{}
+	_, err := factory.Create(authProviderConfig)
+	assert.Error(t, err)
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_CreateWithInvalidProviderConfig(t *testing.T) {
+	authProviderConfig := map[string]interface{}{
+		"name":    000,
+		"invalid": "test",
+	}
+	factory := AlibabaCloudAcrBasicProviderFactory{}
+	_, err := factory.Create(authProviderConfig)
+	assert.Error(t, err)
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_CreateWithMultiProviderConfig(t *testing.T) {
+	ic1 := acrInstancesConfig{
+		InstanceID:   "cri-testing1",
+		InstanceName: "test-instance-1",
+	}
+	ic2 := acrInstancesConfig{
+		InstanceID:   "cri-testing2",
+		InstanceName: "test-instance-2",
+	}
+	authProviderConfig := map[string]interface{}{
+		"name":               "alibabacloudAcrBasic",
+		"acrInstancesConfig": []acrInstancesConfig{ic1, ic2},
+	}
+	factory := AlibabaCloudAcrBasicProviderFactory{}
+	_, err := factory.Create(authProviderConfig)
+	assert.NoError(t, err)
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_Enabled(t *testing.T) {
+	authProvider := mockAuthProvider()
+
+	ctx := context.Background()
+
+	if !authProvider.Enabled(ctx) {
+		t.Fatal("enabled should have returned true but returned false")
+	}
+
+	authProvider.providerName = ""
+	if authProvider.Enabled(ctx) {
+		t.Fatal("enabled should have returned false but returned true")
+	}
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_ProvidesNotEnabled(t *testing.T) {
+	authProvider := alibabacloudAcrBasicAuthProvider{
+		providerName: "",
+	}
+	_, err := authProvider.Provide(context.TODO(), testInvalidHost)
+	assert.Error(t, err)
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_GetAuthTokenWithoutRRSAEnv(t *testing.T) {
+	acrInstancesConfig := make(map[string]string, 0)
+	_, err := getAcrAuthToken(testArtifactWithoutRegion, acrInstancesConfig)
+	assert.Error(t, err)
+
+	expectedMessage := "required environment variables not set, ALIBABA_CLOUD_ROLE_ARN: , ALIBABA_CLOUD_OIDC_PROVIDER_ARN: , ALIBABA_CLOUD_OIDC_TOKEN_FILE: "
+	if err.Error() != expectedMessage {
+		t.Fatalf("expected message: %s, instead got error: %s", expectedMessage, err.Error())
+	}
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_GetAuthTokenWithInvalidHost(t *testing.T) {
+	os.Setenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_ROLE_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE", "placeholder")
+	acrInstancesConfig := map[string]string{
+		"test": testInstanceID,
+	}
+	_, err := getAcrAuthToken(testInvalidHost, acrInstancesConfig)
+	assert.Error(t, err)
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_GetAuthTokenWithoutRegion(t *testing.T) {
+	os.Setenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_ROLE_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE", "placeholder")
+	acrInstancesConfig := make(map[string]string, 0)
+	_, err := getAcrAuthToken(testArtifactWithoutRegion, acrInstancesConfig)
+	assert.Error(t, err)
+
+	expectedMessage := "ALIBABACLOUD_IMAGE_INVALID: Invalid Alibaba Cloud Registry image format"
+	if err.Error() != expectedMessage {
+		t.Fatalf("expected message: %s, instead got error: %s", expectedMessage, err.Error())
+	}
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_GetAuthTokenWithInvalidInstanceId(t *testing.T) {
+	os.Setenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_ROLE_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE", "placeholder")
+	acrInstancesConfig := map[string]string{
+		"testInvalid": testInstanceID,
+	}
+	_, err := getAcrAuthToken(testHost, acrInstancesConfig)
+	assert.Error(t, err)
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_GetAuthTokenWithInvalidAcrClient(t *testing.T) {
+	os.Setenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_ROLE_ARN", "placeholder")
+	os.Setenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE", "placeholder")
+	acrInstancesConfig := map[string]string{
+		"test": testInstanceID,
+	}
+	_, err := getAcrAuthToken(testHost, acrInstancesConfig)
+	assert.Error(t, err)
+}
+
+func TestAlibabaCloudAcrBasicAuthProvider_Provide_TokenRefreshSuccess(t *testing.T) {
+	mockAlibabaCloudAcrAuthTokenGetter := new(MockAlibabaCloudAcrAuthTokenGetter)
+	mockACRToken := cr20181201.GetAuthorizationTokenResponseBody{}
+	mockAlibabaCloudAcrAuthTokenGetter.On("GetAcrAuthToken", "mockartifact", mock.Anything).Return(&mockACRToken, nil)
+
+	authProvider := alibabacloudAcrBasicAuthProvider{
+		providerName:    alibabacloudAcrAuthProviderName,
+		getAcrAuthToken: mockAlibabaCloudAcrAuthTokenGetter,
+	}
+
+	ctx := context.Background()
+	_, err := authProvider.Provide(ctx, "mockartifact")
+
+	// Validate success and token refresh
+	assert.NoError(t, err)
+}
diff --git a/pkg/common/oras/authprovider/alibabacloud/helper_test.go b/pkg/common/oras/authprovider/alibabacloud/helper_test.go
new file mode 100644
index 0000000..fe6ef78
--- /dev/null
+++ b/pkg/common/oras/authprovider/alibabacloud/helper_test.go
@@ -0,0 +1,60 @@
+/*
+Copyright The Ratify Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package alibabacloud
+
+import (
+	"reflect"
+	"testing"
+)
+
+func Test_getRegionFromArtifict(t *testing.T) {
+	type args struct {
+		artifact string
+	}
+	arg1 := "dahu-registry-vpc.cn-hangzhou.cr.aliyuncs.com"
+	arg2 := "registry-vpc.cn-beijing.aliyuncs.com"
+	arg3 := "test.bad"
+	arg4 := "registry-vpc.cr.aliyuncs.com"
+
+	tests := []struct {
+		name    string
+		args    args
+		want    *AcrMetaInfo
+		wantErr bool
+	}{
+		{"mock-test-get-region-from-artifict-1", args{arg1}, &AcrMetaInfo{
+			InstanceName: "dahu",
+			Region:       "cn-hangzhou",
+		}, false},
+		{"mock-test-get-region-from-artifict-2", args{arg2}, &AcrMetaInfo{
+			Region: "cn-beijing",
+		}, false},
+		{"mock-test-get-region-from-artifict-3", args{arg3}, nil, true},
+		{"mock-test-get-region-from-artifict-4", args{arg4}, nil, true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := getRegionFromArtifact(tt.args.artifact)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("getRegionFromArtifict() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("getRegionFromArtifict() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}