diff --git a/docker/.env.example b/docker/.env.example
index 2f9e232886b0e96b6f4a9ecef3ce61fe5ac6ffc2..a6cabe65587ccaddf4e3341aa4f1dabd51ac9f00 100644
--- a/docker/.env.example
+++ b/docker/.env.example
@@ -279,4 +279,12 @@ GID='1000'
 # AGENT_SERPLY_API_KEY=
 
 #------ SearXNG ----------- https://github.com/searxng/searxng
-# AGENT_SEARXNG_API_URL=
\ No newline at end of file
+# AGENT_SEARXNG_API_URL=
+
+###########################################
+######## Other Configurations ############
+###########################################
+
+# Disable viewing chat history from the UI and frontend APIs.
+# See https://docs.anythingllm.com/configuration#disable-view-chat-history for more information.
+# DISABLE_VIEW_CHAT_HISTORY=1
\ No newline at end of file
diff --git a/frontend/src/components/CanViewChatHistory/index.jsx b/frontend/src/components/CanViewChatHistory/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..44e75353147fc3cbd9df21ce2907c2bf7aaf24a0
--- /dev/null
+++ b/frontend/src/components/CanViewChatHistory/index.jsx
@@ -0,0 +1,50 @@
+import { useEffect, useState } from "react";
+import { FullScreenLoader } from "@/components/Preloader";
+import System from "@/models/system";
+import paths from "@/utils/paths";
+
+/**
+ * Protects the view from system set ups who cannot view chat history.
+ * If the user cannot view chat history, they are redirected to the home page.
+ * @param {React.ReactNode} children
+ */
+export function CanViewChatHistory({ children }) {
+  const { loading, viewable } = useCanViewChatHistory();
+  if (loading) return <FullScreenLoader />;
+  if (!viewable) {
+    window.location.href = paths.home();
+    return <FullScreenLoader />;
+  }
+
+  return <>{children}</>;
+}
+
+/**
+ * Provides the `viewable` state to the children.
+ * @returns {React.ReactNode}
+ */
+export function CanViewChatHistoryProvider({ children }) {
+  const { loading, viewable } = useCanViewChatHistory();
+  if (loading) return null;
+  return <>{children({ viewable })}</>;
+}
+
+/**
+ * Hook that fetches the can view chat history state from local storage or the system settings.
+ * @returns {Promise<{viewable: boolean, error: string | null}>}
+ */
+export function useCanViewChatHistory() {
+  const [loading, setLoading] = useState(true);
+  const [viewable, setViewable] = useState(false);
+
+  useEffect(() => {
+    async function fetchViewable() {
+      const { viewable } = await System.fetchCanViewChatHistory();
+      setViewable(viewable);
+      setLoading(false);
+    }
+    fetchViewable();
+  }, []);
+
+  return { loading, viewable };
+}
diff --git a/frontend/src/components/SettingsSidebar/MenuOption/index.jsx b/frontend/src/components/SettingsSidebar/MenuOption/index.jsx
index 38be4883b90a615f7d740b23b8598a566761ae3d..3834549ea9f501a6f1c8ba32ca0302b9fcac7219 100644
--- a/frontend/src/components/SettingsSidebar/MenuOption/index.jsx
+++ b/frontend/src/components/SettingsSidebar/MenuOption/index.jsx
@@ -149,17 +149,32 @@ function useIsExpanded({
   return { isExpanded, setIsExpanded };
 }
 
+/**
+ * Checks if the child options are visible to the user.
+ * This hides the top level options if the child options are not visible
+ * for either the users permissions or the child options hidden prop is set to true by other means.
+ * If all child options return false for `isVisible` then the parent option will not be visible as well.
+ * @param {object} user - The user object.
+ * @param {array} childOptions - The child options.
+ * @returns {boolean} - True if the child options are visible, false otherwise.
+ */
 function hasVisibleOptions(user = null, childOptions = []) {
   if (!Array.isArray(childOptions) || childOptions?.length === 0) return false;
 
-  function isVisible({ roles = [], user = null, flex = false }) {
+  function isVisible({
+    roles = [],
+    user = null,
+    flex = false,
+    hidden = false,
+  }) {
+    if (hidden) return false;
     if (!flex && !roles.includes(user?.role)) return false;
     if (flex && !!user && !roles.includes(user?.role)) return false;
     return true;
   }
 
   return childOptions.some((opt) =>
-    isVisible({ roles: opt.roles, user, flex: opt.flex })
+    isVisible({ roles: opt.roles, user, flex: opt.flex, hidden: opt.hidden })
   );
 }
 
diff --git a/frontend/src/components/SettingsSidebar/index.jsx b/frontend/src/components/SettingsSidebar/index.jsx
index 367b21ab652ced5faec69ac553a24e19b698e7d5..46eba5db9cf99a01eee02b20db03624c68feb683 100644
--- a/frontend/src/components/SettingsSidebar/index.jsx
+++ b/frontend/src/components/SettingsSidebar/index.jsx
@@ -21,6 +21,7 @@ import { useTranslation } from "react-i18next";
 import showToast from "@/utils/toast";
 import System from "@/models/system";
 import Option from "./MenuOption";
+import { CanViewChatHistoryProvider } from "../CanViewChatHistory";
 
 export default function SettingsSidebar() {
   const { t } = useTranslation();
@@ -208,151 +209,157 @@ function SupportEmail() {
 }
 
 const SidebarOptions = ({ user = null, t }) => (
-  <>
-    <Option
-      btnText={t("settings.ai-providers")}
-      icon={<Gear className="h-5 w-5 flex-shrink-0" />}
-      user={user}
-      childOptions={[
-        {
-          btnText: t("settings.llm"),
-          href: paths.settings.llmPreference(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.vector-database"),
-          href: paths.settings.vectorDatabase(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.embedder"),
-          href: paths.settings.embedder.modelPreference(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.text-splitting"),
-          href: paths.settings.embedder.chunkingPreference(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.voice-speech"),
-          href: paths.settings.audioPreference(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.transcription"),
-          href: paths.settings.transcriptionPreference(),
-          flex: true,
-          roles: ["admin"],
-        },
-      ]}
-    />
-    <Option
-      btnText={t("settings.admin")}
-      icon={<UserCircleGear className="h-5 w-5 flex-shrink-0" />}
-      user={user}
-      childOptions={[
-        {
-          btnText: t("settings.users"),
-          href: paths.settings.users(),
-          roles: ["admin", "manager"],
-        },
-        {
-          btnText: t("settings.workspaces"),
-          href: paths.settings.workspaces(),
-          roles: ["admin", "manager"],
-        },
-        {
-          btnText: t("settings.workspace-chats"),
-          href: paths.settings.chats(),
-          flex: true,
-          roles: ["admin", "manager"],
-        },
-        {
-          btnText: t("settings.invites"),
-          href: paths.settings.invites(),
-          roles: ["admin", "manager"],
-        },
-      ]}
-    />
-    <Option
-      btnText={t("settings.agent-skills")}
-      icon={<Robot className="h-5 w-5 flex-shrink-0" />}
-      href={paths.settings.agentSkills()}
-      user={user}
-      flex={true}
-      roles={["admin"]}
-    />
-    <Option
-      btnText={t("settings.customization")}
-      icon={<PencilSimpleLine className="h-5 w-5 flex-shrink-0" />}
-      href={paths.settings.appearance()}
-      user={user}
-      flex={true}
-      roles={["admin", "manager"]}
-    />
-    <Option
-      btnText={t("settings.tools")}
-      icon={<Toolbox className="h-5 w-5 flex-shrink-0" />}
-      user={user}
-      childOptions={[
-        {
-          btnText: t("settings.embed-chats"),
-          href: paths.settings.embedChats(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.embeds"),
-          href: paths.settings.embedSetup(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.event-logs"),
-          href: paths.settings.logs(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.api-keys"),
-          href: paths.settings.apiKeys(),
-          flex: true,
-          roles: ["admin"],
-        },
-        {
-          btnText: t("settings.browser-extension"),
-          href: paths.settings.browserExtension(),
-          flex: true,
-          roles: ["admin", "manager"],
-        },
-      ]}
-    />
-    <Option
-      btnText={t("settings.security")}
-      icon={<Nut className="h-5 w-5 flex-shrink-0" />}
-      href={paths.settings.security()}
-      user={user}
-      flex={true}
-      roles={["admin", "manager"]}
-      hidden={user?.role}
-    />
-    <HoldToReveal key="exp_features">
-      <Option
-        btnText={t("settings.experimental-features")}
-        icon={<Flask className="h-5 w-5 flex-shrink-0" />}
-        href={paths.settings.experimental()}
-        user={user}
-        flex={true}
-        roles={["admin"]}
-      />
-    </HoldToReveal>
-  </>
+  <CanViewChatHistoryProvider>
+    {({ viewable: canViewChatHistory }) => (
+      <>
+        <Option
+          btnText={t("settings.ai-providers")}
+          icon={<Gear className="h-5 w-5 flex-shrink-0" />}
+          user={user}
+          childOptions={[
+            {
+              btnText: t("settings.llm"),
+              href: paths.settings.llmPreference(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.vector-database"),
+              href: paths.settings.vectorDatabase(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.embedder"),
+              href: paths.settings.embedder.modelPreference(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.text-splitting"),
+              href: paths.settings.embedder.chunkingPreference(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.voice-speech"),
+              href: paths.settings.audioPreference(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.transcription"),
+              href: paths.settings.transcriptionPreference(),
+              flex: true,
+              roles: ["admin"],
+            },
+          ]}
+        />
+        <Option
+          btnText={t("settings.admin")}
+          icon={<UserCircleGear className="h-5 w-5 flex-shrink-0" />}
+          user={user}
+          childOptions={[
+            {
+              btnText: t("settings.users"),
+              href: paths.settings.users(),
+              roles: ["admin", "manager"],
+            },
+            {
+              btnText: t("settings.workspaces"),
+              href: paths.settings.workspaces(),
+              roles: ["admin", "manager"],
+            },
+            {
+              hidden: !canViewChatHistory,
+              btnText: t("settings.workspace-chats"),
+              href: paths.settings.chats(),
+              flex: true,
+              roles: ["admin", "manager"],
+            },
+            {
+              btnText: t("settings.invites"),
+              href: paths.settings.invites(),
+              roles: ["admin", "manager"],
+            },
+          ]}
+        />
+        <Option
+          btnText={t("settings.agent-skills")}
+          icon={<Robot className="h-5 w-5 flex-shrink-0" />}
+          href={paths.settings.agentSkills()}
+          user={user}
+          flex={true}
+          roles={["admin"]}
+        />
+        <Option
+          btnText={t("settings.customization")}
+          icon={<PencilSimpleLine className="h-5 w-5 flex-shrink-0" />}
+          href={paths.settings.appearance()}
+          user={user}
+          flex={true}
+          roles={["admin", "manager"]}
+        />
+        <Option
+          btnText={t("settings.tools")}
+          icon={<Toolbox className="h-5 w-5 flex-shrink-0" />}
+          user={user}
+          childOptions={[
+            {
+              hidden: !canViewChatHistory,
+              btnText: t("settings.embed-chats"),
+              href: paths.settings.embedChats(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.embeds"),
+              href: paths.settings.embedSetup(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.event-logs"),
+              href: paths.settings.logs(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.api-keys"),
+              href: paths.settings.apiKeys(),
+              flex: true,
+              roles: ["admin"],
+            },
+            {
+              btnText: t("settings.browser-extension"),
+              href: paths.settings.browserExtension(),
+              flex: true,
+              roles: ["admin", "manager"],
+            },
+          ]}
+        />
+        <Option
+          btnText={t("settings.security")}
+          icon={<Nut className="h-5 w-5 flex-shrink-0" />}
+          href={paths.settings.security()}
+          user={user}
+          flex={true}
+          roles={["admin", "manager"]}
+          hidden={user?.role}
+        />
+        <HoldToReveal key="exp_features">
+          <Option
+            btnText={t("settings.experimental-features")}
+            icon={<Flask className="h-5 w-5 flex-shrink-0" />}
+            href={paths.settings.experimental()}
+            user={user}
+            flex={true}
+            roles={["admin"]}
+          />
+        </HoldToReveal>
+      </>
+    )}
+  </CanViewChatHistoryProvider>
 );
 
 function HoldToReveal({ children, holdForMs = 3_000 }) {
diff --git a/frontend/src/models/system.js b/frontend/src/models/system.js
index 9c8b1f7df1f7c1f468af991087eaf1424c5875e4..1039d6de25c0e25dc9b2755699c95884f1f1ba1c 100644
--- a/frontend/src/models/system.js
+++ b/frontend/src/models/system.js
@@ -9,6 +9,7 @@ const System = {
     footerIcons: "anythingllm_footer_links",
     supportEmail: "anythingllm_support_email",
     customAppName: "anythingllm_custom_app_name",
+    canViewChatHistory: "anythingllm_can_view_chat_history",
   },
   ping: async function () {
     return await fetch(`${API_BASE}/ping`)
@@ -675,6 +676,36 @@ const System = {
         return false;
       });
   },
+
+  /**
+   * Fetches the can view chat history state from local storage or the system settings.
+   * Notice: This is an instance setting that cannot be changed via the UI and it is cached
+   * in local storage for 24 hours.
+   * @returns {Promise<{viewable: boolean, error: string | null}>}
+   */
+  fetchCanViewChatHistory: async function () {
+    const cache = window.localStorage.getItem(
+      this.cacheKeys.canViewChatHistory
+    );
+    const { viewable, lastFetched } = cache
+      ? safeJsonParse(cache, { viewable: false, lastFetched: 0 })
+      : { viewable: false, lastFetched: 0 };
+
+    // Since this is an instance setting that cannot be changed via the UI,
+    // we can cache it in local storage for a day and if the admin changes it,
+    // they should instruct the users to clear local storage.
+    if (typeof viewable === "boolean" && Date.now() - lastFetched < 8.64e7)
+      return { viewable, error: null };
+
+    const res = await System.keys();
+    const isViewable = res?.DisableViewChatHistory === false;
+
+    window.localStorage.setItem(
+      this.cacheKeys.canViewChatHistory,
+      JSON.stringify({ viewable: isViewable, lastFetched: Date.now() })
+    );
+    return { viewable: isViewable, error: null };
+  },
   experimentalFeatures: {
     liveSync: LiveDocumentSync,
     agentPlugins: AgentPlugins,
diff --git a/frontend/src/pages/GeneralSettings/Chats/index.jsx b/frontend/src/pages/GeneralSettings/Chats/index.jsx
index a2385aa2d240707d4a0eae06a4a5452d6e222cb9..01dc36122e2ad6d15d51af2775033d6bdb9f1b06 100644
--- a/frontend/src/pages/GeneralSettings/Chats/index.jsx
+++ b/frontend/src/pages/GeneralSettings/Chats/index.jsx
@@ -11,6 +11,7 @@ import { CaretDown, Download, Sparkle, Trash } from "@phosphor-icons/react";
 import { saveAs } from "file-saver";
 import { useTranslation } from "react-i18next";
 import paths from "@/utils/paths";
+import { CanViewChatHistory } from "@/components/CanViewChatHistory";
 
 const exportOptions = {
   csv: {
@@ -106,7 +107,8 @@ export default function WorkspaceChats() {
 
   useEffect(() => {
     async function fetchChats() {
-      const { chats: _chats, hasPages = false } = await System.chats(offset);
+      const { chats: _chats = [], hasPages = false } =
+        await System.chats(offset);
       setChats(_chats);
       setCanNext(hasPages);
       setLoading(false);
@@ -115,85 +117,87 @@ export default function WorkspaceChats() {
   }, [offset]);
 
   return (
-    <div className="w-screen h-screen overflow-hidden bg-sidebar flex">
-      <Sidebar />
-      <div
-        style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
-        className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
-      >
-        <div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
-          <div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
-            <div className="flex gap-x-4 items-center">
-              <p className="text-lg leading-6 font-bold text-white">
-                {t("recorded.title")}
-              </p>
-              <div className="relative">
-                <button
-                  ref={openMenuButton}
-                  onClick={toggleMenu}
-                  className="flex items-center gap-x-2 px-4 py-1 rounded-lg bg-primary-button hover:text-white text-xs font-semibold hover:bg-secondary shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
-                >
-                  <Download size={18} weight="bold" />
-                  {t("recorded.export")}
-                  <CaretDown size={18} weight="bold" />
-                </button>
-                <div
-                  ref={menuRef}
-                  className={`${
-                    showMenu ? "slide-down" : "slide-up hidden"
-                  } z-20 w-fit rounded-lg absolute top-full right-0 bg-secondary mt-2 shadow-md`}
-                >
-                  <div className="py-2">
-                    {Object.entries(exportOptions).map(([key, data]) => (
-                      <button
-                        key={key}
-                        onClick={() => {
-                          handleDumpChats(key);
-                          setShowMenu(false);
-                        }}
-                        className="w-full text-left px-4 py-2 text-white text-sm hover:bg-[#3D4147]"
-                      >
-                        {data.name}
-                      </button>
-                    ))}
-                  </div>
-                </div>
-              </div>
-              {chats.length > 0 && (
-                <>
+    <CanViewChatHistory>
+      <div className="w-screen h-screen overflow-hidden bg-sidebar flex">
+        <Sidebar />
+        <div
+          style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
+          className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
+        >
+          <div className="flex flex-col w-full px-1 md:pl-6 md:pr-[50px] md:py-6 py-16">
+            <div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
+              <div className="flex gap-x-4 items-center">
+                <p className="text-lg leading-6 font-bold text-white">
+                  {t("recorded.title")}
+                </p>
+                <div className="relative">
                   <button
-                    onClick={handleClearAllChats}
-                    className="flex items-center gap-x-2 px-4 py-1 border hover:border-transparent border-white/40 text-white/40 rounded-lg bg-transparent hover:text-white text-xs font-semibold hover:bg-red-500 shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
+                    ref={openMenuButton}
+                    onClick={toggleMenu}
+                    className="flex items-center gap-x-2 px-4 py-1 rounded-lg bg-primary-button hover:text-white text-xs font-semibold hover:bg-secondary shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
                   >
-                    <Trash size={18} weight="bold" />
-                    Clear Chats
+                    <Download size={18} weight="bold" />
+                    {t("recorded.export")}
+                    <CaretDown size={18} weight="bold" />
                   </button>
-                  <a
-                    href={paths.orderFineTune()}
-                    className="flex items-center gap-x-2 px-4 py-1 border hover:border-transparent border-yellow-300 text-yellow-300/80 rounded-lg bg-transparent hover:text-white text-xs font-semibold hover:bg-yellow-300/75 shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
+                  <div
+                    ref={menuRef}
+                    className={`${
+                      showMenu ? "slide-down" : "slide-up hidden"
+                    } z-20 w-fit rounded-lg absolute top-full right-0 bg-secondary mt-2 shadow-md`}
                   >
-                    <Sparkle size={18} weight="bold" />
-                    Order Fine-Tune Model
-                  </a>
-                </>
-              )}
+                    <div className="py-2">
+                      {Object.entries(exportOptions).map(([key, data]) => (
+                        <button
+                          key={key}
+                          onClick={() => {
+                            handleDumpChats(key);
+                            setShowMenu(false);
+                          }}
+                          className="w-full text-left px-4 py-2 text-white text-sm hover:bg-[#3D4147]"
+                        >
+                          {data.name}
+                        </button>
+                      ))}
+                    </div>
+                  </div>
+                </div>
+                {chats.length > 0 && (
+                  <>
+                    <button
+                      onClick={handleClearAllChats}
+                      className="flex items-center gap-x-2 px-4 py-1 border hover:border-transparent border-white/40 text-white/40 rounded-lg bg-transparent hover:text-white text-xs font-semibold hover:bg-red-500 shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
+                    >
+                      <Trash size={18} weight="bold" />
+                      Clear Chats
+                    </button>
+                    <a
+                      href={paths.orderFineTune()}
+                      className="flex items-center gap-x-2 px-4 py-1 border hover:border-transparent border-yellow-300 text-yellow-300/80 rounded-lg bg-transparent hover:text-white text-xs font-semibold hover:bg-yellow-300/75 shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
+                    >
+                      <Sparkle size={18} weight="bold" />
+                      Order Fine-Tune Model
+                    </a>
+                  </>
+                )}
+              </div>
+              <p className="text-xs leading-[18px] font-base text-white text-opacity-60">
+                {t("recorded.description")}
+              </p>
             </div>
-            <p className="text-xs leading-[18px] font-base text-white text-opacity-60">
-              {t("recorded.description")}
-            </p>
+            <ChatsContainer
+              loading={loading}
+              chats={chats}
+              setChats={setChats}
+              offset={offset}
+              setOffset={setOffset}
+              canNext={canNext}
+              t={t}
+            />
           </div>
-          <ChatsContainer
-            loading={loading}
-            chats={chats}
-            setChats={setChats}
-            offset={offset}
-            setOffset={setOffset}
-            canNext={canNext}
-            t={t}
-          />
         </div>
       </div>
-    </div>
+    </CanViewChatHistory>
   );
 }
 
diff --git a/frontend/src/pages/GeneralSettings/EmbedChats/index.jsx b/frontend/src/pages/GeneralSettings/EmbedChats/index.jsx
index 82cb261aa1e52f7e8aacc3a18fc45c06b8165c6b..60e4db1743eae1afa6f0d49e55142375940adb0f 100644
--- a/frontend/src/pages/GeneralSettings/EmbedChats/index.jsx
+++ b/frontend/src/pages/GeneralSettings/EmbedChats/index.jsx
@@ -11,6 +11,7 @@ import { CaretDown, Download } from "@phosphor-icons/react";
 import showToast from "@/utils/toast";
 import { saveAs } from "file-saver";
 import System from "@/models/system";
+import { CanViewChatHistory } from "@/components/CanViewChatHistory";
 
 const exportOptions = {
   csv: {
@@ -88,59 +89,61 @@ export default function EmbedChats() {
   }, []);
 
   return (
-    <div className="w-screen h-screen overflow-hidden bg-sidebar flex">
-      <Sidebar />
-      <div
-        style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
-        className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
-      >
-        <div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
-          <div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
-            <div className="flex gap-x-4 items-center">
-              <p className="text-lg leading-6 font-bold text-white">
-                {t("embed-chats.title")}
-              </p>
-              <div className="relative">
-                <button
-                  ref={openMenuButton}
-                  onClick={toggleMenu}
-                  className="flex items-center gap-x-2 px-4 py-1 rounded-lg bg-primary-button hover:text-white text-xs font-semibold hover:bg-secondary shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
-                >
-                  <Download size={18} weight="bold" />
-                  {t("embed-chats.export")}
-                  <CaretDown size={18} weight="bold" />
-                </button>
-                <div
-                  ref={menuRef}
-                  className={`${
-                    showMenu ? "slide-down" : "slide-up hidden"
-                  } z-20 w-fit rounded-lg absolute top-full right-0 bg-secondary mt-2 shadow-md`}
-                >
-                  <div className="py-2">
-                    {Object.entries(exportOptions).map(([key, data]) => (
-                      <button
-                        key={key}
-                        onClick={() => {
-                          handleDumpChats(key);
-                          setShowMenu(false);
-                        }}
-                        className="w-full text-left px-4 py-2 text-white text-sm hover:bg-[#3D4147]"
-                      >
-                        {data.name}
-                      </button>
-                    ))}
+    <CanViewChatHistory>
+      <div className="w-screen h-screen overflow-hidden bg-sidebar flex">
+        <Sidebar />
+        <div
+          style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
+          className="relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll"
+        >
+          <div className="flex flex-col w-full px-1 md:pl-6 md:pr-[86px] md:py-6 py-16">
+            <div className="w-full flex flex-col gap-y-1 pb-6 border-white border-b-2 border-opacity-10">
+              <div className="flex gap-x-4 items-center">
+                <p className="text-lg leading-6 font-bold text-white">
+                  {t("embed-chats.title")}
+                </p>
+                <div className="relative">
+                  <button
+                    ref={openMenuButton}
+                    onClick={toggleMenu}
+                    className="flex items-center gap-x-2 px-4 py-1 rounded-lg bg-primary-button hover:text-white text-xs font-semibold hover:bg-secondary shadow-[0_4px_14px_rgba(0,0,0,0.25)] h-[34px] w-fit"
+                  >
+                    <Download size={18} weight="bold" />
+                    {t("embed-chats.export")}
+                    <CaretDown size={18} weight="bold" />
+                  </button>
+                  <div
+                    ref={menuRef}
+                    className={`${
+                      showMenu ? "slide-down" : "slide-up hidden"
+                    } z-20 w-fit rounded-lg absolute top-full right-0 bg-secondary mt-2 shadow-md`}
+                  >
+                    <div className="py-2">
+                      {Object.entries(exportOptions).map(([key, data]) => (
+                        <button
+                          key={key}
+                          onClick={() => {
+                            handleDumpChats(key);
+                            setShowMenu(false);
+                          }}
+                          className="w-full text-left px-4 py-2 text-white text-sm hover:bg-[#3D4147]"
+                        >
+                          {data.name}
+                        </button>
+                      ))}
+                    </div>
                   </div>
                 </div>
               </div>
+              <p className="text-xs leading-[18px] font-base text-white text-opacity-60">
+                {t("embed-chats.description")}
+              </p>
             </div>
-            <p className="text-xs leading-[18px] font-base text-white text-opacity-60">
-              {t("embed-chats.description")}
-            </p>
+            <ChatsContainer />
           </div>
-          <ChatsContainer />
         </div>
       </div>
-    </div>
+    </CanViewChatHistory>
   );
 }
 
diff --git a/server/.env.example b/server/.env.example
index 3f60b0e5bbf9d270c1f79cdda205aae0e7b1635d..f2d16b310b7f75f962086cd37e34e1b89afbdc60 100644
--- a/server/.env.example
+++ b/server/.env.example
@@ -268,4 +268,12 @@ TTS_PROVIDER="native"
 # AGENT_SERPLY_API_KEY=
 
 #------ SearXNG ----------- https://github.com/searxng/searxng
-# AGENT_SEARXNG_API_URL=
\ No newline at end of file
+# AGENT_SEARXNG_API_URL=
+
+###########################################
+######## Other Configurations ############
+###########################################
+
+# Disable viewing chat history from the UI and frontend APIs.
+# See https://docs.anythingllm.com/configuration#disable-view-chat-history for more information.
+# DISABLE_VIEW_CHAT_HISTORY=1
\ No newline at end of file
diff --git a/server/endpoints/embedManagement.js b/server/endpoints/embedManagement.js
index 7ebab23e7be3574e5fd2b79c02019670f1bdb628..8bee4dd75b4fb8ecd29faf673898e8eee272a844 100644
--- a/server/endpoints/embedManagement.js
+++ b/server/endpoints/embedManagement.js
@@ -1,7 +1,6 @@
 const { EmbedChats } = require("../models/embedChats");
 const { EmbedConfig } = require("../models/embedConfig");
 const { EventLogs } = require("../models/eventLogs");
-const { Workspace } = require("../models/workspace");
 const { reqBody, userFromSession } = require("../utils/http");
 const { validEmbedConfigId } = require("../utils/middleware/embedMiddleware");
 const {
@@ -9,6 +8,9 @@ const {
   ROLES,
 } = require("../utils/middleware/multiUserProtected");
 const { validatedRequest } = require("../utils/middleware/validatedRequest");
+const {
+  chatHistoryViewable,
+} = require("../utils/middleware/chatHistoryViewable");
 
 function embedManagementEndpoints(app) {
   if (!app) return;
@@ -90,7 +92,7 @@ function embedManagementEndpoints(app) {
 
   app.post(
     "/embed/chats",
-    [validatedRequest, flexUserRoleValid([ROLES.admin])],
+    [chatHistoryViewable, validatedRequest, flexUserRoleValid([ROLES.admin])],
     async (request, response) => {
       try {
         const { offset = 0, limit = 20 } = reqBody(request);
diff --git a/server/endpoints/system.js b/server/endpoints/system.js
index ccdb50ec85e64bfbdfcd5f4e8e6b9474c7293400..5e631b2f3f2647a9629f2c08ae08a71651a01701 100644
--- a/server/endpoints/system.js
+++ b/server/endpoints/system.js
@@ -50,6 +50,9 @@ const {
 const { SlashCommandPresets } = require("../models/slashCommandsPresets");
 const { EncryptionManager } = require("../utils/EncryptionManager");
 const { BrowserExtensionApiKey } = require("../models/browserExtensionApiKey");
+const {
+  chatHistoryViewable,
+} = require("../utils/middleware/chatHistoryViewable");
 
 function systemEndpoints(app) {
   if (!app) return;
@@ -961,7 +964,11 @@ function systemEndpoints(app) {
 
   app.post(
     "/system/workspace-chats",
-    [validatedRequest, flexUserRoleValid([ROLES.admin, ROLES.manager])],
+    [
+      chatHistoryViewable,
+      validatedRequest,
+      flexUserRoleValid([ROLES.admin, ROLES.manager]),
+    ],
     async (request, response) => {
       try {
         const { offset = 0, limit = 20 } = reqBody(request);
@@ -1001,7 +1008,11 @@ function systemEndpoints(app) {
 
   app.get(
     "/system/export-chats",
-    [validatedRequest, flexUserRoleValid([ROLES.manager, ROLES.admin])],
+    [
+      chatHistoryViewable,
+      validatedRequest,
+      flexUserRoleValid([ROLES.manager, ROLES.admin]),
+    ],
     async (request, response) => {
       try {
         const { type = "jsonl", chatType = "workspace" } = request.query;
diff --git a/server/models/systemSettings.js b/server/models/systemSettings.js
index c69794b48f0b8b77754f845670c13cd6c08cefea..e5de593766639a3c6b1c153c5927a91bee273d04 100644
--- a/server/models/systemSettings.js
+++ b/server/models/systemSettings.js
@@ -246,6 +246,13 @@ const SystemSettings = {
       AgentSerplyApiKey: !!process.env.AGENT_SERPLY_API_KEY || null,
       AgentSearXNGApiUrl: process.env.AGENT_SEARXNG_API_URL || null,
       AgentTavilyApiKey: !!process.env.AGENT_TAVILY_API_KEY || null,
+
+      // --------------------------------------------------------
+      // Compliance Settings
+      // --------------------------------------------------------
+      // Disable View Chat History for the whole instance.
+      DisableViewChatHistory:
+        "DISABLE_VIEW_CHAT_HISTORY" in process.env || false,
     };
   },
 
diff --git a/server/utils/helpers/updateENV.js b/server/utils/helpers/updateENV.js
index 294214a0b7d63b42df1c328ec955a5d2a017b7c6..202ffcd99122704d7052edbe27c281c77b7acc8d 100644
--- a/server/utils/helpers/updateENV.js
+++ b/server/utils/helpers/updateENV.js
@@ -886,6 +886,8 @@ function dumpENV() {
     "ENABLE_HTTPS",
     "HTTPS_CERT_PATH",
     "HTTPS_KEY_PATH",
+    // Other Configuration Keys
+    "DISABLE_VIEW_CHAT_HISTORY",
   ];
 
   // Simple sanitization of each value to prevent ENV injection via newline or quote escaping.
diff --git a/server/utils/middleware/chatHistoryViewable.js b/server/utils/middleware/chatHistoryViewable.js
new file mode 100644
index 0000000000000000000000000000000000000000..aa95342646ad4c8eb790af6a26c60712f449e549
--- /dev/null
+++ b/server/utils/middleware/chatHistoryViewable.js
@@ -0,0 +1,18 @@
+/**
+ * A simple middleware that validates that the chat history is viewable.
+ * via the `DISABLE_VIEW_CHAT_HISTORY` environment variable being set AT ALL.
+ * @param {Request} request - The request object.
+ * @param {Response} response - The response object.
+ * @param {NextFunction} next - The next function.
+ */
+function chatHistoryViewable(_request, response, next) {
+  if ("DISABLE_VIEW_CHAT_HISTORY" in process.env)
+    return response
+      .status(422)
+      .send("This feature has been disabled by the administrator.");
+  next();
+}
+
+module.exports = {
+  chatHistoryViewable,
+};