Repository: devtron-labs/devtron
Pull request #3703 (2023-07-28 06:28:47)

feat: chart provider APIs and registry validation
# Description
This PR contains the Chart Store new APIs:
- GET: chart provider list
- POST: toggle chart provider (enable/disable)
- POST: trigger chart sync job

Additionally : Registry Credentials Validation 
Refactored: Existing Queries, Handled Nil pointer issues 

## How Has This Been Tested?

- [x] GET: chart provider list (RBAC: SuperAdmin)
- [x] POST: toggle chart provider (enable/disable) (RBAC: SuperAdmin)
  - [x] Chart Repository: Blocked incase deployment existing  
  - [x] OCI Registry: NOT Blocked incase deployment existing  
- [x] POST: trigger chart sync job (RBAC: SuperAdmin)
  - [x] Specific to a chart provider
  - [x] All chart providers
- [x] Additional: 
  - [x] Fetch Chart Store Charts List (with Filter)
  - [x] OCI chart details 
  - [x] OCI chart Deployment details
  - [x] Chart Repo chart details 
  - [x] Chart Repo chart Deployment details
  - [x] Registry Credentials Validation 

## Checklist:

* [x] The title of the PR states what changed and the related issues number (used for the release note).
* [ ] Does this PR requires documentation updates?
* [ ] I've updated documentation as required by this PR.
* [x] I have performed a self-review of my own code.
* [x] I have commented my code, particularly in hard-to-understand areas.
* [x] I have tested it for all user roles.
* [ ] I have added all the required unit/api test cases.

## Does this PR introduce a user-facing change?
<!--
If NO, leave the release-note block blank.
If YES, a release note is required:
Enter your extended release note in the block below. If the PR requires additional manual action from users switching to the new version, include the string "action-required".

-->
```release-note

```

sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=devtron-labs_devtron&pullRequest=3703)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [15 Code Smells](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703) No Coverage information  
[![7.6%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/10-16px.png '7.6%')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list) [7.6% Duplication](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list)



![idea](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png 'idea') Catch issues before they fail your Quality Gate with our IDE extension ![sonarlint](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png 'sonarlint') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=sonarcloud-welcome)
sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=devtron-labs_devtron&pullRequest=3703)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [15 Code Smells](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703) No Coverage information  
[![5.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/10-16px.png '5.7%')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list) [5.7% Duplication](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list)



![idea](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png 'idea') Catch issues before they fail your Quality Gate with our IDE extension ![sonarlint](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png 'sonarlint') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=sonarcloud-welcome)
sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=devtron-labs_devtron&pullRequest=3703)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [15 Code Smells](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703) No Coverage information  
[![5.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/10-16px.png '5.7%')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list) [5.7% Duplication](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list)



![idea](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png 'idea') Catch issues before they fail your Quality Gate with our IDE extension ![sonarlint](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png 'sonarlint') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=sonarcloud-welcome)
sonarcloud[bot]: SonarCloud Quality Gate failed.&nbsp; &nbsp; [![Quality Gate failed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonarcloud.io/dashboard?id=devtron-labs_devtron&pullRequest=3703)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL) [15 Code Smells](https://sonarcloud.io/project/issues?id=devtron-labs_devtron&pullRequest=3703&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703) No Coverage information  
[![5.7%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/10-16px.png '5.7%')](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list) [5.7% Duplication](https://sonarcloud.io/component_measures?id=devtron-labs_devtron&pullRequest=3703&metric=new_duplicated_lines_density&view=list)



![idea](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/light_bulb-16px.png 'idea') Catch issues before they fail your Quality Gate with our IDE extension ![sonarlint](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/sonarlint-16px.png 'sonarlint') [SonarLint](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=sonarcloud-welcome)

Patch:
diff --git a/Wire.go b/Wire.go
index 713a887aa..dd0355393 100644
--- a/Wire.go
+++ b/Wire.go
@@ -25,6 +25,7 @@ import (
 	pubsub1 "github.com/devtron-labs/common-lib/pubsub-lib"
 	"github.com/devtron-labs/devtron/api/apiToken"
 	appStoreRestHandler "github.com/devtron-labs/devtron/api/appStore"
+	chartProvider "github.com/devtron-labs/devtron/api/appStore/ChartProvider"
 	appStoreDeployment "github.com/devtron-labs/devtron/api/appStore/deployment"
 	appStoreDiscover "github.com/devtron-labs/devtron/api/appStore/discover"
 	appStoreValues "github.com/devtron-labs/devtron/api/appStore/values"
@@ -136,6 +137,7 @@ func InitializeApp() (*App, error) {
 		k8s.K8sApplicationWireSet,
 		chartRepo.ChartRepositoryWireSet,
 		appStoreDiscover.AppStoreDiscoverWireSet,
+		chartProvider.AppStoreChartProviderExtWireSet,
 		appStoreValues.AppStoreValuesWireSet,
 		appStoreDeployment.AppStoreDeploymentWireSet,
 		server.ServerWireSet,
@@ -221,7 +223,6 @@ func InitializeApp() (*App, error) {
 		wire.Bind(new(pipeline.CiCdPipelineOrchestrator), new(*pipeline.CiCdPipelineOrchestratorImpl)),
 		pipelineConfig.NewMaterialRepositoryImpl,
 		wire.Bind(new(pipelineConfig.MaterialRepository), new(*pipelineConfig.MaterialRepositoryImpl)),
-
 		router.NewMigrateDbRouterImpl,
 		wire.Bind(new(router.MigrateDbRouter), new(*router.MigrateDbRouterImpl)),
 		restHandler.NewMigrateDbRestHandlerImpl,
diff --git a/api/appStore/AppStoreRouter.go b/api/appStore/AppStoreRouter.go
index 75a65324e..c23b3cfd9 100644
--- a/api/appStore/AppStoreRouter.go
+++ b/api/appStore/AppStoreRouter.go
@@ -18,6 +18,7 @@
 package appStore
 
 import (
+	chartProvider "github.com/devtron-labs/devtron/api/appStore/ChartProvider"
 	appStoreDeployment "github.com/devtron-labs/devtron/api/appStore/deployment"
 	appStoreDiscover "github.com/devtron-labs/devtron/api/appStore/discover"
 	appStoreValues "github.com/devtron-labs/devtron/api/appStore/values"
@@ -33,17 +34,21 @@ type AppStoreRouterImpl struct {
 	appStoreValuesRouter              appStoreValues.AppStoreValuesRouter
 	appStoreDiscoverRouter            appStoreDiscover.AppStoreDiscoverRouter
 	appStoreDeploymentRouter          appStoreDeployment.AppStoreDeploymentRouter
+	chartProviderRouter               chartProvider.ChartProviderRouter
 	appStoreStatusTimelineRestHandler AppStoreStatusTimelineRestHandler
 }
 
 func NewAppStoreRouterImpl(restHandler InstalledAppRestHandler,
-	appStoreValuesRouter appStoreValues.AppStoreValuesRouter, appStoreDiscoverRouter appStoreDiscover.AppStoreDiscoverRouter,
+	appStoreValuesRouter appStoreValues.AppStoreValuesRouter,
+	appStoreDiscoverRouter appStoreDiscover.AppStoreDiscoverRouter,
+	chartProviderRouter chartProvider.ChartProviderRouter,
 	appStoreDeploymentRouter appStoreDeployment.AppStoreDeploymentRouter,
 	appStoreStatusTimelineRestHandler AppStoreStatusTimelineRestHandler) *AppStoreRouterImpl {
 	return &AppStoreRouterImpl{
 		deployRestHandler:                 restHandler,
 		appStoreValuesRouter:              appStoreValuesRouter,
 		appStoreDiscoverRouter:            appStoreDiscoverRouter,
+		chartProviderRouter:               chartProviderRouter,
 		appStoreDeploymentRouter:          appStoreDeploymentRouter,
 		appStoreStatusTimelineRestHandler: appStoreStatusTimelineRestHandler,
 	}
@@ -69,6 +74,11 @@ func (router AppStoreRouterImpl) Init(configRouter *mux.Router) {
 	router.appStoreDiscoverRouter.Init(appStoreDiscoverSubRouter)
 	// discover router ends
 
+	// chart provider router starts
+	chartProviderSubRouter := configRouter.PathPrefix("/chart-provider").Subrouter()
+	router.chartProviderRouter.Init(chartProviderSubRouter)
+	// chart provider router ends
+
 	configRouter.Path("/application/exists").
 		HandlerFunc(router.deployRestHandler.CheckAppExists).Methods("POST")
 	configRouter.Path("/group/install").
diff --git a/api/appStore/ChartProvider/ChartProviderRestHandler.go b/api/appStore/ChartProvider/ChartProviderRestHandler.go
new file mode 100644
index 000000000..48eff6575
--- /dev/null
+++ b/api/appStore/ChartProvider/ChartProviderRestHandler.go
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2020 Devtron Labs
+ *
+ * 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 chartProvider
+
+import (
+	"encoding/json"
+	"github.com/devtron-labs/devtron/api/restHandler/common"
+	"github.com/devtron-labs/devtron/pkg/appStore/chartProvider"
+	"github.com/devtron-labs/devtron/pkg/user"
+	"github.com/devtron-labs/devtron/pkg/user/casbin"
+	"go.uber.org/zap"
+	"gopkg.in/go-playground/validator.v9"
+	"net/http"
+	"strconv"
+)
+
+type ChartProviderRestHandler interface {
+	GetChartProviderList(w http.ResponseWriter, r *http.Request)
+	ToggleChartProvider(w http.ResponseWriter, r *http.Request)
+	SyncChartProvider(w http.ResponseWriter, r *http.Request)
+}
+
+type ChartProviderRestHandlerImpl struct {
+	Logger               *zap.SugaredLogger
+	chartProviderService chartProvider.ChartProviderService
+	validator            *validator.Validate
+	userAuthService      user.UserService
+	enforcer             casbin.Enforcer
+}
+
+func NewChartProviderRestHandlerImpl(Logger *zap.SugaredLogger, userAuthService user.UserService, validator *validator.Validate, chartProviderService chartProvider.ChartProviderService,
+	enforcer casbin.Enforcer) *ChartProviderRestHandlerImpl {
+	return &ChartProviderRestHandlerImpl{
+		Logger:               Logger,
+		validator:            validator,
+		chartProviderService: chartProviderService,
+		userAuthService:      userAuthService,
+		enforcer:             enforcer,
+	}
+}
+
+func (handler *ChartProviderRestHandlerImpl) GetChartProviderList(w http.ResponseWriter, r *http.Request) {
+	userId, err := handler.userAuthService.GetLoggedInUser(r)
+	if userId == 0 || err != nil {
+		common.WriteJsonResp(w, err, nil, http.StatusUnauthorized)
+		return
+	}
+	handler.Logger.Infow("request payload, GetChartProviderList", "userId", userId)
+	token := r.Header.Get("token")
+	//RBAC starts
+	if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
+		handler.Logger.Infow("user forbidden to fetch chart providers list", "userId", userId)
+		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
+		return
+	}
+	//RBAC ends
+	res, err := handler.chartProviderService.GetChartProviderList()
+	if err != nil {
+		handler.Logger.Errorw("service err, GetChartProviderList", "err", err, "userId", userId)
+		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
+		return
+	}
+	common.WriteJsonResp(w, err, res, http.StatusOK)
+}
+
+func (handler *ChartProviderRestHandlerImpl) ToggleChartProvider(w http.ResponseWriter, r *http.Request) {
+	decoder := json.NewDecoder(r.Body)
+	userId, err := handler.userAuthService.GetLoggedInUser(r)
+	if userId == 0 || err != nil {
+		common.WriteJsonResp(w, err, nil, http.StatusUnauthorized)
+		return
+	}
+	var request chartProvider.ChartProviderRequestDto
+	err = decoder.Decode(&request)
+	if err != nil {
+		handler.Logger.Errorw("request err, ToggleChartProvider", "err", err, "payload", request)
+		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
+		return
+	}
+	err = handler.validator.Struct(request)
+	if err != nil {
+		handler.Logger.Errorw("validation err, ToggleChartProvider", "err", err, "payload", request)
+		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
+		return
+	}
+	handler.Logger.Infow("request payload, ToggleChartProvider", "payload", request, "userId", userId)
+	token := r.Header.Get("token")
+	//RBAC starts
+	if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
+		handler.Logger.Infow("user forbidden to toggle chart provider", "userId", userId)
+		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
+		return
+	}
+	//RBAC ends
+	request.UserId = userId
+	err = ValidateRequestObjectForChartRepoId(&request)
+	if err != nil {
+		handler.Logger.Errorw("request err, ToggleChartProvider", "err", err, "ChartRepoId", request.Id)
+		common.WriteJsonResp(w, err, "Invalid ChartRepoId", http.StatusBadRequest)
+		return
+	}
+	err = handler.chartProviderService.ToggleChartProvider(&request)
+	if err != nil {
+		handler.Logger.Errorw("service err, ToggleChartProvider", "err", err, "userId", userId)
+		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
+		return
+	}
+	common.WriteJsonResp(w, err, nil, http.StatusOK)
+}
+
+func (handler *ChartProviderRestHandlerImpl) SyncChartProvider(w http.ResponseWriter, r *http.Request) {
+	decoder := json.NewDecoder(r.Body)
+	userId, err := handler.userAuthService.GetLoggedInUser(r)
+	if userId == 0 || err != nil {
+		common.WriteJsonResp(w, err, nil, http.StatusUnauthorized)
+		return
+	}
+	var request chartProvider.ChartProviderRequestDto
+	err = decoder.Decode(&request)
+	if err != nil {
+		handler.Logger.Errorw("request err, SyncChartProvider", "err", err, "payload", request)
+		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
+		return
+	}
+	err = handler.validator.Struct(request)
+	if err != nil {
+		handler.Logger.Errorw("validation err, SyncChartProvider", "err", err, "payload", request)
+		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
+		return
+	}
+	handler.Logger.Infow("request payload, SyncChartProvider", "payload", request, "userId", userId)
+	token := r.Header.Get("token")
+	//RBAC starts
+	if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
+		handler.Logger.Infow("user forbidden to sync chart provider", "userId", userId)
+		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
+		return
+	}
+	//RBAC ends
+	request.UserId = userId
+	err = ValidateRequestObjectForChartRepoId(&request)
+	if err != nil {
+		handler.Logger.Errorw("request err, ToggleChartProvider", "err", err, "ChartRepoId", request.Id)
+		common.WriteJsonResp(w, err, "Invalid ChartRepoId", http.StatusBadRequest)
+		return
+	}
+	err = handler.chartProviderService.SyncChartProvider(&request)
+	if err != nil {
+		handler.Logger.Errorw("service err, SyncChartProvider", "err", err, "userId", userId)
+		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
+		return
+	}
+	common.WriteJsonResp(w, err, nil, http.StatusOK)
+}
+
+func ValidateRequestObjectForChartRepoId(request *chartProvider.ChartProviderRequestDto) error {
+	if !request.IsOCIRegistry {
+		chartRepoId, err := strconv.Atoi(request.Id)
+		if err != nil || chartRepoId <= 0 {
+			return err
+		}
+		request.ChartRepoId = chartRepoId
+	}
+	return nil
+}
diff --git a/api/appStore/ChartProvider/ChartProviderRouter.go b/api/appStore/ChartProvider/ChartProviderRouter.go
new file mode 100644
index 000000000..825e8c99f
--- /dev/null
+++ b/api/appStore/ChartProvider/ChartProviderRouter.go
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2020 Devtron Labs
+ *
+ * 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 chartProvider
+
+import (
+	"github.com/gorilla/mux"
+)
+
+type ChartProviderRouter interface {
+	Init(configRouter *mux.Router)
+}
+
+type ChartProviderRouterImpl struct {
+	chartProviderRestHandler ChartProviderRestHandler
+}
+
+func NewChartProviderRouterImpl(chartProviderRestHandler ChartProviderRestHandler) *ChartProviderRouterImpl {
+	return &ChartProviderRouterImpl{
+		chartProviderRestHandler: chartProviderRestHandler,
+	}
+}
+
+func (router ChartProviderRouterImpl) Init(configRouter *mux.Router) {
+	configRouter.Path("/list").
+		HandlerFunc(router.chartProviderRestHandler.GetChartProviderList).Methods("GET")
+	configRouter.Path("/update").
+		HandlerFunc(router.chartProviderRestHandler.ToggleChartProvider).Methods("POST")
+	configRouter.Path("/sync-chart").
+		HandlerFunc(router.chartProviderRestHandler.SyncChartProvider).Methods("POST")
+}
diff --git a/api/appStore/ChartProvider/wire_appStoreChartProvider.go b/api/appStore/ChartProvider/wire_appStoreChartProvider.go
new file mode 100644
index 000000000..a8edc64d6
--- /dev/null
+++ b/api/appStore/ChartProvider/wire_appStoreChartProvider.go
@@ -0,0 +1,23 @@
+package chartProvider
+
+import (
+	chartProviderService "github.com/devtron-labs/devtron/pkg/appStore/chartProvider"
+	"github.com/google/wire"
+)
+
+var AppStoreChartProviderWireSet = wire.NewSet(
+	chartProviderService.NewChartProviderServiceImpl,
+	wire.Bind(new(chartProviderService.ChartProviderService), new(*chartProviderService.ChartProviderServiceImpl)),
+	NewChartProviderRestHandlerImpl,
+	wire.Bind(new(ChartProviderRestHandler), new(*ChartProviderRestHandlerImpl)),
+	NewChartProviderRouterImpl,
+	wire.Bind(new(ChartProviderRouter), new(*ChartProviderRouterImpl)))
+
+var AppStoreChartProviderExtWireSet = wire.NewSet(
+	chartProviderService.NewChartProviderServiceExtendedImpl,
+	wire.Bind(new(chartProviderService.ChartProviderService), new(*chartProviderService.ChartProviderServiceExtendedImpl)),
+	NewChartProviderRestHandlerImpl,
+	wire.Bind(new(ChartProviderRestHandler), new(*ChartProviderRestHandlerImpl)),
+	NewChartProviderRouterImpl,
+	wire.Bind(new(ChartProviderRouter), new(*ChartProviderRouterImpl)),
+)
diff --git a/api/appStore/discover/AppStoreRestHandler.go b/api/appStore/discover/AppStoreRestHandler.go
index 3a623178c..22cef32d5 100644
--- a/api/appStore/discover/AppStoreRestHandler.go
+++ b/api/appStore/discover/AppStoreRestHandler.go
@@ -83,6 +83,15 @@ func (handler *AppStoreRestHandlerImpl) FindAllApps(w http.ResponseWriter, r *ht
 			}
 		}
 	}
+	var registryIds []string
+	registryIdsStrArr := v.Get("registryId")
+	if len(registryIdsStrArr) > 0 {
+		registryIdStrArr := strings.Split(registryIdsStrArr, ",")
+		for _, registryId := range registryIdStrArr {
+			registryIds = append(registryIds, registryId)
+		}
+	}
+
 	appStoreName := strings.ToLower(v.Get("appStoreName"))
 
 	offset := 0
@@ -95,7 +104,12 @@ func (handler *AppStoreRestHandlerImpl) FindAllApps(w http.ResponseWriter, r *ht
 	if len(sizeStr) > 0 {
 		size, _ = strconv.Atoi(sizeStr)
 	}
-	filter := &appStoreBean.AppStoreFilter{IncludeDeprecated: deprecated, ChartRepoId: chartRepoIds, AppStoreName: appStoreName}
+	filter := &appStoreBean.AppStoreFilter{
+		IncludeDeprecated: deprecated,
+		ChartRepoId:       chartRepoIds,
+		RegistryId:        registryIds,
+		AppStoreName:      appStoreName,
+	}
 	if size > 0 {
 		filter.Size = size
 		filter.Offset = offset
diff --git a/api/chartRepo/ChartRepositoryRestHandler.go b/api/chartRepo/ChartRepositoryRestHandler.go
index c9910293e..738240635 100644
--- a/api/chartRepo/ChartRepositoryRestHandler.go
+++ b/api/chartRepo/ChartRepositoryRestHandler.go
@@ -281,7 +281,11 @@ func (handler *ChartRepositoryRestHandlerImpl) TriggerChartSyncManual(w http.Res
 		common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
 		return
 	}
-	err2 := handler.chartRepositoryService.TriggerChartSyncManual()
+	chartProviderConfig := &chartRepo.ChartProviderConfig{
+		ChartProviderId: "*",
+		IsOCIRegistry:   true,
+	}
+	err2 := handler.chartRepositoryService.TriggerChartSyncManual(chartProviderConfig)
 	if err2 != nil {
 		common.WriteJsonResp(w, err2, nil, http.StatusInternalServerError)
 	} else {
diff --git a/api/helm-app/HelmAppService.go b/api/helm-app/HelmAppService.go
index 1f4ac6e8c..a1514ad6f 100644
--- a/api/helm-app/HelmAppService.go
+++ b/api/helm-app/HelmAppService.go
@@ -61,6 +61,7 @@ type HelmAppService interface {
 	UpdateApplicationWithChartInfoWithExtraValues(ctx context.Context, appIdentifier *AppIdentifier, chartRepository *ChartRepository, extraValues map[string]interface{}, extraValuesYamlUrl string, useLatestChartVersion bool) (*openapi.UpdateReleaseResponse, error)
 	TemplateChart(ctx context.Context, templateChartRequest *openapi2.TemplateChartRequest) (*openapi2.TemplateChartResponse, error)
 	GetNotes(ctx context.Context, request *InstallReleaseRequest) (string, error)
+	ValidateOCIRegistry(ctx context.Context, OCIRegistryRequest *RegistryCredential) bool
 	GetRevisionHistoryMaxValue(appType SourceAppType) int32
 }
 
@@ -779,6 +780,15 @@ func (impl *HelmAppServiceImpl) GetNotes(ctx context.Context, request *InstallRe
 	return notesTxt, err
 }
 
+func (impl *HelmAppServiceImpl) ValidateOCIRegistry(ctx context.Context, OCIRegistryRequest *RegistryCredential) bool {
+	response, err := impl.helmAppClient.ValidateOCIRegistry(ctx, OCIRegistryRequest)
+	if err != nil {
+		impl.logger.Errorw("error in fetching chart", "err", err)
+		return false
+	}
+	return response.IsLoggedIn
+}
+
 type AppIdentifier struct {
 	ClusterId   int    `json:"clusterId"`
 	Namespace   string `json:"namespace"`
diff --git a/api/helm-app/applicationClient.go b/api/helm-app/applicationClient.go
index 421d2e0d7..67e00279c 100644
--- a/api/helm-app/applicationClient.go
+++ b/api/helm-app/applicationClient.go
@@ -29,6 +29,7 @@ type HelmAppClient interface {
 	TemplateChart(ctx context.Context, in *InstallReleaseRequest) (*TemplateChartResponse, error)
 	InstallReleaseWithCustomChart(ctx context.Context, in *HelmInstallCustomRequest) (*HelmInstallCustomResponse, error)
 	GetNotes(ctx context.Context, request *InstallReleaseRequest) (*ChartNotesResponse, error)
+	ValidateOCIRegistry(ctx context.Context, OCIRegistryRequest *RegistryCredential) (*OCIRegistryResponse, error)
 }
 
 type HelmAppClientImpl struct {
@@ -305,3 +306,15 @@ func (impl *HelmAppClientImpl) GetNotes(ctx context.Context, in *InstallReleaseR
 	return response, nil
 
 }
+
+func (impl *HelmAppClientImpl) ValidateOCIRegistry(ctx context.Context, in *RegistryCredential) (*OCIRegistryResponse, error) {
+	applicationClient, err := impl.getApplicationClient()
+	if err != nil {
+		return nil, err
+	}
+	response, err := applicationClient.ValidateOCIRegistry(ctx, in)
+	if err != nil {
+		return nil, err
+	}
+	return response, nil
+}
diff --git a/api/helm-app/applist.pb.go b/api/helm-app/applist.pb.go
index a293d0a07..a1c09a674 100644
--- a/api/helm-app/applist.pb.go
+++ b/api/helm-app/applist.pb.go
@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.31.0
+// 	protoc-gen-go v1.28.1
 // 	protoc        v3.9.1
 // source: api/helm-app/applist.proto
 
@@ -3024,6 +3024,164 @@ func (x *ChartNotesResponse) GetNotes() string {
 	return ""
 }
 
+type RegistryCredential struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RegistryUrl  string `protobuf:"bytes,1,opt,name=RegistryUrl,proto3" json:"RegistryUrl,omitempty"`
+	Username     string `protobuf:"bytes,2,opt,name=Username,proto3" json:"Username,omitempty"`
+	Password     string `protobuf:"bytes,3,opt,name=Password,proto3" json:"Password,omitempty"`
+	AwsRegion    string `protobuf:"bytes,4,opt,name=AwsRegion,proto3" json:"AwsRegion,omitempty"`
+	AccessKey    string `protobuf:"bytes,5,opt,name=AccessKey,proto3" json:"AccessKey,omitempty"`
+	SecretKey    string `protobuf:"bytes,6,opt,name=SecretKey,proto3" json:"SecretKey,omitempty"`
+	RegistryType string `protobuf:"bytes,7,opt,name=RegistryType,proto3" json:"RegistryType,omitempty"`
+	RepoName     string `protobuf:"bytes,8,opt,name=RepoName,proto3" json:"RepoName,omitempty"`
+	IsPublic     bool   `protobuf:"varint,9,opt,name=IsPublic,proto3" json:"IsPublic,omitempty"`
+}
+
+func (x *RegistryCredential) Reset() {
+	*x = RegistryCredential{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_helm_app_applist_proto_msgTypes[47]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RegistryCredential) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RegistryCredential) ProtoMessage() {}
+
+func (x *RegistryCredential) ProtoReflect() protoreflect.Message {
+	mi := &file_api_helm_app_applist_proto_msgTypes[47]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RegistryCredential.ProtoReflect.Descriptor instead.
+func (*RegistryCredential) Descriptor() ([]byte, []int) {
+	return file_api_helm_app_applist_proto_rawDescGZIP(), []int{47}
+}
+
+func (x *RegistryCredential) GetRegistryUrl() string {
+	if x != nil {
+		return x.RegistryUrl
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetUsername() string {
+	if x != nil {
+		return x.Username
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetPassword() string {
+	if x != nil {
+		return x.Password
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetAwsRegion() string {
+	if x != nil {
+		return x.AwsRegion
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetAccessKey() string {
+	if x != nil {
+		return x.AccessKey
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetSecretKey() string {
+	if x != nil {
+		return x.SecretKey
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetRegistryType() string {
+	if x != nil {
+		return x.RegistryType
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetRepoName() string {
+	if x != nil {
+		return x.RepoName
+	}
+	return ""
+}
+
+func (x *RegistryCredential) GetIsPublic() bool {
+	if x != nil {
+		return x.IsPublic
+	}
+	return false
+}
+
+type OCIRegistryResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	IsLoggedIn bool `protobuf:"varint,1,opt,name=IsLoggedIn,proto3" json:"IsLoggedIn,omitempty"`
+}
+
+func (x *OCIRegistryResponse) Reset() {
+	*x = OCIRegistryResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_helm_app_applist_proto_msgTypes[48]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OCIRegistryResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OCIRegistryResponse) ProtoMessage() {}
+
+func (x *OCIRegistryResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_api_helm_app_applist_proto_msgTypes[48]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OCIRegistryResponse.ProtoReflect.Descriptor instead.
+func (*OCIRegistryResponse) Descriptor() ([]byte, []int) {
+	return file_api_helm_app_applist_proto_rawDescGZIP(), []int{48}
+}
+
+func (x *OCIRegistryResponse) GetIsLoggedIn() bool {
+	if x != nil {
+		return x.IsLoggedIn
+	}
+	return false
+}
+
 var File_api_helm_app_applist_proto protoreflect.FileDescriptor
 
 var file_api_helm_app_applist_proto_rawDesc = []byte{
@@ -3442,90 +3600,116 @@ var file_api_helm_app_applist_proto_rawDesc = []byte{
 	0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x2a, 0x0a, 0x12, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4e,
 	0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05,
 	0x6e, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74,
-	0x65, 0x73, 0x32, 0xf6, 0x09, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x10, 0x4c, 0x69, 0x73,
-	0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e,
-	0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10,
-	0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74,
-	0x22, 0x00, 0x30, 0x01, 0x12, 0x2f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x44, 0x65,
-	0x74, 0x61, 0x69, 0x6c, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74,
-	0x61, 0x69, 0x6c, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69,
-	0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74,
-	0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e,
-	0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61,
-	0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0b,
-	0x55, 0x6e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x48, 0x69,
-	0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
-	0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f,
-	0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x11, 0x2e, 0x41,
-	0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x19, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d,
-	0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0d,
-	0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x11, 0x2e,
-	0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x0c, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00,
-	0x12, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61,
-	0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64,
-	0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x00, 0x12, 0x43, 0x0a, 0x10, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52,
-	0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
-	0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x19, 0x2e, 0x55, 0x6e, 0x69,
-	0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x67, 0x72, 0x61,
-	0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x16, 0x2e, 0x55, 0x70, 0x67, 0x72,
-	0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61,
-	0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x13,
-	0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74,
-	0x61, 0x69, 0x6c, 0x12, 0x18, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74,
+	0x65, 0x73, 0x22, 0xa4, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43,
+	0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x67,
+	0x69, 0x73, 0x74, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
+	0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x55,
+	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55,
+	0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77,
+	0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77,
+	0x6f, 0x72, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x77, 0x73, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x41, 0x77, 0x73, 0x52, 0x65, 0x67, 0x69, 0x6f,
+	0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12,
+	0x1c, 0x0a, 0x09, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a,
+	0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x54, 0x79, 0x70,
+	0x65, 0x12, 0x1a, 0x0a, 0x08, 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x08, 0x52, 0x65, 0x70, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a,
+	0x08, 0x49, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x08, 0x49, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x22, 0x35, 0x0a, 0x13, 0x4f, 0x43, 0x49,
+	0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x1e, 0x0a, 0x0a, 0x49, 0x73, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x49, 0x73, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x49, 0x6e,
+	0x32, 0xba, 0x0a, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x41,
+	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0f, 0x2e, 0x41, 0x70,
+	0x70, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x44,
+	0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x41, 0x70, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00,
+	0x30, 0x01, 0x12, 0x2f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74,
+	0x65, 0x12, 0x11, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x0b, 0x55, 0x6e,
+	0x48, 0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x11, 0x2e, 0x48, 0x69, 0x62, 0x65,
+	0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x48,
+	0x69, 0x62, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x00, 0x12, 0x46, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d,
+	0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x11, 0x2e, 0x41, 0x70, 0x70,
 	0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e,
-	0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x49, 0x6e,
-	0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x16, 0x2e, 0x49,
+	0x48, 0x65, 0x6c, 0x6d, 0x41, 0x70, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e,
+	0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x0d, 0x47, 0x65,
+	0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x11, 0x2e, 0x41, 0x70,
+	0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c,
+	0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x00, 0x12, 0x40,
+	0x0a, 0x12, 0x47, 0x65, 0x74, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61, 0x6e, 0x69,
+	0x66, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x44, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x4d, 0x61,
+	0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x12, 0x43, 0x0a, 0x10, 0x55, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c,
+	0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x64,
+	0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x19, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x73,
+	0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x16, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64,
+	0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x13, 0x47, 0x65,
+	0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x12, 0x18, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65,
+	0x74, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x44, 0x65,
+	0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74,
+	0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73,
+	0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x17, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65,
+	0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a,
+	0x1b, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57,
+	0x69, 0x74, 0x68, 0x43, 0x68, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x49,
 	0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65,
 	0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
-	0x50, 0x0a, 0x1b, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x68, 0x61, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16,
+	0x3c, 0x0a, 0x12, 0x49, 0x73, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x73, 0x74,
+	0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49,
+	0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x10, 0x2e, 0x42, 0x6f, 0x6f, 0x6c,
+	0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a,
+	0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65,
+	0x12, 0x17, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61,
+	0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x42, 0x6f, 0x6f, 0x6c,
+	0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a,
+	0x0d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x16,
 	0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
-	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x00, 0x12, 0x3c, 0x0a, 0x12, 0x49, 0x73, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x49, 0x6e,
-	0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x12, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x10, 0x2e, 0x42, 0x6f,
-	0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
-	0x3e, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c, 0x65, 0x61,
-	0x73, 0x65, 0x12, 0x17, 0x2e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x6c,
-	0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x42, 0x6f,
-	0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
-	0x41, 0x0a, 0x0d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, 0x74,
-	0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c,
-	0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x00, 0x12, 0x58, 0x0a, 0x1d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c,
-	0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68,
-	0x61, 0x72, 0x74, 0x12, 0x19, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c,
-	0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a,
-	0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74,
-	0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x08,
-	0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61,
-	0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x13, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x1d, 0x55, 0x70, 0x67, 0x72, 0x61,
-	0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x75, 0x73,
-	0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61,
-	0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x17, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73,
-	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x33, 0x5a, 0x31, 0x67,
-	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x74, 0x72, 0x6f,
-	0x6e, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x69, 0x6e, 0x6b, 0x2f,
-	0x62, 0x65, 0x61, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
-	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
+	0x65, 0x43, 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x12, 0x58, 0x0a, 0x1d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x6c, 0x65, 0x61,
+	0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x68, 0x61, 0x72,
+	0x74, 0x12, 0x19, 0x2e, 0x48, 0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43,
+	0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x48,
+	0x65, 0x6c, 0x6d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x08, 0x47, 0x65,
+	0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13,
+	0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x1d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x75, 0x73, 0x74, 0x6f,
+	0x6d, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
+	0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17,
+	0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x13, 0x56, 0x61, 0x6c,
+	0x69, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x43, 0x49, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79,
+	0x12, 0x13, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x43, 0x72, 0x65, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x14, 0x2e, 0x4f, 0x43, 0x49, 0x52, 0x65, 0x67, 0x69, 0x73,
+	0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x33, 0x5a,
+	0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x65, 0x76, 0x74,
+	0x72, 0x6f, 0x6e, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x69, 0x6e,
+	0x6b, 0x2f, 0x62, 0x65, 0x61, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -3540,7 +3724,7 @@ func file_api_helm_app_applist_proto_rawDescGZIP() []byte {
 	return file_api_helm_app_applist_proto_rawDescData
 }
 
-var file_api_helm_app_applist_proto_msgTypes = make([]protoimpl.MessageInfo, 49)
+var file_api_helm_app_applist_proto_msgTypes = make([]protoimpl.MessageInfo, 51)
 var file_api_helm_app_applist_proto_goTypes = []interface{}{
 	(*ClusterConfig)(nil),             // 0: ClusterConfig
 	(*AppListRequest)(nil),            // 1: AppListRequest
@@ -3589,19 +3773,21 @@ var file_api_helm_app_applist_proto_goTypes = []interface{}{
 	(*ResourceIdentifier)(nil),        // 44: ResourceIdentifier
 	(*ResourceTreeFilter)(nil),        // 45: ResourceTreeFilter
 	(*ChartNotesResponse)(nil),        // 46: ChartNotesResponse
-	nil,                               // 47: ResourceNetworkingInfo.LabelsEntry
-	nil,                               // 48: ResourceIdentifier.LabelsEntry
-	(*timestamp.Timestamp)(nil),       // 49: google.protobuf.Timestamp
+	(*RegistryCredential)(nil),        // 47: RegistryCredential
+	(*OCIRegistryResponse)(nil),       // 48: OCIRegistryResponse
+	nil,                               // 49: ResourceNetworkingInfo.LabelsEntry
+	nil,                               // 50: ResourceIdentifier.LabelsEntry
+	(*timestamp.Timestamp)(nil),       // 51: google.protobuf.Timestamp
 }
 var file_api_helm_app_applist_proto_depIdxs = []int32{
 	0,  // 0: AppListRequest.clusters:type_name -> ClusterConfig
 	3,  // 1: DeployedAppList.DeployedAppDetail:type_name -> DeployedAppDetail
 	4,  // 2: DeployedAppDetail.environmentDetail:type_name -> EnvironmentDetails
-	49, // 3: DeployedAppDetail.LastDeployed:type_name -> google.protobuf.Timestamp
+	51, // 3: DeployedAppDetail.LastDeployed:type_name -> google.protobuf.Timestamp
 	0,  // 4: AppDetailRequest.clusterConfig:type_name -> ClusterConfig
 	45, // 5: AppDetailRequest.resourceTreeFilter:type_name -> ResourceTreeFilter
 	8,  // 6: AppDetail.releaseStatus:type_name -> ReleaseStatus
-	49, // 7: AppDetail.lastDeployed:type_name -> google.protobuf.Timestamp
+	51, // 7: AppDetail.lastDeployed:type_name -> google.protobuf.Timestamp
 	9,  // 8: AppDetail.chartMetadata:type_name -> ChartMetadata
 	10, // 9: AppDetail.resourceTreeResponse:type_name -> ResourceTreeResponse
 	4,  // 10: AppDetail.environmentDetails:type_name -> EnvironmentDetails
@@ -3611,14 +3797,14 @@ var file_api_helm_app_applist_proto_depIdxs = []int32{
 	14, // 14: ResourceNode.networkingInfo:type_name -> ResourceNetworkingInfo
 	13, // 15: ResourceNode.health:type_name -> HealthStatus
 	12, // 16: ResourceNode.info:type_name -> InfoItem
-	47, // 17: ResourceNetworkingInfo.labels:type_name -> ResourceNetworkingInfo.LabelsEntry
+	49, // 17: ResourceNetworkingInfo.labels:type_name -> ResourceNetworkingInfo.LabelsEntry
 	17, // 18: PodMetadata.ephemeralContainers:type_name -> EphemeralContainerData
 	0,  // 19: HibernateRequest.clusterConfig:type_name -> ClusterConfig
 	19, // 20: HibernateRequest.objectIdentifier:type_name -> ObjectIdentifier
 	19, // 21: HibernateStatus.targetObject:type_name -> ObjectIdentifier
 	20, // 22: HibernateResponse.status:type_name -> HibernateStatus
 	9,  // 23: HelmAppDeploymentDetail.chartMetadata:type_name -> ChartMetadata
-	49, // 24: HelmAppDeploymentDetail.deployedAt:type_name -> google.protobuf.Timestamp
+	51, // 24: HelmAppDeploymentDetail.deployedAt:type_name -> google.protobuf.Timestamp
 	22, // 25: HelmAppDeploymentHistory.deploymentHistory:type_name -> HelmAppDeploymentDetail
 	3,  // 26: ReleaseInfo.deployedAppDetail:type_name -> DeployedAppDetail
 	0,  // 27: ObjectRequest.clusterConfig:type_name -> ClusterConfig
@@ -3634,7 +3820,7 @@ var file_api_helm_app_applist_proto_depIdxs = []int32{
 	28, // 37: HelmInstallCustomRequest.releaseIdentifier:type_name -> ReleaseIdentifier
 	42, // 38: ResourceFilter.gvk:type_name -> Gvk
 	44, // 39: ResourceFilter.resourceIdentifier:type_name -> ResourceIdentifier
-	48, // 40: ResourceIdentifier.labels:type_name -> ResourceIdentifier.LabelsEntry
+	50, // 40: ResourceIdentifier.labels:type_name -> ResourceIdentifier.LabelsEntry
 	44, // 41: ResourceTreeFilter.globalFilter:type_name -> ResourceIdentifier
 	43, // 42: ResourceTreeFilter.resourceFilters:type_name -> ResourceFilter
 	1,  // 43: ApplicationService.ListApplications:input_type -> AppListRequest
@@ -3656,27 +3842,29 @@ var file_api_helm_app_applist_proto_depIdxs = []int32{
 	39, // 59: ApplicationService.InstallReleaseWithCustomChart:input_type -> HelmInstallCustomRequest
 	34, // 60: ApplicationService.GetNotes:input_type -> InstallReleaseRequest
 	29, // 61: ApplicationService.UpgradeReleaseWithCustomChart:input_type -> UpgradeReleaseRequest
-	2,  // 62: ApplicationService.ListApplications:output_type -> DeployedAppList
-	6,  // 63: ApplicationService.GetAppDetail:output_type -> AppDetail
-	7,  // 64: ApplicationService.GetAppStatus:output_type -> AppStatus
-	21, // 65: ApplicationService.Hibernate:output_type -> HibernateResponse
-	21, // 66: ApplicationService.UnHibernate:output_type -> HibernateResponse
-	23, // 67: ApplicationService.GetDeploymentHistory:output_type -> HelmAppDeploymentHistory
-	24, // 68: ApplicationService.GetValuesYaml:output_type -> ReleaseInfo
-	26, // 69: ApplicationService.GetDesiredManifest:output_type -> DesiredManifestResponse
-	27, // 70: ApplicationService.UninstallRelease:output_type -> UninstallReleaseResponse
-	30, // 71: ApplicationService.UpgradeRelease:output_type -> UpgradeReleaseResponse
-	32, // 72: ApplicationService.GetDeploymentDetail:output_type -> DeploymentDetailResponse
-	35, // 73: ApplicationService.InstallRelease:output_type -> InstallReleaseResponse
-	30, // 74: ApplicationService.UpgradeReleaseWithChartInfo:output_type -> UpgradeReleaseResponse
-	36, // 75: ApplicationService.IsReleaseInstalled:output_type -> BooleanResponse
-	36, // 76: ApplicationService.RollbackRelease:output_type -> BooleanResponse
-	38, // 77: ApplicationService.TemplateChart:output_type -> TemplateChartResponse
-	40, // 78: ApplicationService.InstallReleaseWithCustomChart:output_type -> HelmInstallCustomResponse
-	46, // 79: ApplicationService.GetNotes:output_type -> ChartNotesResponse
-	30, // 80: ApplicationService.UpgradeReleaseWithCustomChart:output_type -> UpgradeReleaseResponse
-	62, // [62:81] is the sub-list for method output_type
-	43, // [43:62] is the sub-list for method input_type
+	47, // 62: ApplicationService.ValidateOCIRegistry:input_type -> RegistryCredential
+	2,  // 63: ApplicationService.ListApplications:output_type -> DeployedAppList
+	6,  // 64: ApplicationService.GetAppDetail:output_type -> AppDetail
+	7,  // 65: ApplicationService.GetAppStatus:output_type -> AppStatus
+	21, // 66: ApplicationService.Hibernate:output_type -> HibernateResponse
+	21, // 67: ApplicationService.UnHibernate:output_type -> HibernateResponse
+	23, // 68: ApplicationService.GetDeploymentHistory:output_type -> HelmAppDeploymentHistory
+	24, // 69: ApplicationService.GetValuesYaml:output_type -> ReleaseInfo
+	26, // 70: ApplicationService.GetDesiredManifest:output_type -> DesiredManifestResponse
+	27, // 71: ApplicationService.UninstallRelease:output_type -> UninstallReleaseResponse
+	30, // 72: ApplicationService.UpgradeRelease:output_type -> UpgradeReleaseResponse
+	32, // 73: ApplicationService.GetDeploymentDetail:output_type -> DeploymentDetailResponse
+	35, // 74: ApplicationService.InstallRelease:output_type -> InstallReleaseResponse
+	30, // 75: ApplicationService.UpgradeReleaseWithChartInfo:output_type -> UpgradeReleaseResponse
+	36, // 76: ApplicationService.IsReleaseInstalled:output_type -> BooleanResponse
+	36, // 77: ApplicationService.RollbackRelease:output_type -> BooleanResponse
+	38, // 78: ApplicationService.TemplateChart:output_type -> TemplateChartResponse
+	40, // 79: ApplicationService.InstallReleaseWithCustomChart:output_type -> HelmInstallCustomResponse
+	46, // 80: ApplicationService.GetNotes:output_type -> ChartNotesResponse
+	30, // 81: ApplicationService.UpgradeReleaseWithCustomChart:output_type -> UpgradeReleaseResponse
+	48, // 82: ApplicationService.ValidateOCIRegistry:output_type -> OCIRegistryResponse
+	63, // [63:83] is the sub-list for method output_type
+	43, // [43:63] is the sub-list for method input_type
 	43, // [43:43] is the sub-list for extension type_name
 	43, // [43:43] is the sub-list for extension extendee
 	0,  // [0:43] is the sub-list for field type_name
@@ -4252,6 +4440,30 @@ func file_api_helm_app_applist_proto_init() {
 				return nil
 			}
 		}
+		file_api_helm_app_applist_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RegistryCredential); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_helm_app_applist_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OCIRegistryResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -4259,7 +4471,7 @@ func file_api_helm_app_applist_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_api_helm_app_applist_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   49,
+			NumMessages:   51,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/api/helm-app/applist.proto b/api/helm-app/applist.proto
index d94261c48..eba7f9fb2 100644
--- a/api/helm-app/applist.proto
+++ b/api/helm-app/applist.proto
@@ -35,6 +35,7 @@ service ApplicationService {
   rpc InstallReleaseWithCustomChart(HelmInstallCustomRequest) returns (HelmInstallCustomResponse) {}
   rpc GetNotes(InstallReleaseRequest) returns (ChartNotesResponse) {}
   rpc UpgradeReleaseWithCustomChart(UpgradeReleaseRequest) returns(UpgradeReleaseResponse){}
+  rpc ValidateOCIRegistry(RegistryCredential) returns(OCIRegistryResponse) {}
 }
 
 message DeployedAppList {
@@ -315,4 +316,20 @@ message ResourceTreeFilter {
 }
 message ChartNotesResponse{
   string notes = 1;
+}
+
+message RegistryCredential {
+  string RegistryUrl = 1;
+  string Username = 2;
+  string Password = 3;
+  string AwsRegion = 4;
+  string AccessKey = 5;
+  string SecretKey = 6;
+  string RegistryType = 7;
+  string RepoName = 8;
+  bool IsPublic = 9;
+}
+
+message OCIRegistryResponse {
+  bool IsLoggedIn = 1;
 }
\ No newline at end of file
diff --git a/api/helm-app/applist_grpc.pb.go b/api/helm-app/applist_grpc.pb.go
index f3bdb0f28..4cc1bfa04 100644
--- a/api/helm-app/applist_grpc.pb.go
+++ b/api/helm-app/applist_grpc.pb.go
@@ -1,6 +1,6 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
-// - protoc-gen-go-grpc v1.3.0
+// - protoc-gen-go-grpc v1.2.0
 // - protoc             v3.9.1
 // source: api/helm-app/applist.proto
 
@@ -18,28 +18,6 @@ import (
 // Requires gRPC-Go v1.32.0 or later.
 const _ = grpc.SupportPackageIsVersion7
 
-const (
-	ApplicationService_ListApplications_FullMethodName              = "/ApplicationService/ListApplications"
-	ApplicationService_GetAppDetail_FullMethodName                  = "/ApplicationService/GetAppDetail"
-	ApplicationService_GetAppStatus_FullMethodName                  = "/ApplicationService/GetAppStatus"
-	ApplicationService_Hibernate_FullMethodName                     = "/ApplicationService/Hibernate"
-	ApplicationService_UnHibernate_FullMethodName                   = "/ApplicationService/UnHibernate"
-	ApplicationService_GetDeploymentHistory_FullMethodName          = "/ApplicationService/GetDeploymentHistory"
-	ApplicationService_GetValuesYaml_FullMethodName                 = "/ApplicationService/GetValuesYaml"
-	ApplicationService_GetDesiredManifest_FullMethodName            = "/ApplicationService/GetDesiredManifest"
-	ApplicationService_UninstallRelease_FullMethodName              = "/ApplicationService/UninstallRelease"
-	ApplicationService_UpgradeRelease_FullMethodName                = "/ApplicationService/UpgradeRelease"
-	ApplicationService_GetDeploymentDetail_FullMethodName           = "/ApplicationService/GetDeploymentDetail"
-	ApplicationService_InstallRelease_FullMethodName                = "/ApplicationService/InstallRelease"
-	ApplicationService_UpgradeReleaseWithChartInfo_FullMethodName   = "/ApplicationService/UpgradeReleaseWithChartInfo"
-	ApplicationService_IsReleaseInstalled_FullMethodName            = "/ApplicationService/IsReleaseInstalled"
-	ApplicationService_RollbackRelease_FullMethodName               = "/ApplicationService/RollbackRelease"
-	ApplicationService_TemplateChart_FullMethodName                 = "/ApplicationService/TemplateChart"
-	ApplicationService_InstallReleaseWithCustomChart_FullMethodName = "/ApplicationService/InstallReleaseWithCustomChart"
-	ApplicationService_GetNotes_FullMethodName                      = "/ApplicationService/GetNotes"
-	ApplicationService_UpgradeReleaseWithCustomChart_FullMethodName = "/ApplicationService/UpgradeReleaseWithCustomChart"
-)
-
 // ApplicationServiceClient is the client API for ApplicationService service.
 //
 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
@@ -63,6 +41,7 @@ type ApplicationServiceClient interface {
 	InstallReleaseWithCustomChart(ctx context.Context, in *HelmInstallCustomRequest, opts ...grpc.CallOption) (*HelmInstallCustomResponse, error)
 	GetNotes(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*ChartNotesResponse, error)
 	UpgradeReleaseWithCustomChart(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error)
+	ValidateOCIRegistry(ctx context.Context, in *RegistryCredential, opts ...grpc.CallOption) (*OCIRegistryResponse, error)
 }
 
 type applicationServiceClient struct {
@@ -74,7 +53,7 @@ func NewApplicationServiceClient(cc grpc.ClientConnInterface) ApplicationService
 }
 
 func (c *applicationServiceClient) ListApplications(ctx context.Context, in *AppListRequest, opts ...grpc.CallOption) (ApplicationService_ListApplicationsClient, error) {
-	stream, err := c.cc.NewStream(ctx, &ApplicationService_ServiceDesc.Streams[0], ApplicationService_ListApplications_FullMethodName, opts...)
+	stream, err := c.cc.NewStream(ctx, &ApplicationService_ServiceDesc.Streams[0], "/ApplicationService/ListApplications", opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -107,7 +86,7 @@ func (x *applicationServiceListApplicationsClient) Recv() (*DeployedAppList, err
 
 func (c *applicationServiceClient) GetAppDetail(ctx context.Context, in *AppDetailRequest, opts ...grpc.CallOption) (*AppDetail, error) {
 	out := new(AppDetail)
-	err := c.cc.Invoke(ctx, ApplicationService_GetAppDetail_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/GetAppDetail", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -116,7 +95,7 @@ func (c *applicationServiceClient) GetAppDetail(ctx context.Context, in *AppDeta
 
 func (c *applicationServiceClient) GetAppStatus(ctx context.Context, in *AppDetailRequest, opts ...grpc.CallOption) (*AppStatus, error) {
 	out := new(AppStatus)
-	err := c.cc.Invoke(ctx, ApplicationService_GetAppStatus_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/GetAppStatus", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -125,7 +104,7 @@ func (c *applicationServiceClient) GetAppStatus(ctx context.Context, in *AppDeta
 
 func (c *applicationServiceClient) Hibernate(ctx context.Context, in *HibernateRequest, opts ...grpc.CallOption) (*HibernateResponse, error) {
 	out := new(HibernateResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_Hibernate_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/Hibernate", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -134,7 +113,7 @@ func (c *applicationServiceClient) Hibernate(ctx context.Context, in *HibernateR
 
 func (c *applicationServiceClient) UnHibernate(ctx context.Context, in *HibernateRequest, opts ...grpc.CallOption) (*HibernateResponse, error) {
 	out := new(HibernateResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_UnHibernate_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/UnHibernate", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -143,7 +122,7 @@ func (c *applicationServiceClient) UnHibernate(ctx context.Context, in *Hibernat
 
 func (c *applicationServiceClient) GetDeploymentHistory(ctx context.Context, in *AppDetailRequest, opts ...grpc.CallOption) (*HelmAppDeploymentHistory, error) {
 	out := new(HelmAppDeploymentHistory)
-	err := c.cc.Invoke(ctx, ApplicationService_GetDeploymentHistory_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/GetDeploymentHistory", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -152,7 +131,7 @@ func (c *applicationServiceClient) GetDeploymentHistory(ctx context.Context, in
 
 func (c *applicationServiceClient) GetValuesYaml(ctx context.Context, in *AppDetailRequest, opts ...grpc.CallOption) (*ReleaseInfo, error) {
 	out := new(ReleaseInfo)
-	err := c.cc.Invoke(ctx, ApplicationService_GetValuesYaml_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/GetValuesYaml", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -161,7 +140,7 @@ func (c *applicationServiceClient) GetValuesYaml(ctx context.Context, in *AppDet
 
 func (c *applicationServiceClient) GetDesiredManifest(ctx context.Context, in *ObjectRequest, opts ...grpc.CallOption) (*DesiredManifestResponse, error) {
 	out := new(DesiredManifestResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_GetDesiredManifest_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/GetDesiredManifest", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -170,7 +149,7 @@ func (c *applicationServiceClient) GetDesiredManifest(ctx context.Context, in *O
 
 func (c *applicationServiceClient) UninstallRelease(ctx context.Context, in *ReleaseIdentifier, opts ...grpc.CallOption) (*UninstallReleaseResponse, error) {
 	out := new(UninstallReleaseResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_UninstallRelease_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/UninstallRelease", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -179,7 +158,7 @@ func (c *applicationServiceClient) UninstallRelease(ctx context.Context, in *Rel
 
 func (c *applicationServiceClient) UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) {
 	out := new(UpgradeReleaseResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_UpgradeRelease_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/UpgradeRelease", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -188,7 +167,7 @@ func (c *applicationServiceClient) UpgradeRelease(ctx context.Context, in *Upgra
 
 func (c *applicationServiceClient) GetDeploymentDetail(ctx context.Context, in *DeploymentDetailRequest, opts ...grpc.CallOption) (*DeploymentDetailResponse, error) {
 	out := new(DeploymentDetailResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_GetDeploymentDetail_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/GetDeploymentDetail", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -197,7 +176,7 @@ func (c *applicationServiceClient) GetDeploymentDetail(ctx context.Context, in *
 
 func (c *applicationServiceClient) InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error) {
 	out := new(InstallReleaseResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_InstallRelease_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/InstallRelease", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -206,7 +185,7 @@ func (c *applicationServiceClient) InstallRelease(ctx context.Context, in *Insta
 
 func (c *applicationServiceClient) UpgradeReleaseWithChartInfo(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) {
 	out := new(UpgradeReleaseResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_UpgradeReleaseWithChartInfo_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/UpgradeReleaseWithChartInfo", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -215,7 +194,7 @@ func (c *applicationServiceClient) UpgradeReleaseWithChartInfo(ctx context.Conte
 
 func (c *applicationServiceClient) IsReleaseInstalled(ctx context.Context, in *ReleaseIdentifier, opts ...grpc.CallOption) (*BooleanResponse, error) {
 	out := new(BooleanResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_IsReleaseInstalled_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/IsReleaseInstalled", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -224,7 +203,7 @@ func (c *applicationServiceClient) IsReleaseInstalled(ctx context.Context, in *R
 
 func (c *applicationServiceClient) RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*BooleanResponse, error) {
 	out := new(BooleanResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_RollbackRelease_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/RollbackRelease", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -233,7 +212,7 @@ func (c *applicationServiceClient) RollbackRelease(ctx context.Context, in *Roll
 
 func (c *applicationServiceClient) TemplateChart(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*TemplateChartResponse, error) {
 	out := new(TemplateChartResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_TemplateChart_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/TemplateChart", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -242,7 +221,7 @@ func (c *applicationServiceClient) TemplateChart(ctx context.Context, in *Instal
 
 func (c *applicationServiceClient) InstallReleaseWithCustomChart(ctx context.Context, in *HelmInstallCustomRequest, opts ...grpc.CallOption) (*HelmInstallCustomResponse, error) {
 	out := new(HelmInstallCustomResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_InstallReleaseWithCustomChart_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/InstallReleaseWithCustomChart", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -251,7 +230,7 @@ func (c *applicationServiceClient) InstallReleaseWithCustomChart(ctx context.Con
 
 func (c *applicationServiceClient) GetNotes(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*ChartNotesResponse, error) {
 	out := new(ChartNotesResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_GetNotes_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/GetNotes", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -260,7 +239,16 @@ func (c *applicationServiceClient) GetNotes(ctx context.Context, in *InstallRele
 
 func (c *applicationServiceClient) UpgradeReleaseWithCustomChart(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) {
 	out := new(UpgradeReleaseResponse)
-	err := c.cc.Invoke(ctx, ApplicationService_UpgradeReleaseWithCustomChart_FullMethodName, in, out, opts...)
+	err := c.cc.Invoke(ctx, "/ApplicationService/UpgradeReleaseWithCustomChart", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *applicationServiceClient) ValidateOCIRegistry(ctx context.Context, in *RegistryCredential, opts ...grpc.CallOption) (*OCIRegistryResponse, error) {
+	out := new(OCIRegistryResponse)
+	err := c.cc.Invoke(ctx, "/ApplicationService/ValidateOCIRegistry", in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -290,6 +278,7 @@ type ApplicationServiceServer interface {
 	InstallReleaseWithCustomChart(context.Context, *HelmInstallCustomRequest) (*HelmInstallCustomResponse, error)
 	GetNotes(context.Context, *InstallReleaseRequest) (*ChartNotesResponse, error)
 	UpgradeReleaseWithCustomChart(context.Context, *UpgradeReleaseRequest) (*UpgradeReleaseResponse, error)
+	ValidateOCIRegistry(context.Context, *RegistryCredential) (*OCIRegistryResponse, error)
 	mustEmbedUnimplementedApplicationServiceServer()
 }
 
@@ -354,6 +343,9 @@ func (UnimplementedApplicationServiceServer) GetNotes(context.Context, *InstallR
 func (UnimplementedApplicationServiceServer) UpgradeReleaseWithCustomChart(context.Context, *UpgradeReleaseRequest) (*UpgradeReleaseResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method UpgradeReleaseWithCustomChart not implemented")
 }
+func (UnimplementedApplicationServiceServer) ValidateOCIRegistry(context.Context, *RegistryCredential) (*OCIRegistryResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ValidateOCIRegistry not implemented")
+}
 func (UnimplementedApplicationServiceServer) mustEmbedUnimplementedApplicationServiceServer() {}
 
 // UnsafeApplicationServiceServer may be embedded to opt out of forward compatibility for this service.
@@ -398,7 +390,7 @@ func _ApplicationService_GetAppDetail_Handler(srv interface{}, ctx context.Conte
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_GetAppDetail_FullMethodName,
+		FullMethod: "/ApplicationService/GetAppDetail",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).GetAppDetail(ctx, req.(*AppDetailRequest))
@@ -416,7 +408,7 @@ func _ApplicationService_GetAppStatus_Handler(srv interface{}, ctx context.Conte
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_GetAppStatus_FullMethodName,
+		FullMethod: "/ApplicationService/GetAppStatus",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).GetAppStatus(ctx, req.(*AppDetailRequest))
@@ -434,7 +426,7 @@ func _ApplicationService_Hibernate_Handler(srv interface{}, ctx context.Context,
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_Hibernate_FullMethodName,
+		FullMethod: "/ApplicationService/Hibernate",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).Hibernate(ctx, req.(*HibernateRequest))
@@ -452,7 +444,7 @@ func _ApplicationService_UnHibernate_Handler(srv interface{}, ctx context.Contex
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_UnHibernate_FullMethodName,
+		FullMethod: "/ApplicationService/UnHibernate",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).UnHibernate(ctx, req.(*HibernateRequest))
@@ -470,7 +462,7 @@ func _ApplicationService_GetDeploymentHistory_Handler(srv interface{}, ctx conte
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_GetDeploymentHistory_FullMethodName,
+		FullMethod: "/ApplicationService/GetDeploymentHistory",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).GetDeploymentHistory(ctx, req.(*AppDetailRequest))
@@ -488,7 +480,7 @@ func _ApplicationService_GetValuesYaml_Handler(srv interface{}, ctx context.Cont
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_GetValuesYaml_FullMethodName,
+		FullMethod: "/ApplicationService/GetValuesYaml",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).GetValuesYaml(ctx, req.(*AppDetailRequest))
@@ -506,7 +498,7 @@ func _ApplicationService_GetDesiredManifest_Handler(srv interface{}, ctx context
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_GetDesiredManifest_FullMethodName,
+		FullMethod: "/ApplicationService/GetDesiredManifest",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).GetDesiredManifest(ctx, req.(*ObjectRequest))
@@ -524,7 +516,7 @@ func _ApplicationService_UninstallRelease_Handler(srv interface{}, ctx context.C
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_UninstallRelease_FullMethodName,
+		FullMethod: "/ApplicationService/UninstallRelease",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).UninstallRelease(ctx, req.(*ReleaseIdentifier))
@@ -542,7 +534,7 @@ func _ApplicationService_UpgradeRelease_Handler(srv interface{}, ctx context.Con
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_UpgradeRelease_FullMethodName,
+		FullMethod: "/ApplicationService/UpgradeRelease",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).UpgradeRelease(ctx, req.(*UpgradeReleaseRequest))
@@ -560,7 +552,7 @@ func _ApplicationService_GetDeploymentDetail_Handler(srv interface{}, ctx contex
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_GetDeploymentDetail_FullMethodName,
+		FullMethod: "/ApplicationService/GetDeploymentDetail",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).GetDeploymentDetail(ctx, req.(*DeploymentDetailRequest))
@@ -578,7 +570,7 @@ func _ApplicationService_InstallRelease_Handler(srv interface{}, ctx context.Con
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_InstallRelease_FullMethodName,
+		FullMethod: "/ApplicationService/InstallRelease",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).InstallRelease(ctx, req.(*InstallReleaseRequest))
@@ -596,7 +588,7 @@ func _ApplicationService_UpgradeReleaseWithChartInfo_Handler(srv interface{}, ct
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_UpgradeReleaseWithChartInfo_FullMethodName,
+		FullMethod: "/ApplicationService/UpgradeReleaseWithChartInfo",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).UpgradeReleaseWithChartInfo(ctx, req.(*InstallReleaseRequest))
@@ -614,7 +606,7 @@ func _ApplicationService_IsReleaseInstalled_Handler(srv interface{}, ctx context
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_IsReleaseInstalled_FullMethodName,
+		FullMethod: "/ApplicationService/IsReleaseInstalled",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).IsReleaseInstalled(ctx, req.(*ReleaseIdentifier))
@@ -632,7 +624,7 @@ func _ApplicationService_RollbackRelease_Handler(srv interface{}, ctx context.Co
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_RollbackRelease_FullMethodName,
+		FullMethod: "/ApplicationService/RollbackRelease",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).RollbackRelease(ctx, req.(*RollbackReleaseRequest))
@@ -650,7 +642,7 @@ func _ApplicationService_TemplateChart_Handler(srv interface{}, ctx context.Cont
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_TemplateChart_FullMethodName,
+		FullMethod: "/ApplicationService/TemplateChart",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).TemplateChart(ctx, req.(*InstallReleaseRequest))
@@ -668,7 +660,7 @@ func _ApplicationService_InstallReleaseWithCustomChart_Handler(srv interface{},
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_InstallReleaseWithCustomChart_FullMethodName,
+		FullMethod: "/ApplicationService/InstallReleaseWithCustomChart",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).InstallReleaseWithCustomChart(ctx, req.(*HelmInstallCustomRequest))
@@ -686,7 +678,7 @@ func _ApplicationService_GetNotes_Handler(srv interface{}, ctx context.Context,
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_GetNotes_FullMethodName,
+		FullMethod: "/ApplicationService/GetNotes",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).GetNotes(ctx, req.(*InstallReleaseRequest))
@@ -704,7 +696,7 @@ func _ApplicationService_UpgradeReleaseWithCustomChart_Handler(srv interface{},
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: ApplicationService_UpgradeReleaseWithCustomChart_FullMethodName,
+		FullMethod: "/ApplicationService/UpgradeReleaseWithCustomChart",
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 		return srv.(ApplicationServiceServer).UpgradeReleaseWithCustomChart(ctx, req.(*UpgradeReleaseRequest))
@@ -712,6 +704,24 @@ func _ApplicationService_UpgradeReleaseWithCustomChart_Handler(srv interface{},
 	return interceptor(ctx, in, info, handler)
 }
 
+func _ApplicationService_ValidateOCIRegistry_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(RegistryCredential)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ApplicationServiceServer).ValidateOCIRegistry(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/ApplicationService/ValidateOCIRegistry",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ApplicationServiceServer).ValidateOCIRegistry(ctx, req.(*RegistryCredential))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // ApplicationService_ServiceDesc is the grpc.ServiceDesc for ApplicationService service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -791,6 +801,10 @@ var ApplicationService_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "UpgradeReleaseWithCustomChart",
 			Handler:    _ApplicationService_UpgradeReleaseWithCustomChart_Handler,
 		},
+		{
+			MethodName: "ValidateOCIRegistry",
+			Handler:    _ApplicationService_ValidateOCIRegistry_Handler,
+		},
 	},
 	Streams: []grpc.StreamDesc{
 		{
diff --git a/api/restHandler/DockerRegRestHandler.go b/api/restHandler/DockerRegRestHandler.go
index ed4cbf506..4e19acb64 100644
--- a/api/restHandler/DockerRegRestHandler.go
+++ b/api/restHandler/DockerRegRestHandler.go
@@ -22,6 +22,8 @@ import (
 	"fmt"
 	"github.com/devtron-labs/devtron/api/restHandler/common"
 	repository "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry"
+	"github.com/devtron-labs/devtron/internal/util"
+	chartProviderService "github.com/devtron-labs/devtron/pkg/appStore/chartProvider"
 	delete2 "github.com/devtron-labs/devtron/pkg/delete"
 	"github.com/devtron-labs/devtron/pkg/user/casbin"
 	"k8s.io/utils/strings/slices"
@@ -52,6 +54,7 @@ type DockerRegRestHandler interface {
 type DockerRegRestHandlerImpl struct {
 	dockerRegistryConfig  pipeline.DockerRegistryConfig
 	logger                *zap.SugaredLogger
+	chartProviderService  chartProviderService.ChartProviderService
 	gitRegistryConfig     pipeline.GitRegistryConfig
 	dbConfigService       pipeline.DbConfigService
 	userAuthService       user.UserService
@@ -65,6 +68,7 @@ const secureWithCert = "secure-with-cert"
 
 func NewDockerRegRestHandlerImpl(dockerRegistryConfig pipeline.DockerRegistryConfig,
 	logger *zap.SugaredLogger,
+	chartProviderService chartProviderService.ChartProviderService,
 	gitRegistryConfig pipeline.GitRegistryConfig,
 	dbConfigService pipeline.DbConfigService, userAuthService user.UserService,
 	validator *validator.Validate, enforcer casbin.Enforcer, teamService team.TeamService,
@@ -72,6 +76,7 @@ func NewDockerRegRestHandlerImpl(dockerRegistryConfig pipeline.DockerRegistryCon
 	return &DockerRegRestHandlerImpl{
 		dockerRegistryConfig:  dockerRegistryConfig,
 		logger:                logger,
+		chartProviderService:  chartProviderService,
 		gitRegistryConfig:     gitRegistryConfig,
 		dbConfigService:       dbConfigService,
 		userAuthService:       userAuthService,
@@ -101,7 +106,7 @@ func ValidateDockerArtifactStoreRequestBean(bean pipeline.DockerArtifactStoreBea
 		// For Charts with storage action type "PULL/PUSH" or "PULL", RepositoryList cannot be nil
 		chartStorageActionType, chartStorageActionExists := bean.OCIRegistryConfig[repository.OCI_REGISRTY_REPO_TYPE_CHART]
 		if chartStorageActionExists && (chartStorageActionType == repository.STORAGE_ACTION_TYPE_PULL_AND_PUSH || chartStorageActionType == repository.STORAGE_ACTION_TYPE_PULL) {
-			if bean.RepositoryList == nil {
+			if bean.RepositoryList == nil || len(bean.RepositoryList) == 0 || slices.Contains(bean.RepositoryList, "") {
 				return false
 			}
 		}
@@ -147,6 +152,16 @@ func (impl DockerRegRestHandlerImpl) SaveDockerRegistryConfig(w http.ResponseWri
 			return
 		}
 		//RBAC enforcer Ends
+		if isValid := impl.dockerRegistryConfig.ValidateRegistryCredentials(&bean); !isValid {
+			impl.logger.Errorw("registry credentials validation err, SaveDockerRegistryConfig", "err", err, "payload", bean)
+			err = &util.ApiError{
+				HttpStatusCode:  http.StatusBadRequest,
+				InternalMessage: "Invalid authentication credentials. Please verify.",
+				UserMessage:     "Invalid authentication credentials. Please verify.",
+			}
+			common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
+			return
+		}
 		exist, err := impl.dockerRegistryConfig.CheckInActiveDockerAccount(bean.Id)
 
 		if err != nil {
@@ -165,6 +180,19 @@ func (impl DockerRegRestHandlerImpl) SaveDockerRegistryConfig(w http.ResponseWri
 			common.WriteJsonResp(w, err, res, http.StatusOK)
 			return
 		}
+		// valid registry credentials from kubelink
+		if bean.IsOCICompliantRegistry && len(bean.RepositoryList) != 0 {
+			request := &chartProviderService.ChartProviderRequestDto{
+				Id:            bean.Id,
+				IsOCIRegistry: bean.IsOCICompliantRegistry,
+			}
+			err = impl.chartProviderService.SyncChartProvider(request)
+			if err != nil {
+				impl.logger.Errorw("service err, SaveDockerRegistryConfig", "err", err, "userId", userId)
+				common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
+				return
+			}
+		}
 
 		res, err := impl.dockerRegistryConfig.Create(&bean)
 		if err != nil {
@@ -172,7 +200,6 @@ func (impl DockerRegRestHandlerImpl) SaveDockerRegistryConfig(w http.ResponseWri
 			common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
 			return
 		}
-
 		common.WriteJsonResp(w, err, res, http.StatusOK)
 	}
 
@@ -261,34 +288,42 @@ func (impl DockerRegRestHandlerImpl) UpdateDockerRegistryConfig(w http.ResponseW
 		impl.logger.Errorw("validation err, SaveDockerRegistryConfig", "err", err, "payload", bean)
 		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
 		return
-	} else {
-		impl.logger.Infow("request payload, UpdateDockerRegistryConfig", "err", err, "payload", bean)
+	}
+	impl.logger.Infow("request payload, UpdateDockerRegistryConfig", "err", err, "payload", bean)
 
-		err = impl.validator.Struct(bean)
-		if err != nil {
-			impl.logger.Errorw("validation err, UpdateDockerRegistryConfig", "err", err, "payload", bean)
-			common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
-			return
-		}
+	err = impl.validator.Struct(bean)
+	if err != nil {
+		impl.logger.Errorw("validation err, UpdateDockerRegistryConfig", "err", err, "payload", bean)
+		common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
+		return
+	}
 
-		// RBAC enforcer applying
-		token := r.Header.Get("token")
-		if ok := impl.enforcer.Enforce(token, casbin.ResourceDocker, casbin.ActionUpdate, strings.ToLower(bean.Id)); !ok {
-			common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
-			return
+	// RBAC enforcer applying
+	token := r.Header.Get("token")
+	if ok := impl.enforcer.Enforce(token, casbin.ResourceDocker, casbin.ActionUpdate, strings.ToLower(bean.Id)); !ok {
+		common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
+		return
+	}
+	//RBAC enforcer Ends
+	res, err := impl.dockerRegistryConfig.Update(&bean)
+	if err != nil {
+		impl.logger.Errorw("service err, UpdateDockerRegistryConfig", "err", err, "payload", bean)
+		common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
+		return
+	}
+	if res.IsOCICompliantRegistry && len(res.RepositoryList) != 0 {
+		request := &chartProviderService.ChartProviderRequestDto{
+			Id:            res.Id,
+			IsOCIRegistry: res.IsOCICompliantRegistry,
 		}
-		//RBAC enforcer Ends
-
-		res, err := impl.dockerRegistryConfig.Update(&bean)
+		err = impl.chartProviderService.SyncChartProvider(request)
 		if err != nil {
-			impl.logger.Errorw("service err, UpdateDockerRegistryConfig", "err", err, "payload", bean)
+			impl.logger.Errorw("service err, SaveDockerRegistryConfig", "err", err, "userId", userId)
 			common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
 			return
 		}
-
-		common.WriteJsonResp(w, err, res, http.StatusOK)
 	}
-
+	common.WriteJsonResp(w, err, res, http.StatusOK)
 }
 
 func (impl DockerRegRestHandlerImpl) FetchAllDockerRegistryForAutocomplete(w http.ResponseWriter, r *http.Request) {
diff --git a/cmd/external-app/router.go b/cmd/external-app/router.go
index f2b8bf6cb..dd40a99f6 100644
--- a/cmd/external-app/router.go
+++ b/cmd/external-app/router.go
@@ -3,6 +3,7 @@ package main
 import (
 	"encoding/json"
 	"github.com/devtron-labs/devtron/api/apiToken"
+	chartProvider "github.com/devtron-labs/devtron/api/appStore/ChartProvider"
 	appStoreDeployment "github.com/devtron-labs/devtron/api/appStore/deployment"
 	appStoreDiscover "github.com/devtron-labs/devtron/api/appStore/discover"
 	appStoreValues "github.com/devtron-labs/devtron/api/appStore/values"
@@ -45,6 +46,7 @@ type MuxRouter struct {
 	appStoreDiscoverRouter   appStoreDiscover.AppStoreDiscoverRouter
 	appStoreValuesRouter     appStoreValues.AppStoreValuesRouter
 	appStoreDeploymentRouter appStoreDeployment.AppStoreDeploymentRouter
+	chartProviderRouter      chartProvider.ChartProviderRouter
 	dashboardTelemetryRouter dashboardEvent.DashboardTelemetryRouter
 	commonDeploymentRouter   appStoreDeployment.CommonDeploymentRouter
 	externalLinksRouter      externalLink.ExternalLinkRouter
@@ -76,6 +78,7 @@ func NewMuxRouter(
 	appStoreDiscoverRouter appStoreDiscover.AppStoreDiscoverRouter,
 	appStoreValuesRouter appStoreValues.AppStoreValuesRouter,
 	appStoreDeploymentRouter appStoreDeployment.AppStoreDeploymentRouter,
+	chartProviderRouter chartProvider.ChartProviderRouter,
 	dashboardTelemetryRouter dashboardEvent.DashboardTelemetryRouter,
 	commonDeploymentRouter appStoreDeployment.CommonDeploymentRouter,
 	externalLinkRouter externalLink.ExternalLinkRouter,
@@ -106,6 +109,7 @@ func NewMuxRouter(
 		appStoreDiscoverRouter:   appStoreDiscoverRouter,
 		appStoreValuesRouter:     appStoreValuesRouter,
 		appStoreDeploymentRouter: appStoreDeploymentRouter,
+		chartProviderRouter:      chartProviderRouter,
 		dashboardTelemetryRouter: dashboardTelemetryRouter,
 		commonDeploymentRouter:   commonDeploymentRouter,
 		externalLinksRouter:      externalLinkRouter,
@@ -208,6 +212,11 @@ func (r *MuxRouter) Init() {
 	r.appStoreDeploymentRouter.Init(appStoreDeploymentSubRouter)
 	// app-store deployment router ends
 
+	// chart provider router starts
+	chartProviderSubRouter := r.Router.PathPrefix("/orchestrator/app-store/chart-provider").Subrouter()
+	r.chartProviderRouter.Init(chartProviderSubRouter)
+	// chart provider router ends
+
 	//  dashboard event router starts
 	dashboardTelemetryRouter := r.Router.PathPrefix("/orchestrator/dashboard-event").Subrouter()
 	r.dashboardTelemetryRouter.Init(dashboardTelemetryRouter)
diff --git a/cmd/external-app/wire.go b/cmd/external-app/wire.go
index 0b934358c..ada5b93ac 100644
--- a/cmd/external-app/wire.go
+++ b/cmd/external-app/wire.go
@@ -6,6 +6,7 @@ package main
 import (
 	"github.com/devtron-labs/authenticator/middleware"
 	"github.com/devtron-labs/devtron/api/apiToken"
+	chartProvider "github.com/devtron-labs/devtron/api/appStore/ChartProvider"
 	appStoreDeployment "github.com/devtron-labs/devtron/api/appStore/deployment"
 	appStoreDiscover "github.com/devtron-labs/devtron/api/appStore/discover"
 	appStoreValues "github.com/devtron-labs/devtron/api/appStore/values"
@@ -69,6 +70,7 @@ func InitializeApp() (*App, error) {
 		k8s.K8sApplicationWireSet,
 		chartRepo.ChartRepositoryWireSet,
 		appStoreDiscover.AppStoreDiscoverWireSet,
+		chartProvider.AppStoreChartProviderWireSet,
 		appStoreValues.AppStoreValuesWireSet,
 		appStoreDeployment.AppStoreDeploymentWireSet,
 		server.ServerWireSet,
diff --git a/cmd/external-app/wire_gen.go b/cmd/external-app/wire_gen.go
index 5fe7a6803..c3f5af4ac 100644
--- a/cmd/external-app/wire_gen.go
+++ b/cmd/external-app/wire_gen.go
@@ -11,6 +11,7 @@ import (
 	"github.com/devtron-labs/authenticator/client"
 	"github.com/devtron-labs/authenticator/middleware"
 	apiToken2 "github.com/devtron-labs/devtron/api/apiToken"
+	chartProvider2 "github.com/devtron-labs/devtron/api/appStore/ChartProvider"
 	"github.com/devtron-labs/devtron/api/appStore/deployment"
 	"github.com/devtron-labs/devtron/api/appStore/discover"
 	"github.com/devtron-labs/devtron/api/appStore/values"
@@ -42,6 +43,7 @@ import (
 	"github.com/devtron-labs/devtron/pkg/apiToken"
 	app2 "github.com/devtron-labs/devtron/pkg/app"
 	"github.com/devtron-labs/devtron/pkg/appStore/bean"
+	"github.com/devtron-labs/devtron/pkg/appStore/chartProvider"
 	"github.com/devtron-labs/devtron/pkg/appStore/deployment/common"
 	repository4 "github.com/devtron-labs/devtron/pkg/appStore/deployment/repository"
 	service3 "github.com/devtron-labs/devtron/pkg/appStore/deployment/service"
@@ -274,6 +276,9 @@ func InitializeApp() (*App, error) {
 	appStoreDeploymentServiceImpl := service3.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, appStoreApplicationVersionRepositoryImpl, environmentRepositoryImpl, clusterInstalledAppsRepositoryImpl, appRepositoryImpl, appStoreDeploymentHelmServiceImpl, appStoreDeploymentHelmServiceImpl, environmentServiceImpl, clusterServiceImpl, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, globalEnvVariables, installedAppVersionHistoryRepositoryImpl, gitOpsConfigRepositoryImpl, attributesServiceImpl, deploymentServiceTypeConfig, chartTemplateServiceImpl)
 	appStoreDeploymentRestHandlerImpl := appStoreDeployment.NewAppStoreDeploymentRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, enforcerUtilImpl, enforcerUtilHelmImpl, appStoreDeploymentServiceImpl, validate, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, helmUserServiceImpl, attributesServiceImpl)
 	appStoreDeploymentRouterImpl := appStoreDeployment.NewAppStoreDeploymentRouterImpl(appStoreDeploymentRestHandlerImpl)
+	chartProviderServiceImpl := chartProvider.NewChartProviderServiceImpl(sugaredLogger, chartRepoRepositoryImpl, chartRepositoryServiceImpl)
+	chartProviderRestHandlerImpl := chartProvider2.NewChartProviderRestHandlerImpl(sugaredLogger, userServiceImpl, validate, chartProviderServiceImpl, enforcerImpl)
+	chartProviderRouterImpl := chartProvider2.NewChartProviderRouterImpl(chartProviderRestHandlerImpl)
 	posthogClient, err := telemetry.NewPosthogClient(sugaredLogger)
 	if err != nil {
 		return nil, err
@@ -355,7 +360,7 @@ func InitializeApp() (*App, error) {
 	rbacRoleServiceImpl := user.NewRbacRoleServiceImpl(sugaredLogger, rbacRoleDataRepositoryImpl)
 	rbacRoleRestHandlerImpl := user2.NewRbacRoleHandlerImpl(sugaredLogger, validate, rbacRoleServiceImpl, userServiceImpl, enforcerImpl, enforcerUtilImpl)
 	rbacRoleRouterImpl := user2.NewRbacRoleRouterImpl(sugaredLogger, validate, rbacRoleRestHandlerImpl)
-	muxRouter := NewMuxRouter(sugaredLogger, ssoLoginRouterImpl, teamRouterImpl, userAuthRouterImpl, userRouterImpl, clusterRouterImpl, dashboardRouterImpl, helmAppRouterImpl, environmentRouterImpl, k8sApplicationRouterImpl, chartRepositoryRouterImpl, appStoreDiscoverRouterImpl, appStoreValuesRouterImpl, appStoreDeploymentRouterImpl, dashboardTelemetryRouterImpl, commonDeploymentRouterImpl, externalLinkRouterImpl, moduleRouterImpl, serverRouterImpl, apiTokenRouterImpl, k8sCapacityRouterImpl, webhookHelmRouterImpl, userAttributesRouterImpl, telemetryRouterImpl, userTerminalAccessRouterImpl, attributesRouterImpl, appRouterImpl, rbacRoleRouterImpl)
+	muxRouter := NewMuxRouter(sugaredLogger, ssoLoginRouterImpl, teamRouterImpl, userAuthRouterImpl, userRouterImpl, clusterRouterImpl, dashboardRouterImpl, helmAppRouterImpl, environmentRouterImpl, k8sApplicationRouterImpl, chartRepositoryRouterImpl, appStoreDiscoverRouterImpl, appStoreValuesRouterImpl, appStoreDeploymentRouterImpl, chartProviderRouterImpl, dashboardTelemetryRouterImpl, commonDeploymentRouterImpl, externalLinkRouterImpl, moduleRouterImpl, serverRouterImpl, apiTokenRouterImpl, k8sCapacityRouterImpl, webhookHelmRouterImpl, userAttributesRouterImpl, telemetryRouterImpl, userTerminalAccessRouterImpl, attributesRouterImpl, appRouterImpl, rbacRoleRouterImpl)
 	mainApp := NewApp(db, sessionManager, muxRouter, telemetryEventClientImpl, posthogClient, sugaredLogger)
 	return mainApp, nil
 }
diff --git a/internal/sql/repository/dockerRegistry/DockerArtifactStoreRepository.go b/internal/sql/repository/dockerRegistry/DockerArtifactStoreRepository.go
index 6b3a8592a..7bcc47808 100644
--- a/internal/sql/repository/dockerRegistry/DockerArtifactStoreRepository.go
+++ b/internal/sql/repository/dockerRegistry/DockerArtifactStoreRepository.go
@@ -80,6 +80,7 @@ type DockerArtifactStoreRepository interface {
 	FindActiveDefaultStore() (*DockerArtifactStore, error)
 	FindAllActiveForAutocomplete() ([]DockerArtifactStore, error)
 	FindAll() ([]DockerArtifactStore, error)
+	FindAllChartProviders() ([]DockerArtifactStore, error)
 	FindOne(storeId string) (*DockerArtifactStore, error)
 	FindOneInactive(storeId string) (*DockerArtifactStore, error)
 	Update(artifactStore *DockerArtifactStore, tx *pg.Tx) error
@@ -148,6 +149,20 @@ func (impl DockerArtifactStoreRepositoryImpl) FindAll() ([]DockerArtifactStore,
 	return providers, err
 }
 
+func (impl DockerArtifactStoreRepositoryImpl) FindAllChartProviders() ([]DockerArtifactStore, error) {
+	var providers []DockerArtifactStore
+	err := impl.dbConnection.Model(&providers).
+		Column("docker_artifact_store.*", "IpsConfig", "OCIRegistryConfig").
+		Where("active = ?", true).
+		Relation("OCIRegistryConfig", func(q *orm.Query) (query *orm.Query, err error) {
+			return q.Where("deleted IS FALSE and " +
+				"repository_type='CHART' and " +
+				"(repository_action='PULL' or repository_action='PULL/PUSH')"), nil
+		}).
+		Select()
+	return providers, err
+}
+
 func (impl DockerArtifactStoreRepositoryImpl) FindOne(storeId string) (*DockerArtifactStore, error) {
 	var provider DockerArtifactStore
 	err := impl.dbConnection.Model(&provider).
diff --git a/internal/sql/repository/dockerRegistry/OCIRegistryConfigRepository.go b/internal/sql/repository/dockerRegistry/OCIRegistryConfigRepository.go
index f6d9c947d..c49a6beee 100644
--- a/internal/sql/repository/dockerRegistry/OCIRegistryConfigRepository.go
+++ b/internal/sql/repository/dockerRegistry/OCIRegistryConfigRepository.go
@@ -29,6 +29,7 @@ type OCIRegistryConfig struct {
 	RepositoryType        string   `sql:"repository_type,notnull"`
 	RepositoryAction      string   `sql:"repository_action,notnull"`
 	RepositoryList        string   `sql:"repository_list"`
+	IsChartPullActive     bool     `sql:"is_chart_pull_active"`
 	IsPublic              bool     `sql:"is_public"`
 	Deleted               bool     `sql:"deleted,notnull"`
 	sql.AuditLog
diff --git a/pkg/appStore/bean/bean.go b/pkg/appStore/bean/bean.go
index be1991aa0..2253a8795 100644
--- a/pkg/appStore/bean/bean.go
+++ b/pkg/appStore/bean/bean.go
@@ -296,6 +296,7 @@ type AppStoreWithVersion struct {
 	AppStoreApplicationVersionId int       `json:"appStoreApplicationVersionId"`
 	Name                         string    `json:"name"`
 	ChartRepoId                  int       `json:"chart_repo_id"`
+	DockerArtifactStoreId        string    `json:"docker_artifact_store_id"`
 	ChartName                    string    `json:"chart_name"`
 	Icon                         string    `json:"icon"`
 	Active                       bool      `json:"active"`
@@ -309,6 +310,7 @@ type AppStoreWithVersion struct {
 
 type AppStoreFilter struct {
 	ChartRepoId       []int    `json:"chartRepoId"`
+	RegistryId        []string `json:"registryId"`
 	AppStoreName      string   `json:"appStoreName"`
 	AppName           string   `json:"appName"`
 	IncludeDeprecated bool     `json:"includeDeprecated"`
diff --git a/pkg/appStore/chartProvider/ChartProviderService.go b/pkg/appStore/chartProvider/ChartProviderService.go
new file mode 100644
index 000000000..408125275
--- /dev/null
+++ b/pkg/appStore/chartProvider/ChartProviderService.go
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2020 Devtron Labs
+ *
+ * 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 chartProvider
+
+import (
+	dockerRegistryRepository "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry"
+	"github.com/devtron-labs/devtron/internal/util"
+	"github.com/devtron-labs/devtron/pkg/chartRepo"
+	chartRepoRepository "github.com/devtron-labs/devtron/pkg/chartRepo/repository"
+	"github.com/go-pg/pg"
+	"go.uber.org/zap"
+	"strconv"
+	"time"
+)
+
+type ChartProviderService interface {
+	GetChartProviderList() ([]*ChartProviderResponseDto, error)
+	ToggleChartProvider(request *ChartProviderRequestDto) error
+	SyncChartProvider(request *ChartProviderRequestDto) error
+}
+
+type ChartProviderServiceImpl struct {
+	logger                 *zap.SugaredLogger
+	repoRepository         chartRepoRepository.ChartRepoRepository
+	chartRepositoryService chartRepo.ChartRepositoryService
+}
+
+type ChartProviderServiceExtendedImpl struct {
+	registryRepository          dockerRegistryRepository.DockerArtifactStoreRepository
+	ociRegistryConfigRepository dockerRegistryRepository.OCIRegistryConfigRepository
+	*ChartProviderServiceImpl
+}
+
+func NewChartProviderServiceImpl(logger *zap.SugaredLogger, repoRepository chartRepoRepository.ChartRepoRepository, chartRepositoryService chartRepo.ChartRepositoryService) *ChartProviderServiceImpl {
+	return &ChartProviderServiceImpl{
+		logger:                 logger,
+		repoRepository:         repoRepository,
+		chartRepositoryService: chartRepositoryService,
+	}
+}
+
+func NewChartProviderServiceExtendedImpl(logger *zap.SugaredLogger, repoRepository chartRepoRepository.ChartRepoRepository, chartRepositoryService chartRepo.ChartRepositoryService, registryRepository dockerRegistryRepository.DockerArtifactStoreRepository, ociRegistryConfigRepository dockerRegistryRepository.OCIRegistryConfigRepository) *ChartProviderServiceExtendedImpl {
+	return &ChartProviderServiceExtendedImpl{
+		registryRepository:          registryRepository,
+		ociRegistryConfigRepository: ociRegistryConfigRepository,
+		ChartProviderServiceImpl: &ChartProviderServiceImpl{
+			logger:                 logger,
+			repoRepository:         repoRepository,
+			chartRepositoryService: chartRepositoryService,
+		},
+	}
+}
+func UpdateChartRepoList(models []*chartRepoRepository.ChartRepoWithDeploymentCount, chartProviders []*ChartProviderResponseDto) []*ChartProviderResponseDto {
+	for _, model := range models {
+		chartRepo := &ChartProviderResponseDto{}
+		chartRepo.Id = strconv.Itoa(model.Id)
+		chartRepo.Name = model.Name
+		chartRepo.Active = model.Active
+		chartRepo.IsEditable = true
+		chartRepo.IsOCIRegistry = false
+		if model.ActiveDeploymentCount > 0 {
+			chartRepo.IsEditable = false
+		}
+		chartProviders = append(chartProviders, chartRepo)
+	}
+	return chartProviders
+}
+
+func (impl *ChartProviderServiceImpl) GetChartProviderList() ([]*ChartProviderResponseDto, error) {
+	var chartProviders []*ChartProviderResponseDto
+	models, err := impl.repoRepository.FindAllWithDeploymentCount()
+	if err != nil && !util.IsErrNoRows(err) {
+		return nil, err
+	}
+	return UpdateChartRepoList(models, chartProviders), nil
+}
+
+func (impl *ChartProviderServiceImpl) ToggleChartProvider(request *ChartProviderRequestDto) error {
+	dbConnection := impl.repoRepository.GetConnection()
+	tx, err := dbConnection.Begin()
+	if err != nil {
+		return err
+	}
+	// Rollback tx on error.
+	defer tx.Rollback()
+	chartRepo, err := impl.repoRepository.FindById(request.ChartRepoId)
+	if err != nil {
+		return err
+	}
+	chartRepo.Active = request.Active
+	chartRepo.UpdatedBy = request.UserId
+	chartRepo.UpdatedOn = time.Now()
+	err = impl.repoRepository.Update(chartRepo, tx)
+	if err != nil {
+		return err
+	}
+	err = tx.Commit()
+	if err != nil {
+		impl.logger.Errorw("error in db transaction commit, ToggleChartProvider", "err", err)
+		return err
+	}
+	return nil
+}
+
+func (impl *ChartProviderServiceImpl) SyncChartProvider(request *ChartProviderRequestDto) error {
+	chartProviderConfig := &chartRepo.ChartProviderConfig{
+		ChartProviderId: request.Id,
+		IsOCIRegistry:   false,
+	}
+	err := impl.chartRepositoryService.TriggerChartSyncManual(chartProviderConfig)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (impl *ChartProviderServiceExtendedImpl) GetChartProviderList() ([]*ChartProviderResponseDto, error) {
+	var chartProviders []*ChartProviderResponseDto
+	store, err := impl.registryRepository.FindAllChartProviders()
+	if err != nil && !util.IsErrNoRows(err) {
+		impl.logger.Errorw("error in listing artifact", "err", err)
+		return nil, err
+	}
+	for _, model := range store {
+		//TODO: refactor
+		if model.OCIRegistryConfig == nil ||
+			len(model.OCIRegistryConfig) != 1 ||
+			model.OCIRegistryConfig[0].RepositoryType != dockerRegistryRepository.OCI_REGISRTY_REPO_TYPE_CHART {
+			continue
+		}
+		chartRepo := &ChartProviderResponseDto{}
+		chartRepo.Id = model.Id
+		chartRepo.Name = model.Id
+		chartRepo.IsEditable = true
+		chartRepo.Active = model.OCIRegistryConfig[0].IsChartPullActive
+		chartRepo.IsOCIRegistry = true
+		chartRepo.RegistryProvider = model.RegistryType
+		chartProviders = append(chartProviders, chartRepo)
+	}
+
+	models, err := impl.repoRepository.FindAllWithDeploymentCount()
+	if err != nil && !util.IsErrNoRows(err) {
+		return nil, err
+	}
+	return UpdateChartRepoList(models, chartProviders), nil
+}
+
+func (impl *ChartProviderServiceExtendedImpl) ToggleChartProvider(request *ChartProviderRequestDto) error {
+
+	dbConnection := impl.repoRepository.GetConnection()
+	tx, err := dbConnection.Begin()
+	if err != nil {
+		return err
+	}
+	// Rollback tx on error.
+	defer tx.Rollback()
+	if !request.IsOCIRegistry {
+		chartRepo, err := impl.repoRepository.FindById(request.ChartRepoId)
+		if err != nil {
+			return err
+		}
+		chartRepo.Active = request.Active
+		chartRepo.UpdatedBy = request.UserId
+		chartRepo.UpdatedOn = time.Now()
+		err = impl.repoRepository.Update(chartRepo, tx)
+		if err != nil {
+			return err
+		}
+	} else {
+		ociRegistryConfigs, err := impl.ociRegistryConfigRepository.FindByDockerRegistryId(request.Id)
+		if err != nil {
+			impl.logger.Errorw("find OCI config service err, ToggleChartProvider", "err", err, "DockerArtifactStoreId", request.Id)
+			return err
+		}
+		found := false
+		for _, ociRegistryConfig := range ociRegistryConfigs {
+			//TODO: refactor
+			if ociRegistryConfig.RepositoryType == dockerRegistryRepository.OCI_REGISRTY_REPO_TYPE_CHART &&
+				(ociRegistryConfig.RepositoryAction == dockerRegistryRepository.STORAGE_ACTION_TYPE_PULL ||
+					ociRegistryConfig.RepositoryAction == dockerRegistryRepository.STORAGE_ACTION_TYPE_PULL_AND_PUSH) {
+				ociRegistryConfig.IsChartPullActive = request.Active
+				ociRegistryConfig.UpdatedBy = request.UserId
+				ociRegistryConfig.UpdatedOn = time.Now()
+				found = true
+				err = impl.ociRegistryConfigRepository.Update(ociRegistryConfig, tx)
+				if err != nil {
+					impl.logger.Errorw("update OCI config service err, ToggleChartProvider", "err", err, "DockerArtifactStoreId", request.Id)
+					return err
+				}
+				break
+			}
+		}
+		if !found {
+			impl.logger.Errorw("no OCI config found for update, ToggleChartProvider", "err", pg.ErrNoRows, "DockerArtifactStoreId", request.Id)
+			return pg.ErrNoRows
+		}
+	}
+
+	err = tx.Commit()
+	if err != nil {
+		impl.logger.Errorw("error in db transaction commit, ToggleChartProvider", "err", err)
+		return err
+	}
+	return nil
+}
+
+func (impl *ChartProviderServiceExtendedImpl) SyncChartProvider(request *ChartProviderRequestDto) error {
+	chartProviderConfig := &chartRepo.ChartProviderConfig{
+		ChartProviderId: request.Id,
+		IsOCIRegistry:   request.IsOCIRegistry,
+	}
+	err := impl.chartRepositoryService.TriggerChartSyncManual(chartProviderConfig)
+	if err != nil {
+		impl.logger.Errorw("error creating chart sync job, SyncChartProvider", "err", err)
+		return err
+	}
+	return nil
+}
diff --git a/pkg/appStore/chartProvider/bean.go b/pkg/appStore/chartProvider/bean.go
new file mode 100644
index 000000000..2efab9565
--- /dev/null
+++ b/pkg/appStore/chartProvider/bean.go
@@ -0,0 +1,21 @@
+package chartProvider
+
+import repository "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry"
+
+type ChartProviderResponseDto struct {
+	Id               string                  `json:"id" validate:"required"`
+	Name             string                  `json:"name" validate:"required"`
+	Active           bool                    `json:"active" validate:"required"`
+	IsEditable       bool                    `json:"isEditable"`
+	IsOCIRegistry    bool                    `json:"isOCIRegistry"`
+	RegistryProvider repository.RegistryType `json:"registryProvider"`
+	UserId           int32                   `json:"-"`
+}
+
+type ChartProviderRequestDto struct {
+	Id            string `json:"id" validate:"required"`
+	IsOCIRegistry bool   `json:"isOCIRegistry"`
+	Active        bool   `json:"active,omitempty"`
+	UserId        int32  `json:"-"`
+	ChartRepoId   int    `json:"-"`
+}
diff --git a/pkg/appStore/deployment/common/AppStoreDeploymentCommonService.go b/pkg/appStore/deployment/common/AppStoreDeploymentCommonService.go
index ad89f67c1..fe69ed8bd 100644
--- a/pkg/appStore/deployment/common/AppStoreDeploymentCommonService.go
+++ b/pkg/appStore/deployment/common/AppStoreDeploymentCommonService.go
@@ -247,9 +247,11 @@ func (impl AppStoreDeploymentCommonServiceImpl) GetRequirementsString(appStoreVe
 		return "", err
 	}
 	dependency := appStoreBean.Dependency{
-		Name:       appStoreAppVersion.AppStore.Name,
-		Version:    appStoreAppVersion.Version,
-		Repository: appStoreAppVersion.AppStore.ChartRepo.Url,
+		Name:    appStoreAppVersion.AppStore.Name,
+		Version: appStoreAppVersion.Version,
+	}
+	if appStoreAppVersion.AppStore.ChartRepo != nil {
+		dependency.Repository = appStoreAppVersion.AppStore.ChartRepo.Url
 	}
 	var dependencies []appStoreBean.Dependency
 	dependencies = append(dependencies, dependency)
diff --git a/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go b/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go
index 4efa2d185..8aa2e56db 100644
--- a/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go
+++ b/pkg/appStore/deployment/fullMode/AppStoreDeploymentFullModeService.go
@@ -156,11 +156,12 @@ func (impl AppStoreDeploymentFullModeServiceImpl) AppStoreDeployOperationGIT(ins
 	//STEP 3 - update requirements and values
 	argocdAppName := installAppVersionRequest.AppName + "-" + environment.Name
 	dependency := appStoreBean.Dependency{
-		Name:       appStoreAppVersion.AppStore.Name,
-		Version:    appStoreAppVersion.Version,
-		Repository: appStoreAppVersion.AppStore.ChartRepo.Url,
+		Name:    appStoreAppVersion.AppStore.Name,
+		Version: appStoreAppVersion.Version,
+	}
+	if appStoreAppVersion.AppStore.ChartRepo != nil {
+		dependency.Repository = appStoreAppVersion.AppStore.ChartRepo.Url
 	}
-
 	var dependencies []appStoreBean.Dependency
 	dependencies = append(dependencies, dependency)
 	requirementDependencies := &appStoreBean.Dependencies{
diff --git a/pkg/appStore/deployment/repository/InstalledAppRepository.go b/pkg/appStore/deployment/repository/InstalledAppRepository.go
index cf67e81fb..6cd967360 100644
--- a/pkg/appStore/deployment/repository/InstalledAppRepository.go
+++ b/pkg/appStore/deployment/repository/InstalledAppRepository.go
@@ -130,6 +130,7 @@ type GitOpsAppDetails struct {
 type InstalledAppsWithChartDetails struct {
 	AppStoreApplicationName      string    `json:"app_store_application_name"`
 	ChartRepoName                string    `json:"chart_repo_name"`
+	DockerArtifactStoreId        string    `json:"docker_artifact_store_id"`
 	AppName                      string    `json:"app_name"`
 	EnvironmentName              string    `json:"environment_name"`
 	InstalledAppVersionId        int       `json:"installed_app_version_id"`
@@ -284,7 +285,7 @@ func (impl InstalledAppRepositoryImpl) GetInstalledAppVersionAny(id int) (*Insta
 func (impl InstalledAppRepositoryImpl) GetAllInstalledApps(filter *appStoreBean.AppStoreFilter) ([]InstalledAppsWithChartDetails, error) {
 	var installedAppsWithChartDetails []InstalledAppsWithChartDetails
 	var query string
-	query = "select iav.updated_on, iav.id as installed_app_version_id, ch.name as chart_repo_name,"
+	query = "select iav.updated_on, iav.id as installed_app_version_id, ch.name as chart_repo_name, das.id as docker_artifact_store_id,"
 	query = query + " env.environment_name, env.id as environment_id, a.app_name, a.app_offering_mode, asav.icon, asav.name as app_store_application_name,"
 	query = query + " env.namespace, cluster.cluster_name, a.team_id, cluster.id as cluster_id, "
 	query = query + " asav.id as app_store_application_version_id, ia.id , asav.deprecated , app_status.status as app_status, ia.deployment_app_delete_request"
@@ -295,7 +296,8 @@ func (impl InstalledAppRepositoryImpl) GetAllInstalledApps(filter *appStoreBean.
 	query = query + " inner join cluster on env.cluster_id = cluster.id"
 	query = query + " inner join app_store_application_version asav on iav.app_store_application_version_id = asav.id"
 	query = query + " inner join app_store aps on aps.id = asav.app_store_id"
-	query = query + " inner join chart_repo ch on ch.id = aps.chart_repo_id"
+	query = query + " left join chart_repo ch on ch.id = aps.chart_repo_id"
+	query = query + " left join docker_artifact_store das on das.id = aps.docker_artifact_store_id"
 	query = query + " left join app_status on app_status.app_id = ia.app_id and ia.environment_id = app_status.env_id"
 	query = query + " where ia.active = true and iav.active = true"
 	if filter.OnlyDeprecated {
diff --git a/pkg/appStore/deployment/service/AppStoreDeploymentService.go b/pkg/appStore/deployment/service/AppStoreDeploymentService.go
index 725d836df..c037c0442 100644
--- a/pkg/appStore/deployment/service/AppStoreDeploymentService.go
+++ b/pkg/appStore/deployment/service/AppStoreDeploymentService.go
@@ -370,7 +370,10 @@ func (impl *AppStoreDeploymentServiceImpl) IsChartRepoActive(appStoreVersionId i
 		impl.logger.Errorw("fetching error", "err", err)
 		return false, err
 	}
-	return appStoreAppVersion.AppStore.ChartRepo.Active, nil
+	if appStoreAppVersion.AppStore.ChartRepo != nil {
+		return appStoreAppVersion.AppStore.ChartRepo.Active, nil
+	}
+	return false, nil
 }
 
 func (impl AppStoreDeploymentServiceImpl) InstallApp(installAppVersionRequest *appStoreBean.InstallAppVersionDTO, ctx context.Context) (*appStoreBean.InstallAppVersionDTO, error) {
diff --git a/pkg/appStore/discover/repository/AppStoreApplicationVersionRepository.go b/pkg/appStore/discover/repository/AppStoreApplicationVersionRepository.go
index 2446567f5..33a1ff76d 100644
--- a/pkg/appStore/discover/repository/AppStoreApplicationVersionRepository.go
+++ b/pkg/appStore/discover/repository/AppStoreApplicationVersionRepository.go
@@ -47,6 +47,13 @@ func NewAppStoreApplicationVersionRepositoryImpl(Logger *zap.SugaredLogger, dbCo
 	return &AppStoreApplicationVersionRepositoryImpl{dbConnection: dbConnection, Logger: Logger}
 }
 
+type FilterQueryUpdateAction string
+
+const (
+	QUERY_COLUMN_UPDATE FilterQueryUpdateAction = "column"
+	QUERY_JOIN_UPDTAE   FilterQueryUpdateAction = "join"
+)
+
 type AppStoreApplicationVersion struct {
 	TableName   struct{}  `sql:"app_store_application_version" pg:",discard_unknown_columns"`
 	Id          int       `sql:"id,pk"`
@@ -79,6 +86,7 @@ func (impl AppStoreApplicationVersionRepositoryImpl) GetChartInfoById(id int) (*
 	return &appStoreWithVersion, err
 }
 
+// FindAll is not being used. instead FindWithFilter is being used for chart listing
 func (impl *AppStoreApplicationVersionRepositoryImpl) FindAll() ([]appStoreBean.AppStoreWithVersion, error) {
 	var appStoreWithVersion []appStoreBean.AppStoreWithVersion
 	queryTemp := "select asv.version, asv.icon,asv.deprecated ,asv.id as app_store_application_version_id, aps.*, ch.name as chart_name" +
@@ -92,23 +100,66 @@ func (impl *AppStoreApplicationVersionRepositoryImpl) FindAll() ([]appStoreBean.
 	return appStoreWithVersion, err
 }
 
+func updateFindWithFilterQuery(filter *appStoreBean.AppStoreFilter, updateAction FilterQueryUpdateAction) string {
+	query := ""
+	if updateAction == QUERY_COLUMN_UPDATE {
+		if len(filter.ChartRepoId) > 0 && len(filter.RegistryId) > 0 {
+			query = query + " ch.name as chart_name, das.id as docker_artifact_store_id"
+		} else if len(filter.RegistryId) > 0 {
+			query = query + " das.id as docker_artifact_store_id"
+		} else if len(filter.ChartRepoId) > 0 {
+			query = query + " ch.name as chart_name"
+		} else {
+			query = query + " ch.name as chart_name, das.id as docker_artifact_store_id"
+		}
+	}
+	if updateAction == QUERY_JOIN_UPDTAE {
+		if len(filter.ChartRepoId) > 0 && len(filter.RegistryId) > 0 {
+			query = query + " LEFT JOIN chart_repo ch ON aps.chart_repo_id = ch.id" +
+				" LEFT JOIN docker_artifact_store das ON aps.docker_artifact_store_id = das.id" +
+				" LEFT JOIN oci_registry_config oci ON oci.docker_artifact_store_id = das.id" +
+				" WHERE (asv.latest IS TRUE AND (ch.active IS TRUE OR (das.active IS TRUE AND oci.is_chart_pull_active IS TRUE)))" +
+				" AND (ch.id IN (?) OR das.id IN (?))"
+		} else if len(filter.RegistryId) > 0 {
+			query = query +
+				" LEFT JOIN docker_artifact_store das ON aps.docker_artifact_store_id = das.id" +
+				" LEFT JOIN oci_registry_config oci ON oci.docker_artifact_store_id = das.id" +
+				" WHERE asv.latest IS TRUE AND (das.active IS TRUE AND oci.is_chart_pull_active IS TRUE)" +
+				" AND das.id IN (?)"
+		} else if len(filter.ChartRepoId) > 0 {
+			query = query +
+				" LEFT JOIN chart_repo ch ON aps.chart_repo_id = ch.id" +
+				" WHERE asv.latest IS TRUE AND ch.active IS TRUE" +
+				" AND ch.id IN (?)"
+		} else {
+			query = query +
+				" LEFT JOIN chart_repo ch ON aps.chart_repo_id = ch.id" +
+				" LEFT JOIN docker_artifact_store das ON aps.docker_artifact_store_id = das.id" +
+				" LEFT JOIN oci_registry_config oci ON oci.docker_artifact_store_id = das.id" +
+				" WHERE (asv.latest IS TRUE AND (ch.active IS TRUE OR (das.active IS TRUE AND oci.is_chart_pull_active IS TRUE)))"
+		}
+	}
+	return query
+}
+
 func (impl *AppStoreApplicationVersionRepositoryImpl) FindWithFilter(filter *appStoreBean.AppStoreFilter) ([]appStoreBean.AppStoreWithVersion, error) {
 	var appStoreWithVersion []appStoreBean.AppStoreWithVersion
-	query := "SELECT asv.version, asv.icon,asv.deprecated,asv.id as app_store_application_version_id," +
-		" asv.description, aps.*, ch.name as chart_name" +
-		" FROM app_store_application_version asv" +
-		" INNER JOIN app_store aps ON asv.app_store_id = aps.id" +
-		" INNER JOIN chart_repo ch ON aps.chart_repo_id = ch.id" +
-		" WHERE asv.latest IS TRUE AND ch.active = TRUE"
+	query := "SELECT asv.version, asv.icon, asv.deprecated, asv.id as app_store_application_version_id," +
+		" asv.description, aps.*,"
+
+	query = query + updateFindWithFilterQuery(filter, QUERY_COLUMN_UPDATE)
+
+	query = query + " FROM app_store_application_version asv" +
+		" INNER JOIN app_store aps ON asv.app_store_id = aps.id"
+
+	query = query + updateFindWithFilterQuery(filter, QUERY_JOIN_UPDTAE)
+
 	if !filter.IncludeDeprecated {
 		query = query + " AND asv.deprecated = FALSE"
 	}
 	if len(filter.AppStoreName) > 0 {
 		query = query + " AND aps.name LIKE '%" + filter.AppStoreName + "%'"
 	}
-	if len(filter.ChartRepoId) > 0 {
-		query = query + " AND ch.id IN (?)"
-	}
 	query = query + " ORDER BY aps.name ASC"
 	if filter.Size > 0 {
 		query = query + " OFFSET " + strconv.Itoa(filter.Offset) + " LIMIT " + strconv.Itoa(filter.Size) + ""
@@ -116,7 +167,11 @@ func (impl *AppStoreApplicationVersionRepositoryImpl) FindWithFilter(filter *app
 	query = query + ";"
 
 	var err error
-	if len(filter.ChartRepoId) > 0 {
+	if len(filter.ChartRepoId) > 0 && len(filter.RegistryId) > 0 {
+		_, err = impl.dbConnection.Query(&appStoreWithVersion, query, pg.In(filter.ChartRepoId), pg.In(filter.RegistryId))
+	} else if len(filter.RegistryId) > 0 {
+		_, err = impl.dbConnection.Query(&appStoreWithVersion, query, pg.In(filter.RegistryId))
+	} else if len(filter.ChartRepoId) > 0 {
 		_, err = impl.dbConnection.Query(&appStoreWithVersion, query, pg.In(filter.ChartRepoId))
 	} else {
 		_, err = impl.dbConnection.Query(&appStoreWithVersion, query)
@@ -131,8 +186,11 @@ func (impl AppStoreApplicationVersionRepositoryImpl) FindById(id int) (*AppStore
 	appStoreWithVersion := &AppStoreApplicationVersion{}
 	err := impl.dbConnection.
 		Model(appStoreWithVersion).
-		Column("app_store_application_version.*", "AppStore", "AppStore.ChartRepo").
+		Column("app_store_application_version.*", "AppStore", "AppStore.ChartRepo", "AppStore.DockerArtifactStore").
 		Where("app_store_application_version.id = ?", id).
+		Join("INNER JOIN app_store aps on app_store_application_version.app_store_id = aps.id").
+		Join("LEFT JOIN chart_repo ch on aps.chart_repo_id = ch.id").
+		Join("LEFT JOIN docker_artifact_store das on aps.docker_artifact_store_id = das.id").
 		Limit(1).
 		Select()
 	return appStoreWithVersion, err
@@ -145,8 +203,11 @@ func (impl AppStoreApplicationVersionRepositoryImpl) FindByIds(ids []int) ([]*Ap
 	}
 	err := impl.dbConnection.
 		Model(&appStoreApplicationVersions).
-		Column("app_store_application_version.*", "AppStore", "AppStore.ChartRepo").
+		Column("app_store_application_version.*", "AppStore", "AppStore.ChartRepo", "AppStore.DockerArtifactStore").
 		Where("app_store_application_version.id in (?)", pg.In(ids)).
+		Join("INNER JOIN app_store aps on app_store_application_version.app_store_id = aps.id").
+		Join("LEFT JOIN chart_repo ch on aps.chart_repo_id = ch.id").
+		Join("LEFT JOIN docker_artifact_store das on aps.docker_artifact_store_id = das.id").
 		Select()
 	return appStoreApplicationVersions, err
 }
diff --git a/pkg/appStore/discover/repository/AppStoreRepository.go b/pkg/appStore/discover/repository/AppStoreRepository.go
index a55c88a63..036ffdf85 100644
--- a/pkg/appStore/discover/repository/AppStoreRepository.go
+++ b/pkg/appStore/discover/repository/AppStoreRepository.go
@@ -18,6 +18,7 @@
 package appStoreDiscoverRepository
 
 import (
+	dockerArtifactStoreRegistry "github.com/devtron-labs/devtron/internal/sql/repository/dockerRegistry"
 	chartRepoRepository "github.com/devtron-labs/devtron/pkg/chartRepo/repository"
 	"github.com/go-pg/pg"
 	"go.uber.org/zap"
@@ -41,8 +42,10 @@ type AppStore struct {
 	Name        string   `sql:"name"`
 	ChartRepoId int      `sql:"chart_repo_id"`
 	//Active           bool      `sql:"active"`
-	ChartGitLocation string    `sql:"chart_git_location"`
-	CreatedOn        time.Time `sql:"created_on"`
-	UpdatedOn        time.Time `sql:"updated_on"`
-	ChartRepo        *chartRepoRepository.ChartRepo
+	DockerArtifactStoreId string    `sql:"docker_artifact_store_id"`
+	ChartGitLocation      string    `sql:"chart_git_location"`
+	CreatedOn             time.Time `sql:"created_on"`
+	UpdatedOn             time.Time `sql:"updated_on"`
+	ChartRepo             *chartRepoRepository.ChartRepo
+	DockerArtifactStore   *dockerArtifactStoreRegistry.DockerArtifactStore
 }
diff --git a/pkg/appStore/discover/service/AppStoreService.go b/pkg/appStore/discover/service/AppStoreService.go
index 2e6b9f3bd..a90d7ec0b 100644
--- a/pkg/appStore/discover/service/AppStoreService.go
+++ b/pkg/appStore/discover/service/AppStoreService.go
@@ -69,7 +69,6 @@ func (impl *AppStoreServiceImpl) FindChartDetailsById(id int) (appStoreBean.AppS
 		Digest:                  chartDetails.Digest,
 		Icon:                    chartDetails.Icon,
 		Name:                    chartDetails.Name,
-		ChartName:               chartDetails.AppStore.ChartRepo.Name,
 		AppStoreApplicationName: chartDetails.AppStore.Name,
 		Home:                    chartDetails.Home,
 		Source:                  chartDetails.Source,
@@ -83,7 +82,14 @@ func (impl *AppStoreServiceImpl) FindChartDetailsById(id int) (appStoreBean.AppS
 		Readme:                  chartDetails.Readme,
 		ValuesSchemaJson:        chartDetails.ValuesSchemaJson,
 		Notes:                   chartDetails.Notes,
-		IsChartRepoActive:       chartDetails.AppStore.ChartRepo.Active,
+	}
+	if chartDetails.AppStore.DockerArtifactStore != nil {
+		appStoreApplicationVersion.ChartName = chartDetails.AppStore.DockerArtifactStore.Id
+		appStoreApplicationVersion.IsChartRepoActive = chartDetails.AppStore.DockerArtifactStore.Active
+	}
+	if chartDetails.AppStore.ChartRepo != nil {
+		appStoreApplicationVersion.ChartName = chartDetails.AppStore.ChartRepo.Name
+		appStoreApplicationVersion.IsChartRepoActive = chartDetails.AppStore.ChartRepo.Active
 	}
 	return appStoreApplicationVersion, nil
 }
diff --git a/pkg/appStore/values/service/AppStoreValuesService.go b/pkg/appStore/values/service/AppStoreValuesService.go
index 53055a24c..6d20d6fdf 100644
--- a/pkg/appStore/values/service/AppStoreValuesService.go
+++ b/pkg/appStore/values/service/AppStoreValuesService.go
@@ -372,11 +372,16 @@ func (impl AppStoreValuesServiceImpl) GetSelectedChartMetaData(req *ChartMetaDat
 	for _, appversion := range appVersions {
 		chartMeta := &ChartMetaDataResponse{
 			ChartName:                    appversion.AppStore.Name,
-			ChartRepoName:                appversion.AppStore.ChartRepo.Name,
 			AppStoreApplicationVersionId: appversion.Id,
 			Icon:                         appversion.Icon,
 			Kind:                         appStoreBean.REFERENCE_TYPE_DEFAULT,
 		}
+		if appversion.AppStore.DockerArtifactStore != nil {
+			chartMeta.ChartRepoName = appversion.AppStore.DockerArtifactStore.Id
+		}
+		if appversion.AppStore.ChartRepo != nil {
+			chartMeta.ChartRepoName = appversion.AppStore.ChartRepo.Name
+		}
 		res = append(res, chartMeta)
 	}
 	return res, err
diff --git a/pkg/chartRepo/ChartRepositoryService.go b/pkg/chartRepo/ChartRepositoryService.go
index b07846792..e685d921e 100644
--- a/pkg/chartRepo/ChartRepositoryService.go
+++ b/pkg/chartRepo/ChartRepositoryService.go
@@ -73,7 +73,7 @@ type ChartRepositoryService interface {
 	ValidateChartRepo(request *ChartRepoDto) *DetailedErrorHelmRepoValidation
 	ValidateAndCreateChartRepo(request *ChartRepoDto) (*chartRepoRepository.ChartRepo, error, *DetailedErrorHelmRepoValidation)
 	ValidateAndUpdateChartRepo(request *ChartRepoDto) (*chartRepoRepository.ChartRepo, error, *DetailedErrorHelmRepoValidation)
-	TriggerChartSyncManual() error
+	TriggerChartSyncManual(chartProviderConfig *ChartProviderConfig) error
 	DeleteChartRepo(request *ChartRepoDto) error
 	DeleteChartSecret(secretName string) error
 }
@@ -643,7 +643,11 @@ func (impl *ChartRepositoryServiceImpl) ValidateAndCreateChartRepo(request *Char
 	}
 
 	// Trigger chart sync job, ignore error
-	err = impl.TriggerChartSyncManual()
+	chartProviderConfig := &ChartProviderConfig{
+		ChartProviderId: "*",
+		IsOCIRegistry:   true,
+	}
+	err = impl.TriggerChartSyncManual(chartProviderConfig)
 	if err != nil {
 		impl.logger.Errorw("Error in triggering chart sync job manually ", "err", err)
 	}
@@ -662,7 +666,11 @@ func (impl *ChartRepositoryServiceImpl) ValidateAndUpdateChartRepo(request *Char
 	}
 
 	// Trigger chart sync job, ignore error
-	err = impl.TriggerChartSyncManual()
+	chartProviderConfig := &ChartProviderConfig{
+		ChartProviderId: "*",
+		IsOCIRegistry:   true,
+	}
+	err = impl.TriggerChartSyncManual(chartProviderConfig)
 	if err != nil {
 		impl.logger.Errorw("Error in triggering chart sync job manually", "err", err)
 	}
@@ -670,7 +678,7 @@ func (impl *ChartRepositoryServiceImpl) ValidateAndUpdateChartRepo(request *Char
 	return chartRepo, nil, validationResult
 }
 
-func (impl *ChartRepositoryServiceImpl) TriggerChartSyncManual() error {
+func (impl *ChartRepositoryServiceImpl) TriggerChartSyncManual(chartProviderConfig *ChartProviderConfig) error {
 	defaultClusterBean, err := impl.clusterService.FindOne(cluster.DEFAULT_CLUSTER)
 	if err != nil {
 		impl.logger.Errorw("defaultClusterBean err, TriggerChartSyncManual", "err", err)
@@ -683,7 +691,7 @@ func (impl *ChartRepositoryServiceImpl) TriggerChartSyncManual() error {
 		return err
 	}
 
-	manualAppSyncJobByteArr := manualAppSyncJobByteArr(impl.serverEnvConfig.AppSyncImage, impl.serverEnvConfig.AppSyncJobResourcesObj)
+	manualAppSyncJobByteArr := manualAppSyncJobByteArr(impl.serverEnvConfig.AppSyncImage, impl.serverEnvConfig.AppSyncJobResourcesObj, chartProviderConfig)
 
 	err = impl.K8sUtil.DeleteAndCreateJob(manualAppSyncJobByteArr, impl.aCDAuthConfig.ACDConfigMapNamespace, defaultClusterConfig)
 	if err != nil {
diff --git a/pkg/chartRepo/ManualAppSyncYaml.go b/pkg/chartRepo/ManualAppSyncYaml.go
index d613f3929..6003eb96e 100644
--- a/pkg/chartRepo/ManualAppSyncYaml.go
+++ b/pkg/chartRepo/ManualAppSyncYaml.go
@@ -10,14 +10,21 @@ type AppSyncConfig struct {
 	DbConfig               sql.Config
 	DockerImage            string
 	AppSyncJobResourcesObj string
+	ChartProviderConfig    *ChartProviderConfig
 }
 
-func manualAppSyncJobByteArr(dockerImage string, appSyncJobResourcesObj string) []byte {
+type ChartProviderConfig struct {
+	ChartProviderId string
+	IsOCIRegistry   bool
+}
+
+func manualAppSyncJobByteArr(dockerImage string, appSyncJobResourcesObj string, chartProviderConfig *ChartProviderConfig) []byte {
 	cfg, _ := sql.GetConfig()
 	configValues := AppSyncConfig{
 		DbConfig:               sql.Config{Addr: cfg.Addr, Database: cfg.Database, User: cfg.User, Password: cfg.Password},
 		DockerImage:            dockerImage,
 		AppSyncJobResourcesObj: appSyncJobResourcesObj,
+		ChartProviderConfig:    chartProviderConfig,
 	}
 	temp := template.New("manualAppSyncJobByteArr")
 	temp, _ = temp.Parse(`{"apiVersion": "batch/v1",
@@ -52,7 +59,15 @@ func manualAppSyncJobByteArr(dockerImage string, appSyncJobResourcesObj string)
               {
                 "name": "PG_PASSWORD",
                 "value": "{{.DbConfig.Password}}"
-              }
+              },
+			  {
+                "name": "CHART_PROVIDER_ID",
+                "value": "{{.ChartProviderConfig.ChartProviderId}}"
+			  },
+			  {
+                "name": "IS_OCI_REGISTRY",
+                "value": "{{.ChartProviderConfig.IsOCIRegistry}}"
+			  }
             ]
           }
         ],
diff --git a/pkg/pipeline/DockerRegistryConfig.go b/pkg/pipeline/DockerRegistryConfig.go
index daeab7507..264b4da58 100644
--- a/pkg/pipeline/DockerRegistryConfig.go
+++ b/pkg/pipeline/DockerRegistryConfig.go
@@ -18,10 +18,13 @@
 package pipeline
 
 import (
+	"context"
 	"fmt"
+	client "github.com/devtron-labs/devtron/api/helm-app"
 	"github.com/devtron-labs/devtron/pkg/sql"
 	"github.com/go-pg/pg"
 	"k8s.io/utils/strings/slices"
+	"net/http"
 	"strings"
 	"time"
 
@@ -41,6 +44,7 @@ type DockerRegistryConfig interface {
 	Delete(storeId string) (string, error)
 	DeleteReg(bean *DockerArtifactStoreBean) error
 	CheckInActiveDockerAccount(storeId string) (bool, error)
+	ValidateRegistryCredentials(bean *DockerArtifactStoreBean) bool
 	ConfigureOCIRegistry(bean *DockerArtifactStoreBean, isUpdate bool, userId int32, tx *pg.Tx) error
 	CreateOrUpdateOCIRegistryConfig(ociRegistryConfig *repository.OCIRegistryConfig, userId int32, tx *pg.Tx) error
 	FilterOCIRegistryConfigForSpecificRepoType(ociRegistryConfigList []*repository.OCIRegistryConfig, repositoryType string) *repository.OCIRegistryConfig
@@ -82,15 +86,17 @@ type DockerRegistryIpsConfigBean struct {
 
 type DockerRegistryConfigImpl struct {
 	logger                            *zap.SugaredLogger
+	helmAppService                    client.HelmAppService
 	dockerArtifactStoreRepository     repository.DockerArtifactStoreRepository
 	dockerRegistryIpsConfigRepository repository.DockerRegistryIpsConfigRepository
 	ociRegistryConfigRepository       repository.OCIRegistryConfigRepository
 }
 
-func NewDockerRegistryConfigImpl(logger *zap.SugaredLogger, dockerArtifactStoreRepository repository.DockerArtifactStoreRepository,
+func NewDockerRegistryConfigImpl(logger *zap.SugaredLogger, helmAppService client.HelmAppService, dockerArtifactStoreRepository repository.DockerArtifactStoreRepository,
 	dockerRegistryIpsConfigRepository repository.DockerRegistryIpsConfigRepository, ociRegistryConfigRepository repository.OCIRegistryConfigRepository) *DockerRegistryConfigImpl {
 	return &DockerRegistryConfigImpl{
 		logger:                            logger,
+		helmAppService:                    helmAppService,
 		dockerArtifactStoreRepository:     dockerArtifactStoreRepository,
 		dockerRegistryIpsConfigRepository: dockerRegistryIpsConfigRepository,
 		ociRegistryConfigRepository:       ociRegistryConfigRepository,
@@ -536,7 +542,15 @@ func (impl DockerRegistryConfigImpl) Update(bean *DockerArtifactStoreBean) (*Doc
 	bean.PluginId = existingStore.PluginId
 
 	store := NewDockerArtifactStore(bean, true, existingStore.CreatedOn, time.Now(), existingStore.CreatedBy, bean.User)
-
+	if isValid := impl.ValidateRegistryCredentials(bean); !isValid {
+		impl.logger.Errorw("registry credentials validation err, SaveDockerRegistryConfig", "err", err, "payload", bean)
+		err = &util.ApiError{
+			HttpStatusCode:  http.StatusBadRequest,
+			InternalMessage: "Invalid authentication credentials. Please verify.",
+			UserMessage:     "Invalid authentication credentials. Please verify.",
+		}
+		return nil, err
+	}
 	err = impl.dockerArtifactStoreRepository.Update(store, tx)
 	if err != nil {
 		impl.logger.Errorw("error in updating registry config in db", "config", store, "err", err)
@@ -769,3 +783,20 @@ func (impl DockerRegistryConfigImpl) CheckInActiveDockerAccount(storeId string)
 	}
 	return exist, nil
 }
+
+func (impl DockerRegistryConfigImpl) ValidateRegistryCredentials(bean *DockerArtifactStoreBean) bool {
+	if bean.IsPublic {
+		return true
+	}
+	request := &client.RegistryCredential{
+		RegistryUrl:  bean.RegistryURL,
+		Username:     bean.Username,
+		Password:     bean.Password,
+		AwsRegion:    bean.AWSRegion,
+		AccessKey:    bean.AWSAccessKeyId,
+		SecretKey:    bean.AWSSecretAccessKey,
+		RegistryType: string(bean.RegistryType),
+		IsPublic:     bean.IsPublic,
+	}
+	return impl.helmAppService.ValidateOCIRegistry(context.Background(), request)
+}
diff --git a/wire_gen.go b/wire_gen.go
index 7663ccf8c..9c1ffe2d4 100644
--- a/wire_gen.go
+++ b/wire_gen.go
@@ -13,6 +13,7 @@ import (
 	"github.com/devtron-labs/common-lib/pubsub-lib"
 	apiToken2 "github.com/devtron-labs/devtron/api/apiToken"
 	"github.com/devtron-labs/devtron/api/appStore"
+	chartProvider2 "github.com/devtron-labs/devtron/api/appStore/ChartProvider"
 	"github.com/devtron-labs/devtron/api/appStore/deployment"
 	"github.com/devtron-labs/devtron/api/appStore/discover"
 	"github.com/devtron-labs/devtron/api/appStore/values"
@@ -71,6 +72,7 @@ import (
 	appGroup2 "github.com/devtron-labs/devtron/pkg/appGroup"
 	appStatus2 "github.com/devtron-labs/devtron/pkg/appStatus"
 	"github.com/devtron-labs/devtron/pkg/appStore/bean"
+	"github.com/devtron-labs/devtron/pkg/appStore/chartProvider"
 	"github.com/devtron-labs/devtron/pkg/appStore/deployment/common"
 	"github.com/devtron-labs/devtron/pkg/appStore/deployment/fullMode"
 	repository3 "github.com/devtron-labs/devtron/pkg/appStore/deployment/repository"
@@ -461,7 +463,7 @@ func InitializeApp() (*App, error) {
 	ciHandlerImpl := pipeline.NewCiHandlerImpl(sugaredLogger, ciServiceImpl, ciPipelineMaterialRepositoryImpl, clientImpl, ciWorkflowRepositoryImpl, workflowServiceImpl, ciLogServiceImpl, ciConfig, ciArtifactRepositoryImpl, userServiceImpl, eventRESTClientImpl, eventSimpleFactoryImpl, ciPipelineRepositoryImpl, appListingRepositoryImpl, k8sUtil, pipelineRepositoryImpl, enforcerUtilImpl, appGroupServiceImpl, environmentRepositoryImpl, imageTaggingServiceImpl)
 	gitRegistryConfigImpl := pipeline.NewGitRegistryConfigImpl(sugaredLogger, gitProviderRepositoryImpl, clientImpl)
 	ociRegistryConfigRepositoryImpl := repository5.NewOCIRegistryConfigRepositoryImpl(db)
-	dockerRegistryConfigImpl := pipeline.NewDockerRegistryConfigImpl(sugaredLogger, dockerArtifactStoreRepositoryImpl, dockerRegistryIpsConfigRepositoryImpl, ociRegistryConfigRepositoryImpl)
+	dockerRegistryConfigImpl := pipeline.NewDockerRegistryConfigImpl(sugaredLogger, helmAppServiceImpl, dockerArtifactStoreRepositoryImpl, dockerRegistryIpsConfigRepositoryImpl, ociRegistryConfigRepositoryImpl)
 	appListingViewBuilderImpl := app2.NewAppListingViewBuilderImpl(sugaredLogger)
 	linkoutsRepositoryImpl := repository.NewLinkoutsRepositoryImpl(sugaredLogger, db)
 	appListingServiceImpl := app2.NewAppListingServiceImpl(sugaredLogger, appListingRepositoryImpl, applicationServiceClientImpl, appRepositoryImpl, appListingViewBuilderImpl, pipelineRepositoryImpl, linkoutsRepositoryImpl, appLevelMetricsRepositoryImpl, envLevelAppMetricsRepositoryImpl, cdWorkflowRepositoryImpl, pipelineOverrideRepositoryImpl, environmentRepositoryImpl, argoUserServiceImpl, envConfigOverrideRepositoryImpl, chartRepositoryImpl, ciPipelineRepositoryImpl, dockerRegistryIpsConfigServiceImpl)
@@ -558,7 +560,8 @@ func InitializeApp() (*App, error) {
 	gitHostConfigImpl := pipeline.NewGitHostConfigImpl(gitHostRepositoryImpl, sugaredLogger, attributesServiceImpl)
 	gitHostRestHandlerImpl := restHandler.NewGitHostRestHandlerImpl(sugaredLogger, gitHostConfigImpl, userServiceImpl, validate, enforcerImpl, clientImpl, gitRegistryConfigImpl)
 	gitHostRouterImpl := router.NewGitHostRouterImpl(gitHostRestHandlerImpl)
-	dockerRegRestHandlerImpl := restHandler.NewDockerRegRestHandlerImpl(dockerRegistryConfigImpl, sugaredLogger, gitRegistryConfigImpl, dbConfigServiceImpl, userServiceImpl, validate, enforcerImpl, teamServiceImpl, deleteServiceFullModeImpl)
+	chartProviderServiceExtendedImpl := chartProvider.NewChartProviderServiceExtendedImpl(sugaredLogger, chartRepoRepositoryImpl, chartRepositoryServiceImpl, dockerArtifactStoreRepositoryImpl, ociRegistryConfigRepositoryImpl)
+	dockerRegRestHandlerImpl := restHandler.NewDockerRegRestHandlerImpl(dockerRegistryConfigImpl, sugaredLogger, chartProviderServiceExtendedImpl, gitRegistryConfigImpl, dbConfigServiceImpl, userServiceImpl, validate, enforcerImpl, teamServiceImpl, deleteServiceFullModeImpl)
 	dockerRegRouterImpl := router.NewDockerRegRouterImpl(dockerRegRestHandlerImpl)
 	notificationSettingsRepositoryImpl := repository.NewNotificationSettingsRepositoryImpl(db)
 	notificationConfigBuilderImpl := notifier.NewNotificationConfigBuilderImpl(sugaredLogger)
@@ -591,10 +594,12 @@ func InitializeApp() (*App, error) {
 	appStoreServiceImpl := service3.NewAppStoreServiceImpl(sugaredLogger, appStoreApplicationVersionRepositoryImpl)
 	appStoreRestHandlerImpl := appStoreDiscover.NewAppStoreRestHandlerImpl(sugaredLogger, userServiceImpl, appStoreServiceImpl, enforcerImpl)
 	appStoreDiscoverRouterImpl := appStoreDiscover.NewAppStoreDiscoverRouterImpl(appStoreRestHandlerImpl)
+	chartProviderRestHandlerImpl := chartProvider2.NewChartProviderRestHandlerImpl(sugaredLogger, userServiceImpl, validate, chartProviderServiceExtendedImpl, enforcerImpl)
+	chartProviderRouterImpl := chartProvider2.NewChartProviderRouterImpl(chartProviderRestHandlerImpl)
 	appStoreDeploymentRestHandlerImpl := appStoreDeployment.NewAppStoreDeploymentRestHandlerImpl(sugaredLogger, userServiceImpl, enforcerImpl, enforcerUtilImpl, enforcerUtilHelmImpl, appStoreDeploymentServiceImpl, validate, helmAppServiceImpl, appStoreDeploymentCommonServiceImpl, argoUserServiceImpl, attributesServiceImpl)
 	appStoreDeploymentRouterImpl := appStoreDeployment.NewAppStoreDeploymentRouterImpl(appStoreDeploymentRestHandlerImpl)
 	appStoreStatusTimelineRestHandlerImpl := appStore.NewAppStoreStatusTimelineRestHandlerImpl(sugaredLogger, pipelineStatusTimelineServiceImpl, enforcerUtilImpl, enforcerImpl)
-	appStoreRouterImpl := appStore.NewAppStoreRouterImpl(installedAppRestHandlerImpl, appStoreValuesRouterImpl, appStoreDiscoverRouterImpl, appStoreDeploymentRouterImpl, appStoreStatusTimelineRestHandlerImpl)
+	appStoreRouterImpl := appStore.NewAppStoreRouterImpl(installedAppRestHandlerImpl, appStoreValuesRouterImpl, appStoreDiscoverRouterImpl, chartProviderRouterImpl, appStoreDeploymentRouterImpl, appStoreStatusTimelineRestHandlerImpl)
 	chartRepositoryRestHandlerImpl := chartRepo2.NewChartRepositoryRestHandlerImpl(sugaredLogger, userServiceImpl, chartRepositoryServiceImpl, enforcerImpl, validate, deleteServiceExtendedImpl, chartRefRepositoryImpl, refChartDir, attributesServiceImpl)
 	chartRepositoryRouterImpl := chartRepo2.NewChartRepositoryRouterImpl(chartRepositoryRestHandlerImpl)
 	lensConfig, err := lens.GetLensConfig()


Test patch:
diff --git a/pkg/pipeline/DockerRegistryConfig_test.go b/pkg/pipeline/DockerRegistryConfig_test.go
index 7918f9726..79ca14f33 100644
--- a/pkg/pipeline/DockerRegistryConfig_test.go
+++ b/pkg/pipeline/DockerRegistryConfig_test.go
@@ -192,5 +192,5 @@ func InitDockerRegistryConfig() {
 	dockerArtifactStoreRepository := repository.NewDockerArtifactStoreRepositoryImpl(conn)
 	dockerRegistryIpsConfigRepository := repository.NewDockerRegistryIpsConfigRepositoryImpl(conn)
 	ociRegistryConfigRepository := repository.NewOCIRegistryConfigRepositoryImpl(conn)
-	dockerRegistryConfig = NewDockerRegistryConfigImpl(logger, dockerArtifactStoreRepository, dockerRegistryIpsConfigRepository, ociRegistryConfigRepository)
+	dockerRegistryConfig = NewDockerRegistryConfigImpl(logger, nil, dockerArtifactStoreRepository, dockerRegistryIpsConfigRepository, ociRegistryConfigRepository)
 }