diff --git a/include/dbus_privileges.hpp b/include/dbus_privileges.hpp
index fca4a13..07a1216 100644
--- a/include/dbus_privileges.hpp
+++ b/include/dbus_privileges.hpp
@@ -6,9 +6,11 @@
 #include "http_response.hpp"
 #include "logging.hpp"
 #include "routing/baserule.hpp"
+#include "user_role_map.hpp"
 #include "utils/dbus_utils.hpp"
 
 #include <boost/url/format.hpp>
+#include <sdbusplus/bus/match.hpp>
 #include <sdbusplus/unpack_properties.hpp>
 
 #include <memory>
@@ -16,82 +18,6 @@
 
 namespace crow
 {
-// Populate session with user information.
-inline bool
-    populateUserInfo(Request& req,
-                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                     const dbus::utility::DBusPropertiesMap& userInfoMap)
-{
-    const std::string* userRolePtr = nullptr;
-    const bool* remoteUser = nullptr;
-    const bool* passwordExpired = nullptr;
-    const std::vector<std::string>* userGroups = nullptr;
-
-    const bool success = sdbusplus::unpackPropertiesNoThrow(
-        redfish::dbus_utils::UnpackErrorPrinter(), userInfoMap, "UserPrivilege",
-        userRolePtr, "RemoteUser", remoteUser, "UserPasswordExpired",
-        passwordExpired, "UserGroups", userGroups);
-
-    if (!success)
-    {
-        BMCWEB_LOG_ERROR("Failed to unpack user properties.");
-        asyncResp->res.result(
-            boost::beast::http::status::internal_server_error);
-        return false;
-    }
-
-    if (req.session == nullptr)
-    {
-        return false;
-    }
-
-    if (userRolePtr != nullptr)
-    {
-        req.session->userRole = *userRolePtr;
-        BMCWEB_LOG_DEBUG("userName = {} userRole = {}", req.session->username,
-                         *userRolePtr);
-    }
-
-    if (remoteUser == nullptr)
-    {
-        BMCWEB_LOG_ERROR("RemoteUser property missing or wrong type");
-        asyncResp->res.result(
-            boost::beast::http::status::internal_server_error);
-        return false;
-    }
-    bool expired = false;
-    if (passwordExpired == nullptr)
-    {
-        if (!*remoteUser)
-        {
-            BMCWEB_LOG_ERROR("UserPasswordExpired property is expected for"
-                             " local user but is missing or wrong type");
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
-            return false;
-        }
-    }
-    else
-    {
-        expired = *passwordExpired;
-    }
-
-    // Set isConfigureSelfOnly based on D-Bus results.  This
-    // ignores the results from both pamAuthenticateUser and the
-    // value from any previous use of this session.
-    req.session->isConfigureSelfOnly = expired;
-
-    if (userGroups != nullptr)
-    {
-        // Populate session with user groups.
-        for (const auto& userGroup : *userGroups)
-        {
-            req.session->userGroups.emplace_back(userGroup);
-        }
-    }
-
-    return true;
-}
 
 inline bool
     isUserPrivileged(Request& req,
@@ -128,44 +54,10 @@
         return false;
     }
 
-    req.userRole = req.session->userRole;
     return true;
 }
 
 template <typename CallbackFn>
-void afterGetUserInfo(Request& req,
-                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                      BaseRule& rule, CallbackFn&& callback,
-                      const boost::system::error_code& ec,
-                      const dbus::utility::DBusPropertiesMap& userInfoMap)
-{
-    if (ec)
-    {
-        BMCWEB_LOG_ERROR("GetUserInfo failed...");
-        asyncResp->res.result(
-            boost::beast::http::status::internal_server_error);
-        return;
-    }
-
-    if (!populateUserInfo(req, asyncResp, userInfoMap))
-    {
-        BMCWEB_LOG_ERROR("Failed to populate user information");
-        asyncResp->res.result(
-            boost::beast::http::status::internal_server_error);
-        return;
-    }
-
-    if (!isUserPrivileged(req, asyncResp, rule))
-    {
-        // User is not privileged
-        BMCWEB_LOG_ERROR("Insufficient Privilege");
-        asyncResp->res.result(boost::beast::http::status::forbidden);
-        return;
-    }
-    callback(req);
-}
-
-template <typename CallbackFn>
 void validatePrivilege(Request& req,
                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                        BaseRule& rule, CallbackFn&& callback)
@@ -175,15 +67,29 @@
         return;
     }
     std::string username = req.session->username;
-    crow::connections::systemBus->async_method_call(
-        [&req, asyncResp, &rule, callback(std::forward<CallbackFn>(callback))](
-            const boost::system::error_code& ec,
-            const dbus::utility::DBusPropertiesMap& userInfoMap) mutable {
-        afterGetUserInfo(req, asyncResp, rule,
-                         std::forward<CallbackFn>(callback), ec, userInfoMap);
-        },
-        "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
-        "xyz.openbmc_project.User.Manager", "GetUserInfo", username);
+    UserFields props =
+        UserRoleMap::getInstance().getUserRole(req.session->username);
+    if (props.userRole)
+    {
+        req.session->userRole = props.userRole.value_or("");
+    }
+    if (props.passwordExpired)
+    {
+        req.session->isConfigureSelfOnly = *props.passwordExpired;
+    }
+    if (props.userGroups)
+    {
+        req.session->userGroups = std::move(*props.userGroups);
+    }
+
+    if (!isUserPrivileged(req, asyncResp, rule))
+    {
+        // User is not privileged
+        BMCWEB_LOG_WARNING("Insufficient Privilege");
+        asyncResp->res.result(boost::beast::http::status::forbidden);
+        return;
+    }
+    callback(req);
 }
 
 } // namespace crow
diff --git a/include/sessions.hpp b/include/sessions.hpp
index cb7f78e..90a1de9 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -2,10 +2,12 @@
 
 #include "logging.hpp"
 #include "ossl_random.hpp"
+#include "user_role_map.hpp"
 #include "utility.hpp"
 #include "utils/ip_utils.hpp"
 
 #include <nlohmann/json.hpp>
+#include <sdbusplus/message.hpp>
 
 #include <algorithm>
 #include <csignal>
@@ -256,11 +258,15 @@
             }
         }
 
+        std::string userRole = crow::UserRoleMap::getInstance()
+                                   .getUserRole(username)
+                                   .userRole.value_or("");
+
         auto session = std::make_shared<UserSession>(UserSession{
             uniqueId, sessionToken, std::string(username), csrfToken, clientId,
             redfish::ip_util::toString(clientIp),
             std::chrono::steady_clock::now(), persistence, false,
-            isConfigureSelfOnly});
+            isConfigureSelfOnly, userRole});
         auto it = authTokens.emplace(sessionToken, session);
         // Only need to write to disk if session isn't about to be destroyed.
         needWrite = persistence == PersistenceType::TIMEOUT;
diff --git a/include/user_role_map.hpp b/include/user_role_map.hpp
new file mode 100644
index 0000000..ce2f97e
--- /dev/null
+++ b/include/user_role_map.hpp
@@ -0,0 +1,278 @@
+#pragma once
+
+#include "dbus_utility.hpp"
+#include "logging.hpp"
+#include "utils/dbus_utils.hpp"
+
+#include <boost/container/flat_map.hpp>
+#include <boost/url/format.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/unpack_properties.hpp>
+
+#include <functional>
+#include <memory>
+#include <optional>
+#include <string>
+#include <variant>
+#include <vector>
+
+namespace crow
+{
+struct UserFields
+{
+    std::optional<std::string> userRole;
+    std::optional<bool> remote;
+    std::optional<bool> passwordExpired;
+    std::optional<std::vector<std::string>> userGroups;
+};
+
+struct UserRoleMap
+{
+  public:
+    static UserRoleMap& getInstance()
+    {
+        static UserRoleMap userRoleMap;
+        return userRoleMap;
+    }
+
+    UserFields getUserRole(std::string_view name)
+    {
+        auto it = roleMap.find(name);
+        if (it == roleMap.end())
+        {
+            BMCWEB_LOG_ERROR("User name {} is not found in the UserRoleMap.",
+                             name);
+            return {};
+        }
+        return it->second;
+    }
+    UserRoleMap(const UserRoleMap&) = delete;
+    UserRoleMap& operator=(const UserRoleMap&) = delete;
+    UserRoleMap(UserRoleMap&&) = delete;
+    UserRoleMap& operator=(UserRoleMap&&) = delete;
+    ~UserRoleMap() = default;
+
+  private:
+    static UserFields extractUserRole(
+        const dbus::utility::DBusInteracesMap& interfacesProperties)
+    {
+        UserFields fields;
+        for (const auto& interface : interfacesProperties)
+        {
+            for (const auto& property : interface.second)
+            {
+                if (property.first == "UserPrivilege")
+                {
+                    const std::string* role =
+                        std::get_if<std::string>(&property.second);
+                    if (role != nullptr)
+                    {
+                        fields.userRole = *role;
+                    }
+                }
+                else if (property.first == "UserGroups")
+                {
+                    const std::vector<std::string>* groups =
+                        std::get_if<std::vector<std::string>>(&property.second);
+                    if (groups != nullptr)
+                    {
+                        fields.userGroups = *groups;
+                    }
+                }
+                else if (property.first == "UserPasswordExpired")
+                {
+                    const bool* expired = std::get_if<bool>(&property.second);
+                    if (expired != nullptr)
+                    {
+                        fields.passwordExpired = *expired;
+                    }
+                }
+                else if (property.first == "RemoteUser")
+                {
+                    const bool* remote = std::get_if<bool>(&property.second);
+                    if (remote != nullptr)
+                    {
+                        fields.remote = *remote;
+                    }
+                }
+            }
+        }
+        return fields;
+    }
+
+    void userAdded(sdbusplus::message::message& m)
+    {
+        BMCWEB_LOG_DEBUG("User Added");
+        sdbusplus::message::object_path objPath;
+        dbus::utility::DBusInteracesMap interfacesProperties;
+
+        try
+        {
+            m.read(objPath, interfacesProperties);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            BMCWEB_LOG_ERROR(
+                "Failed to parse user add signal.ERROR={}REPLY_SIG={}",
+                e.what(), m.get_signature());
+            return;
+        }
+        BMCWEB_LOG_DEBUG("obj path = {}", objPath.str);
+
+        std::string name = objPath.filename();
+        if (name.empty())
+        {
+            return;
+        }
+        UserFields role = extractUserRole(interfacesProperties);
+
+        // Insert the newly added user name and the role
+        auto res = roleMap.emplace(name, role);
+        if (!res.second)
+        {
+            BMCWEB_LOG_ERROR(
+                "Insertion of the user=\"{}\" in the roleMap failed.", name);
+            return;
+        }
+    }
+
+    void userRemoved(sdbusplus::message::message& m)
+    {
+        BMCWEB_LOG_DEBUG("User Removed");
+        sdbusplus::message::object_path objPath;
+
+        try
+        {
+            m.read(objPath);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            BMCWEB_LOG_ERROR("Failed to parse user delete signal.");
+            BMCWEB_LOG_ERROR("ERROR={}REPLY_SIG={}", e.what(),
+                             m.get_signature());
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG("obj path = {}", objPath.str);
+
+        std::string name = objPath.filename();
+        if (name.empty())
+        {
+            return;
+        }
+
+        roleMap.erase(name);
+    }
+
+    void userPropertiesChanged(sdbusplus::message::message& m)
+    {
+        BMCWEB_LOG_DEBUG("Properties Changed");
+        std::string interface;
+        dbus::utility::DBusPropertiesMap changedProperties;
+        try
+        {
+            m.read(interface, changedProperties);
+        }
+        catch (const sdbusplus::exception::SdBusError& e)
+        {
+            BMCWEB_LOG_ERROR("Failed to parse user properties changed signal.");
+            BMCWEB_LOG_ERROR("ERROR={}REPLY_SIG={}", e.what(),
+                             m.get_signature());
+            return;
+        }
+        dbus::utility::DBusInteracesMap map;
+        map.emplace_back("xyz.openbmc_project.User.Attributes",
+                         changedProperties);
+        const sdbusplus::message::object_path path(m.get_path());
+
+        BMCWEB_LOG_DEBUG("Object Path = \"{}\"", path.str);
+
+        std::string user = path.filename();
+        if (user.empty())
+        {
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG("User Name = \"{}\"", user);
+
+        UserFields role = extractUserRole(map);
+
+        auto userProps = roleMap.find(user);
+        if (userProps == roleMap.end())
+        {
+            BMCWEB_LOG_CRITICAL("User {} not found", user);
+            return;
+        }
+        if (role.userRole)
+        {
+            userProps->second.userRole = role.userRole;
+        }
+        if (role.remote)
+        {
+            userProps->second.remote = role.remote;
+        }
+        if (role.userGroups)
+        {
+            userProps->second.userGroups = role.userGroups;
+        }
+        if (role.passwordExpired)
+        {
+            userProps->second.passwordExpired = role.passwordExpired;
+        }
+    }
+
+    void onGetManagedObjects(
+        const boost::system::error_code& ec,
+        const dbus::utility::ManagedObjectType& managedObjects)
+    {
+        if (ec)
+        {
+            BMCWEB_LOG_DEBUG("User manager call failed, ignoring");
+            return;
+        }
+
+        for (const auto& managedObj : managedObjects)
+        {
+            std::string name =
+                sdbusplus::message::object_path(managedObj.first).filename();
+            if (name.empty())
+            {
+                continue;
+            }
+            UserFields role = extractUserRole(managedObj.second);
+            roleMap.emplace(name, role);
+        }
+    }
+
+    static constexpr const char* userObjPath = "/xyz/openbmc_project/user";
+
+    UserRoleMap() :
+        userAddedSignal(
+            *crow::connections::systemBus,
+            sdbusplus::bus::match::rules::interfacesAdded(userObjPath),
+            std::bind_front(&UserRoleMap::userAdded, this)),
+        userRemovedSignal(
+            *crow::connections::systemBus,
+            sdbusplus::bus::match::rules::interfacesRemoved(userObjPath),
+            std::bind_front(&UserRoleMap::userRemoved, this)),
+        userPropertiesChangedSignal(
+            *crow::connections::systemBus,
+            sdbusplus::bus::match::rules::propertiesChangedNamespace(
+                userObjPath, "xyz.openbmc_project.User.Attributes"),
+            std::bind_front(&UserRoleMap::userPropertiesChanged, this))
+    {
+        dbus::utility::getManagedObjects(
+            "xyz.openbmc_project.User.Manager", {userObjPath},
+            std::bind_front(&UserRoleMap::onGetManagedObjects, this));
+    }
+
+    // Map of username -> role
+    boost::container::flat_map<std::string, UserFields, std::less<>> roleMap;
+
+    // These MUST be last, otherwise destruction can cause race conditions.
+    sdbusplus::bus::match_t userAddedSignal;
+    sdbusplus::bus::match_t userRemovedSignal;
+    sdbusplus::bus::match_t userPropertiesChangedSignal;
+};
+
+} // namespace crow
