diff --git a/cmdline/CMakeLists.txt b/cmdline/CMakeLists.txt
index 049b1a190f479c5ae19bd282b0c4a07b3729bc58..adad349308206b740bc6a8ee2f9855932b35afda 100644
--- a/cmdline/CMakeLists.txt
+++ b/cmdline/CMakeLists.txt
@@ -32,7 +32,7 @@ include_directories(${CMAKE_BINARY_DIR}/eos_cta ${PROTOBUF3_INCLUDE_DIRS})
 #
 # cta-admin <admin_command> is the SSI version of "cta <admin_command>"
 #
-add_executable(cta-admin CtaAdminCmd.cpp CtaAdminCmdParse.cpp Configuration.cpp)
+add_executable(cta-admin CtaAdminCmd.cpp CtaAdminCmdParse.cpp)
 target_link_libraries(cta-admin XrdSsiPbEosCta XrdSsi-4 XrdSsiLib XrdUtils)
 set_property (TARGET cta-admin APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH})
 
@@ -43,7 +43,7 @@ set_property (TARGET cta-admin APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH})
 # Previously this was the eoscta_stub which was called by a script invoked by the EOS WFE.
 #
 find_package(cryptopp REQUIRED)
-add_executable(cta-wfe-test EosCtaStub.cpp Configuration.cpp)
+add_executable(cta-wfe-test EosCtaStub.cpp)
 target_link_libraries(cta-wfe-test cryptopp ctacommon XrdSsiPbEosCta XrdSsi-4 XrdSsiLib XrdUtils)
 set_property (TARGET cta-wfe-test APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH})
 
diff --git a/cmdline/Configuration.cpp b/cmdline/Configuration.cpp
deleted file mode 100644
index 00c2b191d70036d53bc5b50076a1316e8df2caf9..0000000000000000000000000000000000000000
--- a/cmdline/Configuration.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * The CERN Tape Archive (CTA) project
- * Copyright (C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "Configuration.hpp"
-
-#include <fstream>
-#include <stdexcept>
-#include <exception>
-	
-
-namespace cta {
-namespace cmdline {
-
-//------------------------------------------------------------------------------
-// s_fileFormat
-//------------------------------------------------------------------------------
-const char *Configuration::s_fileFormat = "<FQDN>:<port>";
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-Configuration::Configuration(
-  const std::string &filename):
-  filename(filename) {
-  frontendHostAndPort = parseFile(filename);
-}
-
-//------------------------------------------------------------------------------
-// parseFile
-//------------------------------------------------------------------------------
-std::string Configuration::parseFile(const std::string &filename) {
-  try {
-    std::ifstream file(filename);
-    if (!file) {
-      throw std::runtime_error("Failed to open ");
-    }
-    return parseStream(file);
-  } catch(std::exception &ex) {
-    throw std::runtime_error(std::string("Failed to parse configuration file " +
-                                         filename + ": " + ex.what()));
-  }
-}
-
-//------------------------------------------------------------------------------
-// parseFile
-//------------------------------------------------------------------------------
-std::string Configuration::getFrontendHostAndPort() throw() {
-  return frontendHostAndPort;
-}
-
-//------------------------------------------------------------------------------
-// parseStream
-//------------------------------------------------------------------------------
-std::string Configuration::parseStream(std::istream &inputStream) {
-  const std::list<std::string> lines = readNonEmptyLines(inputStream);
-
-  if(1 != lines.size()) {
-    throw std::runtime_error("There should only be one and only one line "
-                             "containing a frontend hostname and port");
-  }
-
-  const std::string frontendHostAndPort = lines.front();
-  std::vector<std::string> configurationLine;
-  splitString(frontendHostAndPort, ' ', configurationLine);
-  if(1 != configurationLine.size()) {
-    throw std::runtime_error(std::string("There should not be any space in the "
-                                         "host configuration: Correct"
-                                         " format is ") + s_fileFormat);
-  }
-  std::vector<std::string> components;
-  splitString(frontendHostAndPort, ':', components);
-  if(2 != components.size()) {
-    throw std::runtime_error(std::string("Port not found in the configuration:"
-                                         " Correct format is ") + s_fileFormat);
-  }
-  const std::string &hostname = components[0];
-  const std::string &port = components[1];
-  if(!onlyContainsNumerals(port)) {
-    throw std::runtime_error(std::string("Port must only contain numerals: "
-                                         "value=") + port);
-  }
-  if(4 > hostname.length()) {
-    throw std::runtime_error(std::string("Hostname too short: "
-                                         "value=") + hostname);
-  }
-  return frontendHostAndPort;
-}
-//-----------------------------------------------------------------------------
-// splitString
-//-----------------------------------------------------------------------------
-void Configuration::splitString(const std::string &str, const char separator,
-  std::vector<std::string> &result) {
-
-  if(str.empty()) {
-    return;
-  }
-
-  std::string::size_type beginIndex = 0;
-  std::string::size_type endIndex   = str.find(separator);
-
-  while(endIndex != std::string::npos) {
-    result.push_back(str.substr(beginIndex, endIndex - beginIndex));
-    beginIndex = ++endIndex;
-    endIndex = str.find(separator, endIndex);
-  }
-
-  // If no separator could not be found then simply append the whole input
-  // string to the result
-  if(endIndex == std::string::npos) {
-    result.push_back(str.substr(beginIndex, str.length()));
-  }
-}
-
-//------------------------------------------------------------------------------
-// onlyContainsNumerals
-//------------------------------------------------------------------------------
-bool Configuration::onlyContainsNumerals(const std::string &str) throw() {
-  for(std::string::const_iterator itor = str.begin(); itor != str.end();
-    itor++) {
-    if(*itor < '0' || *itor  > '9') {
-      return false;
-    }
-  }
-  return true;
-}
-
-//-----------------------------------------------------------------------------
-// trimString
-//-----------------------------------------------------------------------------
-std::string Configuration::trimString(const std::string &s) throw() {
-  const std::string& spaces="\t\n\v\f\r ";
-
-  // Find first non white character
-  size_t beginpos = s.find_first_not_of(spaces);
-  std::string::const_iterator it1;
-  if (std::string::npos != beginpos) {
-    it1 = beginpos + s.begin();
-  } else {
-    it1 = s.begin();
-  }
-
-  // Find last non white chararacter
-  std::string::const_iterator it2;
-  size_t endpos = s.find_last_not_of(spaces);
-  if (std::string::npos != endpos) {
-    it2 = endpos + 1 + s.begin();
-  } else {
-    it2 = s.end();
-  }
-
-  return std::string(it1, it2);
-}
-
-//------------------------------------------------------------------------------
-// readNonEmptyLines
-//------------------------------------------------------------------------------
-std::list<std::string> Configuration::readNonEmptyLines(std::istream &inputStream) {
-
-  std::list<std::string> lines;
-  std::string line;
-
-  while(std::getline(inputStream, line)) {
-    // Remove the newline character if there is one
-    {
-      const std::string::size_type newlinePos = line.find("\n");
-      if(newlinePos != std::string::npos) {
-        line = line.substr(0, newlinePos);
-      }
-    }
-
-    // If there is a comment, then remove it from the line
-    {
-      const std::string::size_type startOfComment = line.find("#");
-      if(startOfComment != std::string::npos) {
-        line = line.substr(0, startOfComment);
-      }
-    }
-
-    // Left and right trim the line of whitespace
-    line = Configuration::trimString(std::string(line));
-
-    // If the line is not empty
-    if(!line.empty()) {
-      lines.push_back(line);
-    }
-  }
-
-  return lines;
-}
-} // namesapce cmdline
-} // namespace cta
diff --git a/cmdline/Configuration.hpp b/cmdline/Configuration.hpp
deleted file mode 100644
index 1ae1c09f37aa714660f676dca3b89fc76be7bb8d..0000000000000000000000000000000000000000
--- a/cmdline/Configuration.hpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * The CERN Tape Archive (CTA) project
- * Copyright (C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include <istream>
-#include <list>
-#include <string>
-#include <vector>
-
-namespace cta {
-namespace cmdline {
-
-/**
- * A set of configuration details.
- */
-class Configuration {
-public:
-  
-  /**
-   * Constructor.
-   *
-   * @param filename The configuration file name.
-   */
-  Configuration(const std::string &filename);
-  
-private:
-  
-  /**
-   * The frontend hostname and port to connect.
-   */
-  std::string frontendHostAndPort;
-  
-  /**
-   * The configuration file name.
-   */
-  const std::string filename;
-
-  
-  /**
-   * Reads and parses the configuration information from the specified file.
-   *
-   * The input stream must contain one and only one configuration string.
-   *
-   * The format of the configuration string is:
-   *
-   *   <host>.cern.ch:<port>
-   *
-   * The file can contain multiple empty lines.
-   *
-   * The file can contain multiple comment lines where a comment
-   * line starts with optional whitespace and a hash character '#'.
-   *
-   * @param filename The name of the file containing the configuration
-   * information.
-   * @return The configuration information.
-   */
-  std::string parseFile(const std::string &filename);
-
-  /**
-   * Reads and parses the configuration information from the specified file.
-   *
-   * The input stream must contain one and only one configuration string.
-   *
-   * The format of the configuration string is:
-   *
-   *   <host>.cern.ch:<port>
-   *
-   * The file can contain multiple empty lines.
-   *
-   * The file can contain multiple comment lines where a comment
-   * line starts with optional whitespace and a hash character '#'.
-   *
-   * @param filename The name of the file containing the configuration
-   * information.
-   * @return The configuration information.
-   */
-  std::string parseStream(std::istream &inputStream);
-
-  /**
-   * Reads the entire contents of the specified stream and returns a list of the
-   * non-empty lines.
-   *
-   * A line is considered not empty if it contains characters that are not white
-   * space and are not part of a comment.
-   *
-   * @param is The input stream.
-   * @return A list of the non-empty lines.
-   */
-   std::list<std::string> readNonEmptyLines(std::istream &inputStream);
-   
-  /**
-   * Returns the result of trimming both left and right white-space from the
-   * specified string.
-   *
-   * @param s The string to be trimmed.
-   * @return The result of trimming the string.
-   */
-  std::string trimString(const std::string &s) throw();
-
-  /**
-   * Splits the specified string into a vector of strings using the specified
-   * separator.
-   *
-   * Please note that the string to be split is NOT modified.
-   *
-   * @param str The string to be split.
-   * @param separator The separator to be used to split the specified string.
-   * @param result The vector when the result of spliting the string will be
-   * stored.
-   */
-  void splitString(const std::string &str, const char separator, std::vector<std::string> &result);
-  
-  /**
-   * Returns true if the specified string only contains numerals else false.
-   *
-   * @return True if the specified string only contains numerals else false.
-   */
-  static bool onlyContainsNumerals(const std::string &str) throw();
-  
-  /**
-   * Human readable description of the format of the database
-   * login/configuration file.
-   */
-  static const char *s_fileFormat;
-  
-public:
-  /**
-   * Returns the value of the configuration parameters.
-   *
-   * @return The frontend host and port from the configuration.
-   */
-  std::string getFrontendHostAndPort() throw();
-
-}; // class Configuration
-
-} // namespace cmdline
-} // namespace cta
diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp
index 5f69ead0858f92c5e452c95ce3370e50c2ef1df7..be788cacd84fe4f0edcaa3f33afa145640c97f77 100644
--- a/cmdline/CtaAdminCmd.cpp
+++ b/cmdline/CtaAdminCmd.cpp
@@ -24,7 +24,6 @@
 #include <XrdSsiPbLog.hpp>
 #include <XrdSsiPbIStreamBuffer.hpp>
 
-#include "cmdline/Configuration.hpp"
 #include "CtaAdminCmd.hpp"
 
 
@@ -147,15 +146,14 @@ void CtaAdminCmd::send() const
       throwUsage(ex.what());
    }
 
-   // Get socket address of CTA Frontend endpoint
-   cta::cmdline::Configuration cliConf("/etc/cta/cta-cli.conf");
-   std::string endpoint = cliConf.getFrontendHostAndPort();
-
    // Set configuration options
-   XrdSsiPb::Config config;
+   XrdSsiPb::Config config("/etc/cta/cta-cli.conf", "cta");
+   config.set("resource", "/ctafrontend");
    config.set("response_bufsize", StreamBufferSize);         // default value = 1024 bytes
    config.set("request_timeout", DefaultRequestTimeout);     // default value = 10s
-   config.getEnv("request_timeout", "XRD_REQUESTTIMEOUT");   // environment variable can override default
+
+   // Allow environment variables to override config file
+   config.getEnv("request_timeout", "XRD_REQUESTTIMEOUT");
 
    // If XRDDEBUG=1, switch on all logging
    if(getenv("XRDDEBUG")) {
@@ -165,7 +163,7 @@ void CtaAdminCmd::send() const
    config.getEnv("log", "XrdSsiPbLogLevel");
 
    // Obtain a Service Provider
-   XrdSsiPbServiceType cta_service(endpoint, Resource, config);
+   XrdSsiPbServiceType cta_service(config);
 
    // Send the Request to the Service and get a Response
    cta::xrd::Response response;
diff --git a/cmdline/CtaAdminCmd.hpp b/cmdline/CtaAdminCmd.hpp
index 1f0fa2f7daea8a84f6075299c38d8f64170ccec1..2207b8ae72546825cf92a90abf5b5d1bdeda3b6a 100644
--- a/cmdline/CtaAdminCmd.hpp
+++ b/cmdline/CtaAdminCmd.hpp
@@ -63,7 +63,6 @@ private:
    /*
     * Member variables
     */
-   const std::string Resource              = "/ctafrontend";    //!< XRootD SSI Resource name
    const std::string StreamBufferSize      = "1024";            //!< Buffer size for Data/Stream Responses
    const std::string DefaultRequestTimeout = "10";              //!< Default Request Timeout. Can be overridden by
                                                                 //!< XRD_REQUESTTIMEOUT environment variable.
diff --git a/cmdline/EosCtaStub.cpp b/cmdline/EosCtaStub.cpp
index 1210401bc2e04d1657806ceaa0a12ec107b2b4da..de885362a42864923c7f23a9553fbf77f3bf4d54 100644
--- a/cmdline/EosCtaStub.cpp
+++ b/cmdline/EosCtaStub.cpp
@@ -25,7 +25,6 @@
 #include <XrdSsiPbLog.hpp>
 
 #include "common/dataStructures/FrontendReturnCode.hpp"
-#include "cmdline/Configuration.hpp"
 #include "CtaFrontendApi.hpp"
 
 
@@ -259,13 +258,12 @@ int exceptionThrowingMain(int argc, const char *const *const argv)
    // Parse the command line arguments: fill the Notification fields
    fillNotification(notification, argc, argv);
 
-   // Get socket address of CTA Frontend endpoint
-   cta::cmdline::Configuration cliConf("/etc/cta/cta-cli.conf");
-   std::string endpoint = cliConf.getFrontendHostAndPort();
-
    // Set configuration options
-   XrdSsiPb::Config config;
-   config.getEnv("request_timeout", "XRD_REQUESTTIMEOUT");   // environment variable can override default
+   XrdSsiPb::Config config("/etc/cta/cta-cli.conf", "cta");
+   config.set("resource", "/ctafrontend");
+
+   // Allow environment variables to override config file
+   config.getEnv("request_timeout", "XRD_REQUESTTIMEOUT");
 
    // If XRDDEBUG=1, switch on all logging
    if(getenv("XRDDEBUG")) {
@@ -275,8 +273,7 @@ int exceptionThrowingMain(int argc, const char *const *const argv)
    config.getEnv("log", "XrdSsiPbLogLevel");
 
    // Obtain a Service Provider
-   std::string resource("/ctafrontend");
-   XrdSsiPbServiceType cta_service(endpoint, resource);
+   XrdSsiPbServiceType cta_service(config);
 
    // Send the Request to the Service and get a Response
    cta::xrd::Response response;
diff --git a/cmdline/cta-cli.conf b/cmdline/cta-cli.conf
index 28cac16b4acfc1b4797490770ca7c5c4b9eddcc2..6ccae00b5d10637f4678cfcdf3b9038ddf38e153 100644
--- a/cmdline/cta-cli.conf
+++ b/cmdline/cta-cli.conf
@@ -1,2 +1,2 @@
 # The CTA frontend address in the form <FQDN>:<TCPPort>
-<host>.cern.ch:10955
+cta.endpoint <host>.cern.ch:10955
diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface
index ceb96f82573becd825370fed391eae0b0bcf2dc5..8251f8652a956ec7df6e51e853aeeebf1d333ea0 160000
--- a/xrootd-ssi-protobuf-interface
+++ b/xrootd-ssi-protobuf-interface
@@ -1 +1 @@
-Subproject commit ceb96f82573becd825370fed391eae0b0bcf2dc5
+Subproject commit 8251f8652a956ec7df6e51e853aeeebf1d333ea0