diff --git a/src/ledger/bin/tests/cloud_provider/launcher/BUILD.gn b/src/ledger/bin/tests/cloud_provider/launcher/BUILD.gn
index 5bdb88f3a18417852462f4b7b22c7f51eb148531..9a7f3ae9c213c18a3dcdb53a8f1ba738147f8985 100644
--- a/src/ledger/bin/tests/cloud_provider/launcher/BUILD.gn
+++ b/src/ledger/bin/tests/cloud_provider/launcher/BUILD.gn
@@ -11,7 +11,9 @@ source_set("launcher") {
   ]
 
   public_deps = [
+    "//garnet/public/lib/callback",
     "//sdk/fidl/fuchsia.ledger.cloud",
+    "//sdk/fidl/fuchsia.sys",
     "//sdk/lib/fidl/cpp",
     "//sdk/lib/sys/cpp/testing:unit",
   ]
diff --git a/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.cc b/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.cc
index 979871a008f3902a37d7b6be7baa5b186cf66f21..2d65680c4c6f931259561e7f6fa27c56ac1fd72d 100644
--- a/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.cc
+++ b/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.cc
@@ -16,15 +16,44 @@ constexpr char kValidationTestsUrl[] =
     "#meta/cloud_provider_validation_tests.cmx";
 }  // namespace
 
+ValidationTestsLauncher::CloudProviderProxy::CloudProviderProxy(
+    fidl::InterfacePtr<fuchsia::ledger::cloud::CloudProvider> proxied,
+    fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider> request,
+    fuchsia::sys::ComponentControllerPtr controller)
+    : binding_(proxied.get(), std::move(request)),
+      proxied_(std::move(proxied)),
+      controller_(std::move(controller)) {
+  binding_.set_error_handler([this](zx_status_t status) {
+    if (on_empty_)
+      on_empty_();
+  });
+  proxied_.set_error_handler([this](zx_status_t status) {
+    if (on_empty_)
+      on_empty_();
+  });
+}
+
+ValidationTestsLauncher::CloudProviderProxy::~CloudProviderProxy(){};
+
+void ValidationTestsLauncher::CloudProviderProxy::set_on_empty(
+    fit::closure on_empty) {
+  on_empty_ = std::move(on_empty);
+}
+
 ValidationTestsLauncher::ValidationTestsLauncher(
     sys::ComponentContext* component_context,
-    fit::function<
-        void(fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
+    fit::function<fuchsia::sys::ComponentControllerPtr(
+        fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
         factory)
     : component_context_(component_context), factory_(std::move(factory)) {
   service_directory_provider_.AddService<fuchsia::ledger::cloud::CloudProvider>(
       [this](fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>
-                 request) { factory_(std::move(request)); });
+                 request) {
+        fidl::InterfacePtr<fuchsia::ledger::cloud::CloudProvider> proxied;
+        auto controller = factory_(proxied.NewRequest());
+        proxies_.emplace(std::move(proxied), std::move(request),
+                         std::move(controller));
+      });
 }
 
 void ValidationTestsLauncher::Run(const std::vector<std::string>& arguments,
diff --git a/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.h b/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.h
index 25a7cd472e8ad9cbdb9c389e68e5402a6f97cb5b..1ec062d4d2fd2449799a75f16fdafab0f047e524 100644
--- a/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.h
+++ b/src/ledger/bin/tests/cloud_provider/launcher/validation_tests_launcher.h
@@ -7,6 +7,7 @@
 
 #include <fuchsia/ledger/cloud/cpp/fidl.h>
 #include <fuchsia/sys/cpp/fidl.h>
+#include <lib/callback/auto_cleanable.h>
 #include <lib/sys/cpp/component_context.h>
 #include <lib/sys/cpp/testing/service_directory_provider.h>
 
@@ -21,10 +22,13 @@ class ValidationTestsLauncher {
   // The constructor.
   //
   // |factory| is called to produce instances of the cloud provider under test.
+  // It may return a component controller: when the cloud provider instance is
+  // not used anymore (ie. the other end of the interface request is closed),
+  // the component controller is closed, which terminates the cloud provider.
   ValidationTestsLauncher(
       sys::ComponentContext* component_context,
-      fit::function<
-          void(fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
+      fit::function<fuchsia::sys::ComponentControllerPtr(
+          fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
           factory);
 
   // Starts the tests.
@@ -36,13 +40,32 @@ class ValidationTestsLauncher {
            fit::function<void(int32_t)> callback);
 
  private:
+  // Proxies requests from |request| to |proxied|, and terminates the component
+  // controlled by |controller| when one of the ends closes the channel.
+  class CloudProviderProxy {
+   public:
+    CloudProviderProxy(
+        fidl::InterfacePtr<fuchsia::ledger::cloud::CloudProvider> proxied,
+        fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider> request,
+        fuchsia::sys::ComponentControllerPtr controller);
+    ~CloudProviderProxy();
+    void set_on_empty(fit::closure on_empty);
+
+   private:
+    fidl::Binding<fuchsia::ledger::cloud::CloudProvider> binding_;
+    fidl::InterfacePtr<fuchsia::ledger::cloud::CloudProvider> proxied_;
+    fuchsia::sys::ComponentControllerPtr controller_;
+    fit::closure on_empty_;
+  };
+
   sys::ComponentContext* const component_context_;
-  fit::function<void(
+  fit::function<fuchsia::sys::ComponentControllerPtr(
       fidl::InterfaceRequest<fuchsia::ledger::cloud::CloudProvider>)>
       factory_;
   sys::testing::ServiceDirectoryProvider service_directory_provider_;
   fuchsia::sys::ComponentControllerPtr validation_tests_controller_;
   fit::function<void(int32_t)> callback_;
+  callback::AutoCleanableSet<CloudProviderProxy> proxies_;
 };
 
 }  // namespace cloud_provider
diff --git a/src/ledger/cloud_provider_firestore/bin/validation/app.cc b/src/ledger/cloud_provider_firestore/bin/validation/app.cc
index c9e7ebf3da04eeb3af389cf02e92a534af67af93..da3db95e4b1c89116a8ef6e5afd314e85c810dda 100644
--- a/src/ledger/cloud_provider_firestore/bin/validation/app.cc
+++ b/src/ledger/cloud_provider_firestore/bin/validation/app.cc
@@ -61,6 +61,9 @@ int main(int argc, char** argv) {
         factory.MakeCloudProvider(
             cloud_provider_firestore::CloudProviderFactory::UserId::New(),
             std::move(request));
+        // Return null because we do not create individual instances of a
+        // component per request.
+        return nullptr;
       });
 
   int32_t return_code = -1;
diff --git a/src/ledger/cloud_provider_in_memory/bin/validation/launch.cc b/src/ledger/cloud_provider_in_memory/bin/validation/launch.cc
index 316371aad517e02773ae85ec3a0997b6800f663e..e6c2e0f6a86517bad520647d9939958c9466f62d 100644
--- a/src/ledger/cloud_provider_in_memory/bin/validation/launch.cc
+++ b/src/ledger/cloud_provider_in_memory/bin/validation/launch.cc
@@ -34,9 +34,12 @@ int main(int argc, char** argv) {
         auto cloud_provider_services = sys::ServiceDirectory::CreateWithRequest(
             &launch_info.directory_request);
 
-        component_launcher->CreateComponent(std::move(launch_info), nullptr);
+        fuchsia::sys::ComponentControllerPtr controller;
+        component_launcher->CreateComponent(std::move(launch_info),
+                                            controller.NewRequest());
         cloud_provider_services->Connect(
             std::move(request), fuchsia::ledger::cloud::CloudProvider::Name_);
+        return controller;
       });
 
   int32_t return_code = -1;