diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp
index 4d9d977316ec6c77adac0a393020a073b2bf5e9f..7d9d5bf7cf7d7564ba809803ebe741eabda5434f 100644
--- a/cmdline/CtaAdminCmd.cpp
+++ b/cmdline/CtaAdminCmd.cpp
@@ -83,9 +83,10 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const
          case Data::kLpaSummary:    std::cout << Log::DumpProtobuf(&record.lpa_summary());  break;
          case Data::kLprItem:       std::cout << Log::DumpProtobuf(&record.lpr_item());     break;
          case Data::kLprSummary:    std::cout << Log::DumpProtobuf(&record.lpr_summary());  break;
-         case Data::kTplsItem:      std::cout << Log::DumpProtobuf(&record.tpls_item());    break;
-         case Data::kTalsItem:      std::cout << Log::DumpProtobuf(&record.tals_item());    break;
          case Data::kRelsItem:      std::cout << Log::DumpProtobuf(&record.rels_item());    break;
+         case Data::kRmrlsItem:     std::cout << Log::DumpProtobuf(&record.rmrls_item());   break;
+         case Data::kTalsItem:      std::cout << Log::DumpProtobuf(&record.tals_item());    break;
+         case Data::kTplsItem:      std::cout << Log::DumpProtobuf(&record.tpls_item());    break;
          default:
             throw std::runtime_error("Received invalid stream data from CTA Frontend.");
       }
@@ -104,9 +105,10 @@ void IStreamBuffer<cta::xrd::Data>::DataCallback(cta::xrd::Data record) const
          case Data::kLpaSummary:    formattedText.print(record.lpa_summary());  break;
          case Data::kLprItem:       formattedText.print(record.lpr_item());     break;
          case Data::kLprSummary:    formattedText.print(record.lpr_summary());  break;
-         case Data::kTplsItem:      formattedText.print(record.tpls_item());    break;
-         case Data::kTalsItem:      formattedText.print(record.tals_item());    break;
          case Data::kRelsItem:      formattedText.print(record.rels_item());    break;
+         case Data::kRmrlsItem:     formattedText.print(record.rmrls_item());   break;
+         case Data::kTalsItem:      formattedText.print(record.tals_item());    break;
+         case Data::kTplsItem:      formattedText.print(record.tpls_item());    break;
          default:
             throw std::runtime_error("Received invalid stream data from CTA Frontend.");
    }
@@ -253,6 +255,7 @@ void CtaAdminCmd::send() const
             case HeaderType::LISTPENDINGRETRIEVES:         formattedText.printListPendingRetrievesHeader(); break;
             case HeaderType::LISTPENDINGRETRIEVES_SUMMARY: formattedText.printListPendingRetrievesSummaryHeader(); break;
             case HeaderType::REPACK_LS:                    formattedText.printRepackLsHeader(); break;
+            case HeaderType::REQUESTERMOUNTRULE_LS:        formattedText.printRequesterMountRuleLsHeader(); break;
             case HeaderType::TAPE_LS:                      formattedText.printTapeLsHeader(); break;
             case HeaderType::TAPEPOOL_LS:                  formattedText.printTapePoolLsHeader(); break;
             case HeaderType::NONE:
diff --git a/cmdline/CtaAdminTextFormatter.cpp b/cmdline/CtaAdminTextFormatter.cpp
index f009a87c0db108fad108784f7a5d513ec1aca437..56f7765c0ecbc05b1ac86e65cee811e7373cf7a2 100644
--- a/cmdline/CtaAdminTextFormatter.cpp
+++ b/cmdline/CtaAdminTextFormatter.cpp
@@ -541,6 +541,37 @@ void TextFormatter::print(const RepackLsItem &rels_item) {
   );
 }
 
+void TextFormatter::printRequesterMountRuleLsHeader() {
+  push_back("HEADER");
+  push_back(
+    "instance",
+    "username",
+    "policy",
+    "c.user",
+    "c.host",
+    "c.time",
+    "m.user",
+    "m.host",
+    "m.time",
+    "comment"
+  );
+}
+
+void TextFormatter::print(const RequesterMountRuleLsItem &rmrls_item) {
+  push_back(
+    rmrls_item.disk_instance(),
+    rmrls_item.requester_mount_rule(),
+    rmrls_item.mount_policy(),
+    rmrls_item.creation_log().username(),
+    rmrls_item.creation_log().host(),
+    timeToStr(rmrls_item.creation_log().time()),
+    rmrls_item.last_modification_log().username(),
+    rmrls_item.last_modification_log().host(),
+    timeToStr(rmrls_item.last_modification_log().time()),
+    rmrls_item.comment()
+  );
+}
+
 void TextFormatter::printTapeLsHeader() {
   push_back("HEADER");
   push_back(
diff --git a/cmdline/CtaAdminTextFormatter.hpp b/cmdline/CtaAdminTextFormatter.hpp
index 2edbeeb6cb2e5adbc38ed0184edf076c08ece859..b2a902dd9c6217a48d365f0c6d8bcf6b286ae1b4 100644
--- a/cmdline/CtaAdminTextFormatter.hpp
+++ b/cmdline/CtaAdminTextFormatter.hpp
@@ -57,6 +57,7 @@ public:
   void printListPendingRetrievesHeader();
   void printListPendingRetrievesSummaryHeader();
   void printRepackLsHeader();
+  void printRequesterMountRuleLsHeader();
   void printTapeLsHeader();
   void printTapePoolLsHeader();
    
@@ -74,6 +75,7 @@ public:
   void print(const ListPendingRetrievesItem &lpr_item);
   void print(const ListPendingRetrievesSummary &lpr_summary);
   void print(const RepackLsItem &rels_item);
+  void print(const RequesterMountRuleLsItem &rmrls_item);
   void print(const TapeLsItem &tals_item);
   void print(const TapePoolLsItem &tpls_item);
 
diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
index 49bf6d796548a382d477ed1fa311d660e9c6649f..a2ee1f7aa4f1914e34df63252d622c4280ccf15d 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
@@ -34,6 +34,7 @@ using XrdSsiPb::PbException;
 #include "XrdCtaGroupMountRuleLs.hpp"
 #include "XrdCtaListPendingQueue.hpp"
 #include "XrdCtaRepackLs.hpp"
+#include "XrdCtaRequesterMountRuleLs.hpp"
 #include "XrdCtaTapeLs.hpp"
 #include "XrdCtaTapePoolLs.hpp"
 
@@ -211,7 +212,7 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons
                processRequesterMountRule_Rm(response);
                break;
             case cmd_pair(AdminCmd::CMD_REQUESTERMOUNTRULE, AdminCmd::SUBCMD_LS):
-               processRequesterMountRule_Ls(response);
+               processRequesterMountRule_Ls(response, stream);
                break;
             case cmd_pair(AdminCmd::CMD_SHOWQUEUES, AdminCmd::SUBCMD_NONE):
                processShowQueues(response);
@@ -1289,35 +1290,14 @@ void RequestMessage::processRequesterMountRule_Rm(cta::xrd::Response &response)
 
 
 
-void RequestMessage::processRequesterMountRule_Ls(cta::xrd::Response &response)
+void RequestMessage::processRequesterMountRule_Ls(cta::xrd::Response &response, XrdSsiStream* &stream)
 {
-   using namespace cta::admin;
-
-   std::stringstream cmdlineOutput;
-
-   std::list<cta::common::dataStructures::RequesterMountRule> list = m_catalogue.getRequesterMountRules();
+  using namespace cta::admin;
 
-   if(!list.empty())
-   {
-      std::vector<std::vector<std::string>> responseTable;
-      std::vector<std::string> header = {
-         "instance","username","policy","c.user","c.host","c.time","m.user","m.host","m.time","comment"
-      };
-      if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header);    
-      for(auto it = list.cbegin(); it != list.cend(); it++) {
-         std::vector<std::string> currentRow;
-         currentRow.push_back(it->diskInstance);
-         currentRow.push_back(it->name);
-         currentRow.push_back(it->mountPolicy);
-         addLogInfoToResponseRow(currentRow, it->creationLog, it->lastModificationLog);
-         currentRow.push_back(it->comment);
-         responseTable.push_back(currentRow);
-      }
-      cmdlineOutput << formatResponse(responseTable);
-   }
+  stream = new RequesterMountRuleLsStream(*this, m_catalogue, m_scheduler);
 
-   response.set_message_txt(cmdlineOutput.str());
-   response.set_type(cta::xrd::Response::RSP_SUCCESS);
+  response.set_show_header(HeaderType::REQUESTERMOUNTRULE_LS);
+  response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }
 
 
diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.hpp b/xroot_plugins/XrdSsiCtaRequestMessage.hpp
index 744e6a07f685a6c68028cb6d58b7886b9e167762..06fcc39900ba4518ed171d7980a65d6a24748c53 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.hpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.hpp
@@ -176,7 +176,6 @@ private:
    void processRequesterMountRule_Add(cta::xrd::Response &response);
    void processRequesterMountRule_Ch (cta::xrd::Response &response);
    void processRequesterMountRule_Rm (cta::xrd::Response &response);
-   void processRequesterMountRule_Ls (cta::xrd::Response &response);
    void processShowQueues            (cta::xrd::Response &response);
    void processStorageClass_Add      (cta::xrd::Response &response);
    void processStorageClass_Ch       (cta::xrd::Response &response);
@@ -208,6 +207,7 @@ private:
    admincmdstream_t processGroupMountRule_Ls;
    admincmdstream_t processListPendingArchives;
    admincmdstream_t processListPendingRetrieves;
+   admincmdstream_t processRequesterMountRule_Ls;
    admincmdstream_t processTapePool_Ls;
    admincmdstream_t processTape_Ls;
    admincmdstream_t processRepack_Ls;
diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface
index 9eb104df34892f5d7a6a251faae6399dd1f7f5c1..5ff5030b66c1a5737258af799e75a799285cf970 160000
--- a/xrootd-ssi-protobuf-interface
+++ b/xrootd-ssi-protobuf-interface
@@ -1 +1 @@
-Subproject commit 9eb104df34892f5d7a6a251faae6399dd1f7f5c1
+Subproject commit 5ff5030b66c1a5737258af799e75a799285cf970