[config] Move certificate provider registry into core config (#30890)

* [config] Move certificate provider registry into core config

* Automated change: Fix sanity tests

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
diff --git a/BUILD b/BUILD
index 037663b..c4d4248 100644
--- a/BUILD
+++ b/BUILD
@@ -1251,6 +1251,7 @@
     ],
     visibility = ["@grpc:client_channel"],
     deps = [
+        "certificate_provider_registry",
         "channel_args_preconditioning",
         "channel_creds_registry",
         "channel_init",
@@ -4433,8 +4434,9 @@
         "src/core/lib/security/certificate_provider/certificate_provider_factory.h",
     ],
     deps = [
+        "error",
         "gpr",
-        "grpc_base",
+        "grpc_public_hdrs",
         "json",
         "ref_counted",
         "ref_counted_ptr",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3641b18..7aeead7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2866,6 +2866,7 @@
   src/core/lib/security/authorization/authorization_policy_provider_vtable.cc
   src/core/lib/security/authorization/evaluate_args.cc
   src/core/lib/security/authorization/grpc_server_authz_filter.cc
+  src/core/lib/security/certificate_provider/certificate_provider_registry.cc
   src/core/lib/security/context/security_context.cc
   src/core/lib/security/credentials/call_creds_util.cc
   src/core/lib/security/credentials/composite/composite_credentials.cc
diff --git a/Makefile b/Makefile
index ee50991..9a552ea 100644
--- a/Makefile
+++ b/Makefile
@@ -2019,6 +2019,7 @@
     src/core/lib/security/authorization/authorization_policy_provider_vtable.cc \
     src/core/lib/security/authorization/evaluate_args.cc \
     src/core/lib/security/authorization/grpc_server_authz_filter.cc \
+    src/core/lib/security/certificate_provider/certificate_provider_registry.cc \
     src/core/lib/security/context/security_context.cc \
     src/core/lib/security/credentials/call_creds_util.cc \
     src/core/lib/security/credentials/composite/composite_credentials.cc \
@@ -3166,7 +3167,6 @@
 src/core/lib/security/authorization/grpc_authorization_engine.cc: $(OPENSSL_DEP)
 src/core/lib/security/authorization/matchers.cc: $(OPENSSL_DEP)
 src/core/lib/security/authorization/rbac_policy.cc: $(OPENSSL_DEP)
-src/core/lib/security/certificate_provider/certificate_provider_registry.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/alts/alts_credentials.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/alts/check_gcp_environment.cc: $(OPENSSL_DEP)
 src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc: $(OPENSSL_DEP)
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index 29a4728..92235c9 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -2147,6 +2147,8 @@
   - src/core/lib/security/authorization/authorization_policy_provider.h
   - src/core/lib/security/authorization/evaluate_args.h
   - src/core/lib/security/authorization/grpc_server_authz_filter.h
+  - src/core/lib/security/certificate_provider/certificate_provider_factory.h
+  - src/core/lib/security/certificate_provider/certificate_provider_registry.h
   - src/core/lib/security/context/security_context.h
   - src/core/lib/security/credentials/call_creds_util.h
   - src/core/lib/security/credentials/channel_creds_registry.h
@@ -2465,6 +2467,7 @@
   - src/core/lib/security/authorization/authorization_policy_provider_vtable.cc
   - src/core/lib/security/authorization/evaluate_args.cc
   - src/core/lib/security/authorization/grpc_server_authz_filter.cc
+  - src/core/lib/security/certificate_provider/certificate_provider_registry.cc
   - src/core/lib/security/context/security_context.cc
   - src/core/lib/security/credentials/call_creds_util.cc
   - src/core/lib/security/credentials/composite/composite_credentials.cc
diff --git a/grpc.gyp b/grpc.gyp
index 5012b08..5d8a6cf 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -1370,6 +1370,7 @@
         'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc',
         'src/core/lib/security/authorization/evaluate_args.cc',
         'src/core/lib/security/authorization/grpc_server_authz_filter.cc',
+        'src/core/lib/security/certificate_provider/certificate_provider_registry.cc',
         'src/core/lib/security/context/security_context.cc',
         'src/core/lib/security/credentials/call_creds_util.cc',
         'src/core/lib/security/credentials/composite/composite_credentials.cc',
diff --git a/src/core/ext/xds/certificate_provider_store.cc b/src/core/ext/xds/certificate_provider_store.cc
index d771df0..b78129d 100644
--- a/src/core/ext/xds/certificate_provider_store.cc
+++ b/src/core/ext/xds/certificate_provider_store.cc
@@ -24,6 +24,7 @@
 
 #include <grpc/support/log.h>
 
+#include "src/core/lib/config/core_configuration.h"
 #include "src/core/lib/iomgr/error.h"
 #include "src/core/lib/security/certificate_provider/certificate_provider_registry.h"
 
@@ -48,8 +49,9 @@
   CertificateProviderFactory* factory = nullptr;
   if (!plugin_name.empty()) {
     ScopedField field(errors, ".plugin_name");
-    factory = CertificateProviderRegistry::LookupCertificateProviderFactory(
-        plugin_name);
+    factory = CoreConfiguration::Get()
+                  .certificate_provider_registry()
+                  .LookupCertificateProviderFactory(plugin_name);
     if (factory == nullptr) {
       errors->AddError(absl::StrCat("Unrecognized plugin name: ", plugin_name));
       return;  // No point checking config.
@@ -126,8 +128,10 @@
     return nullptr;
   }
   CertificateProviderFactory* factory =
-      CertificateProviderRegistry::LookupCertificateProviderFactory(
-          plugin_config_it->second.plugin_name);
+      CoreConfiguration::Get()
+          .certificate_provider_registry()
+          .LookupCertificateProviderFactory(
+              plugin_config_it->second.plugin_name);
   if (factory == nullptr) {
     // This should never happen since an entry is only inserted in the
     // plugin_config_map_ if the corresponding factory was found when parsing
diff --git a/src/core/ext/xds/file_watcher_certificate_provider_factory.cc b/src/core/ext/xds/file_watcher_certificate_provider_factory.cc
index fed84d0..ce7092f 100644
--- a/src/core/ext/xds/file_watcher_certificate_provider_factory.cc
+++ b/src/core/ext/xds/file_watcher_certificate_provider_factory.cc
@@ -31,6 +31,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 
+#include "src/core/lib/config/core_configuration.h"
 #include "src/core/lib/json/json_util.h"
 #include "src/core/lib/security/certificate_provider/certificate_provider_registry.h"
 #include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
@@ -143,11 +144,10 @@
       file_watcher_config->refresh_interval().millis() / GPR_MS_PER_SEC);
 }
 
-void FileWatcherCertificateProviderInit() {
-  CertificateProviderRegistry::RegisterCertificateProviderFactory(
+void RegisterFileWatcherCertificateProvider(
+    CoreConfiguration::Builder* builder) {
+  builder->certificate_provider_registry()->RegisterCertificateProviderFactory(
       absl::make_unique<FileWatcherCertificateProviderFactory>());
 }
 
-void FileWatcherCertificateProviderShutdown() {}
-
 }  // namespace grpc_core
diff --git a/src/core/lib/config/core_configuration.cc b/src/core/lib/config/core_configuration.cc
index 43a77ce..30931be 100644
--- a/src/core/lib/config/core_configuration.cc
+++ b/src/core/lib/config/core_configuration.cc
@@ -44,7 +44,9 @@
       channel_creds_registry_(builder->channel_creds_registry_.Build()),
       service_config_parser_(builder->service_config_parser_.Build()),
       resolver_registry_(builder->resolver_registry_.Build()),
-      lb_policy_registry_(builder->lb_policy_registry_.Build()) {}
+      lb_policy_registry_(builder->lb_policy_registry_.Build()),
+      certificate_provider_registry_(
+          builder->certificate_provider_registry_.Build()) {}
 
 void CoreConfiguration::RegisterBuilder(std::function<void(Builder*)> builder) {
   GPR_ASSERT(config_.load(std::memory_order_relaxed) == nullptr &&
diff --git a/src/core/lib/config/core_configuration.h b/src/core/lib/config/core_configuration.h
index ab5219d..ba3ae5f 100644
--- a/src/core/lib/config/core_configuration.h
+++ b/src/core/lib/config/core_configuration.h
@@ -25,6 +25,7 @@
 #include "src/core/lib/channel/channel_args_preconditioning.h"
 #include "src/core/lib/load_balancing/lb_policy_registry.h"
 #include "src/core/lib/resolver/resolver_registry.h"
+#include "src/core/lib/security/certificate_provider/certificate_provider_registry.h"
 #include "src/core/lib/security/credentials/channel_creds_registry.h"
 #include "src/core/lib/service_config/service_config_parser.h"
 #include "src/core/lib/surface/channel_init.h"
@@ -69,6 +70,10 @@
       return &lb_policy_registry_;
     }
 
+    CertificateProviderRegistry::Builder* certificate_provider_registry() {
+      return &certificate_provider_registry_;
+    }
+
    private:
     friend class CoreConfiguration;
 
@@ -79,6 +84,7 @@
     ServiceConfigParser::Builder service_config_parser_;
     ResolverRegistry::Builder resolver_registry_;
     LoadBalancingPolicyRegistry::Builder lb_policy_registry_;
+    CertificateProviderRegistry::Builder certificate_provider_registry_;
 
     Builder();
     CoreConfiguration* Build();
@@ -187,6 +193,10 @@
     return lb_policy_registry_;
   }
 
+  const CertificateProviderRegistry& certificate_provider_registry() const {
+    return certificate_provider_registry_;
+  }
+
   static void SetDefaultBuilder(void (*builder)(CoreConfiguration::Builder*)) {
     default_builder_ = builder;
   }
@@ -212,6 +222,7 @@
   ServiceConfigParser service_config_parser_;
   ResolverRegistry resolver_registry_;
   LoadBalancingPolicyRegistry lb_policy_registry_;
+  CertificateProviderRegistry certificate_provider_registry_;
 };
 
 extern void BuildCoreConfiguration(CoreConfiguration::Builder* builder);
diff --git a/src/core/lib/security/certificate_provider/certificate_provider_registry.cc b/src/core/lib/security/certificate_provider/certificate_provider_registry.cc
index 210374f..86bee4b 100644
--- a/src/core/lib/security/certificate_provider/certificate_provider_registry.cc
+++ b/src/core/lib/security/certificate_provider/certificate_provider_registry.cc
@@ -30,74 +30,31 @@
 
 namespace grpc_core {
 
-namespace {
-
-class RegistryState {
- public:
-  void RegisterCertificateProviderFactory(
-      std::unique_ptr<CertificateProviderFactory> factory) {
-    gpr_log(GPR_DEBUG, "registering certificate provider factory for \"%s\"",
-            factory->name());
-    for (size_t i = 0; i < factories_.size(); ++i) {
-      GPR_ASSERT(strcmp(factories_[i]->name(), factory->name()) != 0);
-    }
-    factories_.push_back(std::move(factory));
+void CertificateProviderRegistry::Builder::RegisterCertificateProviderFactory(
+    std::unique_ptr<CertificateProviderFactory> factory) {
+  gpr_log(GPR_DEBUG, "registering certificate provider factory for \"%s\"",
+          factory->name());
+  for (size_t i = 0; i < factories_.size(); ++i) {
+    GPR_ASSERT(strcmp(factories_[i]->name(), factory->name()) != 0);
   }
+  factories_.push_back(std::move(factory));
+}
 
-  CertificateProviderFactory* LookupCertificateProviderFactory(
-      absl::string_view name) const {
-    for (size_t i = 0; i < factories_.size(); ++i) {
-      if (name == factories_[i]->name()) {
-        return factories_[i].get();
-      }
-    }
-    return nullptr;
-  }
-
- private:
-  std::vector<std::unique_ptr<CertificateProviderFactory>> factories_;
-};
-
-RegistryState* g_state = nullptr;
-
-}  // namespace
-
-//
-// CertificateProviderRegistry
-//
+CertificateProviderRegistry CertificateProviderRegistry::Builder::Build() {
+  CertificateProviderRegistry r;
+  r.factories_ = std::move(factories_);
+  return r;
+}
 
 CertificateProviderFactory*
 CertificateProviderRegistry::LookupCertificateProviderFactory(
-    absl::string_view name) {
-  GPR_ASSERT(g_state != nullptr);
-  return g_state->LookupCertificateProviderFactory(name);
-}
-
-void CertificateProviderRegistry::InitRegistry() {
-  if (g_state == nullptr) g_state = new RegistryState();
-}
-
-void CertificateProviderRegistry::ShutdownRegistry() {
-  delete g_state;
-  g_state = nullptr;
-}
-
-void CertificateProviderRegistry::RegisterCertificateProviderFactory(
-    std::unique_ptr<CertificateProviderFactory> factory) {
-  InitRegistry();
-  g_state->RegisterCertificateProviderFactory(std::move(factory));
+    absl::string_view name) const {
+  for (size_t i = 0; i < factories_.size(); ++i) {
+    if (name == factories_[i]->name()) {
+      return factories_[i].get();
+    }
+  }
+  return nullptr;
 }
 
 }  // namespace grpc_core
-
-//
-// Plugin registration
-//
-
-void grpc_certificate_provider_registry_init() {
-  grpc_core::CertificateProviderRegistry::InitRegistry();
-}
-
-void grpc_certificate_provider_registry_shutdown() {
-  grpc_core::CertificateProviderRegistry::ShutdownRegistry();
-}
diff --git a/src/core/lib/security/certificate_provider/certificate_provider_registry.h b/src/core/lib/security/certificate_provider/certificate_provider_registry.h
index 25a0801..b81e377 100644
--- a/src/core/lib/security/certificate_provider/certificate_provider_registry.h
+++ b/src/core/lib/security/certificate_provider/certificate_provider_registry.h
@@ -22,6 +22,7 @@
 #include <grpc/support/port_platform.h>
 
 #include <memory>
+#include <vector>
 
 #include "absl/strings/string_view.h"
 
@@ -32,26 +33,36 @@
 // Global registry for all the certificate provider plugins.
 class CertificateProviderRegistry {
  public:
+  class Builder {
+   public:
+    // Register a provider with the registry. Can only be called after calling
+    // InitRegistry(). The key of the factory is extracted from factory
+    // parameter with method CertificateProviderFactory::name. If the same key
+    // is registered twice, an exception is raised.
+    void RegisterCertificateProviderFactory(
+        std::unique_ptr<CertificateProviderFactory> factory);
+
+    CertificateProviderRegistry Build();
+
+   private:
+    std::vector<std::unique_ptr<CertificateProviderFactory>> factories_;
+  };
+
+  CertificateProviderRegistry(const CertificateProviderRegistry&) = delete;
+  CertificateProviderRegistry& operator=(const CertificateProviderRegistry&) =
+      delete;
+  CertificateProviderRegistry(CertificateProviderRegistry&&) = default;
+  CertificateProviderRegistry& operator=(CertificateProviderRegistry&&) =
+      default;
+
   // Returns the factory for the plugin keyed by name.
-  static CertificateProviderFactory* LookupCertificateProviderFactory(
-      absl::string_view name);
+  CertificateProviderFactory* LookupCertificateProviderFactory(
+      absl::string_view name) const;
 
-  // The following methods are used to create and populate the
-  // CertificateProviderRegistry. NOT THREAD SAFE -- to be used only during
-  // global gRPC initialization and shutdown.
+ private:
+  CertificateProviderRegistry() = default;
 
-  // Global initialization of the registry.
-  static void InitRegistry();
-
-  // Global shutdown of the registry.
-  static void ShutdownRegistry();
-
-  // Register a provider with the registry. Can only be called after calling
-  // InitRegistry(). The key of the factory is extracted from factory
-  // parameter with method CertificateProviderFactory::name. If the same key
-  // is registered twice, an exception is raised.
-  static void RegisterCertificateProviderFactory(
-      std::unique_ptr<CertificateProviderFactory> factory);
+  std::vector<std::unique_ptr<CertificateProviderFactory>> factories_;
 };
 
 }  // namespace grpc_core
diff --git a/src/core/plugin_registry/grpc_plugin_registry_extra.cc b/src/core/plugin_registry/grpc_plugin_registry_extra.cc
index 9bc6545..8578414 100644
--- a/src/core/plugin_registry/grpc_plugin_registry_extra.cc
+++ b/src/core/plugin_registry/grpc_plugin_registry_extra.cc
@@ -26,22 +26,12 @@
 void XdsClientGlobalInit();
 void XdsClientGlobalShutdown();
 }  // namespace grpc_core
-void grpc_certificate_provider_registry_init(void);
-void grpc_certificate_provider_registry_shutdown(void);
-namespace grpc_core {
-void FileWatcherCertificateProviderInit();
-void FileWatcherCertificateProviderShutdown();
-}  // namespace grpc_core
 #endif
 
 void grpc_register_extra_plugins() {
 #ifndef GRPC_NO_XDS
   grpc_register_plugin(grpc_core::XdsClientGlobalInit,
                        grpc_core::XdsClientGlobalShutdown);
-  grpc_register_plugin(grpc_certificate_provider_registry_init,
-                       grpc_certificate_provider_registry_shutdown);
-  grpc_register_plugin(grpc_core::FileWatcherCertificateProviderInit,
-                       grpc_core::FileWatcherCertificateProviderShutdown);
 #endif
 }
 
@@ -59,6 +49,8 @@
 extern void RegisterCdsLbPolicy(CoreConfiguration::Builder* builder);
 extern void RegisterXdsClusterResolverLbPolicy(
     CoreConfiguration::Builder* builder);
+extern void RegisterFileWatcherCertificateProvider(
+    CoreConfiguration::Builder* builder);
 #endif
 void RegisterExtraFilters(CoreConfiguration::Builder* builder) {
   // Use builder to avoid unused-parameter warning.
@@ -75,6 +67,7 @@
   RegisterXdsClusterImplLbPolicy(builder);
   RegisterCdsLbPolicy(builder);
   RegisterXdsClusterResolverLbPolicy(builder);
+  RegisterFileWatcherCertificateProvider(builder);
 #endif
 }
 }  // namespace grpc_core
diff --git a/test/core/security/certificate_provider_registry_test.cc b/test/core/security/certificate_provider_registry_test.cc
index fa13b7b..4aeb4e2 100644
--- a/test/core/security/certificate_provider_registry_test.cc
+++ b/test/core/security/certificate_provider_registry_test.cc
@@ -60,23 +60,17 @@
 };
 
 TEST(CertificateProviderRegistryTest, Basic) {
-  CertificateProviderRegistry::InitRegistry();
+  CertificateProviderRegistry::Builder b;
   auto* fake_factory_1 = new FakeCertificateProviderFactory1;
   auto* fake_factory_2 = new FakeCertificateProviderFactory2;
-  CertificateProviderRegistry::RegisterCertificateProviderFactory(
+  b.RegisterCertificateProviderFactory(
       std::unique_ptr<CertificateProviderFactory>(fake_factory_1));
-  CertificateProviderRegistry::RegisterCertificateProviderFactory(
+  b.RegisterCertificateProviderFactory(
       std::unique_ptr<CertificateProviderFactory>(fake_factory_2));
-  EXPECT_EQ(
-      CertificateProviderRegistry::LookupCertificateProviderFactory("fake1"),
-      fake_factory_1);
-  EXPECT_EQ(
-      CertificateProviderRegistry::LookupCertificateProviderFactory("fake2"),
-      fake_factory_2);
-  EXPECT_EQ(
-      CertificateProviderRegistry::LookupCertificateProviderFactory("fake3"),
-      nullptr);
-  CertificateProviderRegistry::ShutdownRegistry();
+  auto r = b.Build();
+  EXPECT_EQ(r.LookupCertificateProviderFactory("fake1"), fake_factory_1);
+  EXPECT_EQ(r.LookupCertificateProviderFactory("fake2"), fake_factory_2);
+  EXPECT_EQ(r.LookupCertificateProviderFactory("fake3"), nullptr);
 }
 
 }  // namespace
diff --git a/test/core/xds/certificate_provider_store_test.cc b/test/core/xds/certificate_provider_store_test.cc
index 6925c51..1f1f4bb 100644
--- a/test/core/xds/certificate_provider_store_test.cc
+++ b/test/core/xds/certificate_provider_store_test.cc
@@ -22,6 +22,7 @@
 
 #include <gmock/gmock.h>
 
+#include "src/core/lib/config/core_configuration.h"
 #include "src/core/lib/gprpp/unique_type_name.h"
 #include "src/core/lib/security/certificate_provider/certificate_provider_registry.h"
 #include "test/core/util/test_config.h"
@@ -107,66 +108,84 @@
 TEST_F(CertificateProviderStoreTest, Basic) {
   // Set up factories. (Register only one of the factories.)
   auto* fake_factory_1 = new FakeCertificateProviderFactory1;
-  CertificateProviderRegistry::RegisterCertificateProviderFactory(
-      std::unique_ptr<CertificateProviderFactory>(fake_factory_1));
-  auto fake_factory_2 = absl::make_unique<FakeCertificateProviderFactory2>();
-  // Set up store
-  CertificateProviderStore::PluginDefinitionMap map = {
-      {"fake_plugin_1",
-       {"fake1", fake_factory_1->CreateCertificateProviderConfig(Json::Object(),
-                                                                 nullptr)}},
-      {"fake_plugin_2",
-       {"fake2", fake_factory_2->CreateCertificateProviderConfig(Json::Object(),
-                                                                 nullptr)}},
-      {"fake_plugin_3",
-       {"fake1", fake_factory_1->CreateCertificateProviderConfig(Json::Object(),
-                                                                 nullptr)}},
-  };
-  auto store = MakeOrphanable<CertificateProviderStore>(std::move(map));
-  // Test for creating certificate providers with known plugin configuration.
-  auto cert_provider_1 = store->CreateOrGetCertificateProvider("fake_plugin_1");
-  ASSERT_NE(cert_provider_1, nullptr);
-  auto cert_provider_3 = store->CreateOrGetCertificateProvider("fake_plugin_3");
-  ASSERT_NE(cert_provider_3, nullptr);
-  // Test for creating certificate provider with known plugin configuration but
-  // unregistered factory.
-  ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_2"), nullptr);
-  // Test for creating certificate provider with unknown plugin configuration.
-  ASSERT_EQ(store->CreateOrGetCertificateProvider("unknown"), nullptr);
-  // Test for getting previously created certificate providers.
-  ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_1"),
-            cert_provider_1);
-  ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_3"),
-            cert_provider_3);
-  // Release previously created certificate providers so that the store outlasts
-  // the certificate providers.
-  cert_provider_1.reset();
-  cert_provider_3.reset();
+  CoreConfiguration::RunWithSpecialConfiguration(
+      [=](CoreConfiguration::Builder* builder) {
+        builder->certificate_provider_registry()
+            ->RegisterCertificateProviderFactory(
+                std::unique_ptr<CertificateProviderFactory>(fake_factory_1));
+      },
+      [=] {
+        auto fake_factory_2 =
+            absl::make_unique<FakeCertificateProviderFactory2>();
+        // Set up store
+        CertificateProviderStore::PluginDefinitionMap map = {
+            {"fake_plugin_1",
+             {"fake1", fake_factory_1->CreateCertificateProviderConfig(
+                           Json::Object(), nullptr)}},
+            {"fake_plugin_2",
+             {"fake2", fake_factory_2->CreateCertificateProviderConfig(
+                           Json::Object(), nullptr)}},
+            {"fake_plugin_3",
+             {"fake1", fake_factory_1->CreateCertificateProviderConfig(
+                           Json::Object(), nullptr)}},
+        };
+        auto store = MakeOrphanable<CertificateProviderStore>(std::move(map));
+        // Test for creating certificate providers with known plugin
+        // configuration.
+        auto cert_provider_1 =
+            store->CreateOrGetCertificateProvider("fake_plugin_1");
+        ASSERT_NE(cert_provider_1, nullptr);
+        auto cert_provider_3 =
+            store->CreateOrGetCertificateProvider("fake_plugin_3");
+        ASSERT_NE(cert_provider_3, nullptr);
+        // Test for creating certificate provider with known plugin
+        // configuration but unregistered factory.
+        ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_2"),
+                  nullptr);
+        // Test for creating certificate provider with unknown plugin
+        // configuration.
+        ASSERT_EQ(store->CreateOrGetCertificateProvider("unknown"), nullptr);
+        // Test for getting previously created certificate providers.
+        ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_1"),
+                  cert_provider_1);
+        ASSERT_EQ(store->CreateOrGetCertificateProvider("fake_plugin_3"),
+                  cert_provider_3);
+        // Release previously created certificate providers so that the store
+        // outlasts the certificate providers.
+        cert_provider_1.reset();
+        cert_provider_3.reset();
+      });
 }
 
 TEST_F(CertificateProviderStoreTest, Multithreaded) {
   auto* fake_factory_1 = new FakeCertificateProviderFactory1;
-  CertificateProviderRegistry::RegisterCertificateProviderFactory(
-      std::unique_ptr<CertificateProviderFactory>(fake_factory_1));
-  CertificateProviderStore::PluginDefinitionMap map = {
-      {"fake_plugin_1",
-       {"fake1", fake_factory_1->CreateCertificateProviderConfig(Json::Object(),
-                                                                 nullptr)}}};
-  auto store = MakeOrphanable<CertificateProviderStore>(std::move(map));
-  // Test concurrent `CreateOrGetCertificateProvider()` with the same key.
-  std::vector<std::thread> threads;
-  threads.reserve(1000);
-  for (auto i = 0; i < 1000; i++) {
-    threads.emplace_back([&store]() {
-      for (auto i = 0; i < 10; ++i) {
-        ASSERT_NE(store->CreateOrGetCertificateProvider("fake_plugin_1"),
-                  nullptr);
-      }
-    });
-  }
-  for (auto& thread : threads) {
-    thread.join();
-  }
+  CoreConfiguration::RunWithSpecialConfiguration(
+      [=](CoreConfiguration::Builder* builder) {
+        builder->certificate_provider_registry()
+            ->RegisterCertificateProviderFactory(
+                std::unique_ptr<CertificateProviderFactory>(fake_factory_1));
+      },
+      [=] {
+        CertificateProviderStore::PluginDefinitionMap map = {
+            {"fake_plugin_1",
+             {"fake1", fake_factory_1->CreateCertificateProviderConfig(
+                           Json::Object(), nullptr)}}};
+        auto store = MakeOrphanable<CertificateProviderStore>(std::move(map));
+        // Test concurrent `CreateOrGetCertificateProvider()` with the same key.
+        std::vector<std::thread> threads;
+        threads.reserve(1000);
+        for (auto i = 0; i < 1000; i++) {
+          threads.emplace_back([&store]() {
+            for (auto i = 0; i < 10; ++i) {
+              ASSERT_NE(store->CreateOrGetCertificateProvider("fake_plugin_1"),
+                        nullptr);
+            }
+          });
+        }
+        for (auto& thread : threads) {
+          thread.join();
+        }
+      });
 }
 
 }  // namespace
diff --git a/test/core/xds/xds_bootstrap_test.cc b/test/core/xds/xds_bootstrap_test.cc
index 8da1b03..402760b 100644
--- a/test/core/xds/xds_bootstrap_test.cc
+++ b/test/core/xds/xds_bootstrap_test.cc
@@ -22,6 +22,7 @@
 
 #include "src/core/ext/xds/xds_bootstrap_grpc.h"
 #include "src/core/ext/xds/xds_client_grpc.h"
+#include "src/core/lib/config/core_configuration.h"
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/gpr/tmpfile.h"
 #include "src/core/lib/security/certificate_provider/certificate_provider_registry.h"
@@ -711,9 +712,14 @@
 int main(int argc, char** argv) {
   ::testing::InitGoogleTest(&argc, argv);
   grpc::testing::TestEnvironment env(&argc, argv);
+  grpc_core::CoreConfiguration::RegisterBuilder(
+      [](grpc_core::CoreConfiguration::Builder* builder) {
+        builder->certificate_provider_registry()
+            ->RegisterCertificateProviderFactory(
+                absl::make_unique<
+                    grpc_core::testing::FakeCertificateProviderFactory>());
+      });
   grpc_init();
-  grpc_core::CertificateProviderRegistry::RegisterCertificateProviderFactory(
-      absl::make_unique<grpc_core::testing::FakeCertificateProviderFactory>());
   int ret = RUN_ALL_TESTS();
   grpc_shutdown();
   return ret;
diff --git a/test/cpp/end2end/xds/xds_end2end_test.cc b/test/cpp/end2end/xds/xds_end2end_test.cc
index 4fa9208..9862085 100644
--- a/test/cpp/end2end/xds/xds_end2end_test.cc
+++ b/test/cpp/end2end/xds/xds_end2end_test.cc
@@ -68,6 +68,7 @@
 #include "src/core/lib/address_utils/parse_address.h"
 #include "src/core/lib/address_utils/sockaddr_utils.h"
 #include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/config/core_configuration.h"
 #include "src/core/lib/gpr/env.h"
 #include "src/core/lib/gpr/string.h"
 #include "src/core/lib/gpr/time_precise.h"
@@ -4050,14 +4051,21 @@
 #endif
   grpc::testing::FakeCertificateProvider::CertDataMapWrapper cert_data_map_1;
   grpc::testing::g_fake1_cert_data_map = &cert_data_map_1;
-  grpc_core::CertificateProviderRegistry::RegisterCertificateProviderFactory(
-      absl::make_unique<grpc::testing::FakeCertificateProviderFactory>(
-          "fake1", grpc::testing::g_fake1_cert_data_map));
   grpc::testing::FakeCertificateProvider::CertDataMapWrapper cert_data_map_2;
   grpc::testing::g_fake2_cert_data_map = &cert_data_map_2;
-  grpc_core::CertificateProviderRegistry::RegisterCertificateProviderFactory(
-      absl::make_unique<grpc::testing::FakeCertificateProviderFactory>(
-          "fake2", grpc::testing::g_fake2_cert_data_map));
+  grpc_core::CoreConfiguration::RegisterBuilder(
+      [](grpc_core::CoreConfiguration::Builder* builder) {
+        builder->certificate_provider_registry()
+            ->RegisterCertificateProviderFactory(
+                absl::make_unique<
+                    grpc::testing::FakeCertificateProviderFactory>(
+                    "fake1", grpc::testing::g_fake1_cert_data_map));
+        builder->certificate_provider_registry()
+            ->RegisterCertificateProviderFactory(
+                absl::make_unique<
+                    grpc::testing::FakeCertificateProviderFactory>(
+                    "fake2", grpc::testing::g_fake2_cert_data_map));
+      });
   grpc_init();
   grpc_core::XdsHttpFilterRegistry::RegisterFilter(
       absl::make_unique<grpc::testing::NoOpHttpFilter>(