Adding a very rudimentary admin page that displays a table of users 
diff --git a/website/src/components/UsersCell.tsx b/website/src/components/UsersCell.tsx
new file mode 100644
index 0000000000..b2b04c83dc
--- /dev/null
+++ b/website/src/components/UsersCell.tsx
@@ -0,0 +1,44 @@
+import { Table, TableCaption, TableContainer, Tbody, Td, Th, Thead, Tr } from "@chakra-ui/react";
+import { useState } from "react";
+import fetcher from "src/lib/fetcher";
+import useSWR from "swr";
+
+/**
+ * Fetches users from the users api route and then presents them in a simple Chakra table.
+ */
+const UsersCell = () => {
+  // Fetch and save the users.
+  const [users, setUsers] = useState([]);
+  const { isLoading } = useSWR("/api/admin/users", fetcher, {
+    onSuccess: setUsers,
+  });
+
+  // Present users in a naive table.
+  return (
+    <TableContainer>
+      <Table variant="simple">
+        <TableCaption>Users</TableCaption>
+        <Thead>
+          <Tr>
+            <Th>Id</Th>
+            <Th>Email</Th>
+            <Th>Name</Th>
+            <Th>Role</Th>
+          </Tr>
+        </Thead>
+        <Tbody>
+          {users.map((user, index) => (
+            <Tr key={index}>
+              <Td>{user.id}</Td>
+              <Td>{user.email}</Td>
+              <Td>{user.name}</Td>
+              <Td>{user.role}</Td>
+            </Tr>
+          ))}
+        </Tbody>
+      </Table>
+    </TableContainer>
+  );
+};
+
+export default UsersCell;
diff --git a/website/src/pages/admin/index.tsx b/website/src/pages/admin/index.tsx
new file mode 100644
index 0000000000..60d61903c0
--- /dev/null
+++ b/website/src/pages/admin/index.tsx
@@ -0,0 +1,49 @@
+import Head from "next/head";
+import { useRouter } from "next/router";
+import { useSession } from "next-auth/react";
+import { useEffect } from "react";
+import { getTransparentHeaderLayout } from "src/components/Layout";
+import UsersCell from "src/components/UsersCell";
+
+/**
+ * Provides the admin index page that will display a list of users and give
+ * admins the ability to manage their access rights.
+ */
+const AdminIndex = () => {
+  const router = useRouter();
+  const { data: session, status } = useSession();
+
+  // Check when the user session is loaded and re-route if the user is not an
+  // admin.  This follows the suggestion by NextJS for handling private pages:
+  //   https://nextjs.org/docs/api-reference/next/router#usage
+  //
+  // All admin pages should use the same check and routing steps.
+  useEffect(() => {
+    if (status === "loading") {
+      return;
+    }
+    if (session?.user?.role === "admin") {
+      return;
+    }
+    router.push("/");
+  }, [session, status]);
+
+  // Show the final page.
+  // TODO(#237): Display a component that fetches actual user data.
+  return (
+    <>
+      <Head>
+        <title>Open Assistant</title>
+        <meta
+          name="description"
+          content="Conversational AI for everyone. An open source project to create a chat enabled GPT LLM run by LAION and contributors around the world."
+        />
+      </Head>
+      <main className="oa-basic-theme">{status === "loading" ? "loading..." : <UsersCell />}</main>
+    </>
+  );
+};
+
+AdminIndex.getLayout = getTransparentHeaderLayout;
+
+export default AdminIndex;
diff --git a/website/src/pages/api/admin/users.ts b/website/src/pages/api/admin/users.ts
new file mode 100644
index 0000000000..186bb2536c
--- /dev/null
+++ b/website/src/pages/api/admin/users.ts
@@ -0,0 +1,31 @@
+import { getToken } from "next-auth/jwt";
+import client from "src/lib/prismadb";
+
+/**
+ * Returns a list of user results from the database when the requesting user is
+ * a logged in admin.
+ */
+const handler = async (req, res) => {
+  const token = await getToken({ req });
+
+  // Return nothing if the user isn't registered or if the user isn't an admin.
+  if (!token || token.role !== "admin") {
+    res.status(403).end();
+    return;
+  }
+
+  // Fetch 20 users.
+  const users = await client.user.findMany({
+    select: {
+      id: true,
+      role: true,
+      name: true,
+      email: true,
+    },
+    take: 20,
+  });
+
+  res.status(200).json(users);
+};
+
+export default handler;

This starts #237 with a very basic and minimally styled version.  This does not include any management functionality, that will be in a follow up PR.