diff --git a/frontend/src/components/Modals/Settings/PasswordProtection/index.jsx b/frontend/src/components/Modals/Settings/PasswordProtection/index.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..2b6444edba782db4af1fa979dd0b37f1df4ba47b
--- /dev/null
+++ b/frontend/src/components/Modals/Settings/PasswordProtection/index.jsx
@@ -0,0 +1,141 @@
+import React, { useState, useEffect } from "react";
+import System from "../../../../models/system";
+
+const noop = () => false;
+export default function PasswordProtection({ hideModal = noop }) {
+  const [loading, setLoading] = useState(true);
+  const [saving, setSaving] = useState(false);
+  const [success, setSuccess] = useState(false);
+  const [error, setError] = useState(null);
+  const [usePassword, setUsePassword] = useState(false);
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    setSaving(true);
+    setSuccess(false);
+    setError(null);
+
+    const form = new FormData(e.target);
+    const data = {
+      usePassword,
+      newPassword: form.get("password"),
+    };
+
+    const { success, error } = await System.updateSystemPassword(data);
+    if (success) {
+      setSuccess(true);
+      setSaving(false);
+      setTimeout(() => {
+        window.localStorage.removeItem("anythingllm_authToken");
+        window.location.reload();
+      }, 2_000);
+      return;
+    }
+
+    setError(error);
+    setSaving(false);
+  };
+
+  useEffect(() => {
+    async function fetchKeys() {
+      const settings = await System.keys();
+      setUsePassword(settings?.RequiresAuth);
+      setLoading(false);
+    }
+    fetchKeys();
+  }, []);
+
+  return (
+    <div className="relative w-full max-w-2xl max-h-full">
+      <div className="relative bg-white rounded-lg shadow dark:bg-stone-700">
+        <div className="flex items-start justify-between px-6 py-4">
+          <p className="text-gray-800 dark:text-stone-200 text-base ">
+            Protect your AnythingLLM instance with a password. If you forget
+            this there is no recovery method so ensure you save this password.
+          </p>
+        </div>
+        {(error || success) && (
+          <div className="w-full flex px-6">
+            {error && (
+              <div className="w-full bg-red-300 text-red-800 font-semibold px-4 py-2 rounded-lg">
+                {error}
+              </div>
+            )}
+            {success && (
+              <div className="w-full bg-green-300 text-green-800 font-semibold px-4 py-2 rounded-lg">
+                Your page will refresh in a few seconds.
+              </div>
+            )}
+          </div>
+        )}
+        <div className="p-6 space-y-6 flex h-full w-full">
+          {loading ? (
+            <div className="w-full h-full flex items-center justify-center">
+              <p className="text-gray-800 dark:text-gray-200 text-base">
+                loading system settings
+              </p>
+            </div>
+          ) : (
+            <div className="w-full flex flex-col gap-y-4">
+              <form onSubmit={handleSubmit}>
+                <div className="">
+                  <label className="mb-2.5 block font-medium text-black dark:text-white">
+                    Password Protect Instance
+                  </label>
+
+                  <label className="relative inline-flex cursor-pointer items-center">
+                    <input
+                      type="checkbox"
+                      name="use_password"
+                      onClick={() => setUsePassword(!usePassword)}
+                      checked={usePassword}
+                      className="peer sr-only pointer-events-none"
+                    />
+                    <div className="pointer-events-none peer h-6 w-11 rounded-full bg-gray-200 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-green-600 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:border-gray-600 dark:bg-stone-400 dark:peer-focus:ring-blue-800"></div>
+                  </label>
+                </div>
+                <div className="w-full flex flex-col gap-y-2 my-2">
+                  {usePassword && (
+                    <div>
+                      <label
+                        htmlFor="password"
+                        className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
+                      >
+                        New Password
+                      </label>
+                      <input
+                        name="password"
+                        type="text"
+                        className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-stone-600 dark:border-stone-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
+                        placeholder="Your Instance Password"
+                        minLength={8}
+                        required={true}
+                        autoComplete="off"
+                      />
+                    </div>
+                  )}
+                  <button
+                    disabled={saving}
+                    type="submit"
+                    className="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600"
+                  >
+                    {saving ? "Saving..." : "Save Changes"}
+                  </button>
+                </div>
+              </form>
+            </div>
+          )}
+        </div>
+        <div className="flex items-center p-6 space-x-2 border-t border-gray-200 rounded-b dark:border-gray-600">
+          <button
+            onClick={hideModal}
+            type="button"
+            className="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-blue-300 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600"
+          >
+            Close
+          </button>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/frontend/src/components/Modals/Settings/index.jsx b/frontend/src/components/Modals/Settings/index.jsx
index baa46df4a44ff4df6bb7dc14315b458246b17f68..e898a7afa0ec7fccabe4f95b4941fe2093210d23 100644
--- a/frontend/src/components/Modals/Settings/index.jsx
+++ b/frontend/src/components/Modals/Settings/index.jsx
@@ -1,11 +1,13 @@
 import React, { useState } from "react";
-import { Archive, Cloud, Key, X } from "react-feather";
+import { Archive, Lock, Key, X } from "react-feather";
 import SystemKeys from "./Keys";
 import ExportOrImportData from "./ExportImport";
+import PasswordProtection from "./PasswordProtection";
 
 const TABS = {
   keys: SystemKeys,
   exportimport: ExportOrImportData,
+  password: PasswordProtection,
 };
 
 const noop = () => false;
@@ -62,6 +64,13 @@ function SettingTabs({ selectedTab, changeTab }) {
           icon={<Archive className="h-4 w-4 flex-shrink-0" />}
           onClick={changeTab}
         />
+        <SettingTab
+          active={selectedTab === "password"}
+          displayName="Password Protection"
+          tabName="password"
+          icon={<Lock className="h-4 w-4 flex-shrink-0" />}
+          onClick={changeTab}
+        />
       </ul>
     </div>
   );
diff --git a/frontend/src/models/system.js b/frontend/src/models/system.js
index 06ca2b92c1810170db51edf6b6e60bb0bec0e011..7e5f61bfdd4a638e53af7cf234ff3b00ac84f2e8 100644
--- a/frontend/src/models/system.js
+++ b/frontend/src/models/system.js
@@ -86,6 +86,18 @@ const System = {
         return { newValues: null, error: e.message };
       });
   },
+  updateSystemPassword: async (data) => {
+    return await fetch(`${API_BASE}/system/update-password`, {
+      method: "POST",
+      headers: baseHeaders(),
+      body: JSON.stringify(data),
+    })
+      .then((res) => res.json())
+      .catch((e) => {
+        console.error(e);
+        return { success: false, error: e.message };
+      });
+  },
   deleteDocument: async (name, meta) => {
     return await fetch(`${API_BASE}/system/remove-document`, {
       method: "DELETE",
diff --git a/server/endpoints/system.js b/server/endpoints/system.js
index 5193539ca6dc3432d1f55996b32eb158d64aa742..a39ef3a3b142edff67a68a33c04e501da4b25cf0 100644
--- a/server/endpoints/system.js
+++ b/server/endpoints/system.js
@@ -13,6 +13,7 @@ const { getVectorDbClass } = require("../utils/helpers");
 const { updateENV } = require("../utils/helpers/updateENV");
 const { reqBody, makeJWT } = require("../utils/http");
 const { setupDataImports } = require("../utils/files/multer");
+const { v4 } = require("uuid");
 const { handleImports } = setupDataImports();
 
 function systemEndpoints(app) {
@@ -155,6 +156,20 @@ function systemEndpoints(app) {
     }
   });
 
+  app.post("/system/update-password", async (request, response) => {
+    try {
+      const { usePassword, newPassword } = reqBody(request);
+      const { error } = updateENV({
+        AuthToken: usePassword ? newPassword : "",
+        JWTSecret: usePassword ? v4() : "",
+      });
+      response.status(200).json({ success: !error, error });
+    } catch (e) {
+      console.log(e.message, e);
+      response.sendStatus(500).end();
+    }
+  });
+
   app.get("/system/data-export", async (_, response) => {
     try {
       const { filename, error } = await exportData();
diff --git a/server/utils/helpers/updateENV.js b/server/utils/helpers/updateENV.js
index 4161aec13af3ca941effe6d7f8a1b32c31dae60d..54eec1e5bcee1e79d4d7bd7b58eca10a7b4373ff 100644
--- a/server/utils/helpers/updateENV.js
+++ b/server/utils/helpers/updateENV.js
@@ -27,9 +27,15 @@ const KEY_MAPPING = {
     envKey: "PINECONE_INDEX",
     checks: [],
   },
+  AuthToken: {
+    envKey: "AUTH_TOKEN",
+    checks: [],
+  },
+  JWTSecret: {
+    envKey: "JWT_SECRET",
+    checks: [],
+  },
   // Not supported yet.
-  // 'AuthToken': 'AUTH_TOKEN',
-  // 'JWTSecret': 'JWT_SECRET',
   // 'StorageDir': 'STORAGE_DIR',
 };
 
diff --git a/server/utils/http/index.js b/server/utils/http/index.js
index af42f5de51907916ba678d92588825560f58322b..9fd643b75634c67295d892eea153fd4eb4f9949f 100644
--- a/server/utils/http/index.js
+++ b/server/utils/http/index.js
@@ -2,7 +2,6 @@ process.env.NODE_ENV === "development"
   ? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` })
   : require("dotenv").config();
 const JWT = require("jsonwebtoken");
-const SECRET = process.env.JWT_SECRET;
 
 function reqBody(request) {
   return typeof request.body === "string"
@@ -15,15 +14,16 @@ function queryParams(request) {
 }
 
 function makeJWT(info = {}, expiry = "30d") {
-  if (!SECRET) throw new Error("Cannot create JWT as JWT_SECRET is unset.");
-  return JWT.sign(info, SECRET, { expiresIn: expiry });
+  if (!process.env.JWT_SECRET)
+    throw new Error("Cannot create JWT as JWT_SECRET is unset.");
+  return JWT.sign(info, process.env.JWT_SECRET, { expiresIn: expiry });
 }
 
 function decodeJWT(jwtToken) {
   try {
-    return JWT.verify(jwtToken, SECRET);
+    return JWT.verify(jwtToken, process.env.JWT_SECRET);
   } catch {}
-  return null;
+  return { p: null };
 }
 
 module.exports = {