diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt
index d3af262321545cff1c6faf4873e6c19a39c37801..410d2938d7d38b5cb1bf686f9400eac35a487809 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt
@@ -1,6 +1,6 @@
 /*
  * Briar Desktop
- * Copyright (C) 2021-2022 The Briar Project
+ * Copyright (C) 2021-2023 The Briar Project
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItemViewSmall.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItemViewSmall.kt
index b602a5127b09693394e518931b2dc861c6b668ad..6e8549b8cf481ba2851ff23698e60c5994e73218 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItemViewSmall.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItemViewSmall.kt
@@ -33,6 +33,7 @@ import androidx.compose.ui.text.style.TextOverflow.Companion.Ellipsis
 import androidx.compose.ui.unit.dp
 import org.briarproject.bramble.api.contact.ContactId
 import org.briarproject.bramble.api.identity.AuthorId
+import org.briarproject.briar.api.identity.AuthorInfo
 import org.briarproject.briar.api.identity.AuthorInfo.Status
 import org.briarproject.briar.desktop.ui.TrustIndicatorShort
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
@@ -74,13 +75,28 @@ fun ContactItemViewSmall(
     contactItem: ContactItem,
     showConnectionState: Boolean = true,
     modifier: Modifier = Modifier,
+) = ContactItemViewSmall(
+    displayName = contactItem.displayName,
+    authorId = contactItem.authorId,
+    authorInfo = contactItem.authorInfo,
+    isConnected = if (showConnectionState) contactItem.isConnected else null,
+    modifier = modifier,
+)
+
+@Composable
+fun ContactItemViewSmall(
+    displayName: String,
+    authorId: AuthorId,
+    authorInfo: AuthorInfo,
+    isConnected: Boolean? = null,
+    modifier: Modifier = Modifier,
 ) = Row(
     horizontalArrangement = spacedBy(8.dp),
     verticalAlignment = Alignment.CenterVertically,
     modifier = modifier
         .fillMaxWidth()
         .semantics {
-            text = getDescription(contactItem, showConnectionState)
+            text = getDescription(displayName, isConnected)
         }
 ) {
     Row(
@@ -88,32 +104,32 @@ fun ContactItemViewSmall(
         horizontalArrangement = spacedBy(8.dp),
         modifier = Modifier.weight(1f, fill = true),
     ) {
-        ProfileCircle(27.dp, contactItem)
+        ProfileCircle(20.dp, authorId, authorInfo)
         Text(
             modifier = Modifier.weight(1f, fill = false),
-            text = contactItem.displayName,
+            text = displayName,
             style = MaterialTheme.typography.body1,
             maxLines = 3,
             overflow = Ellipsis,
         )
-        TrustIndicatorShort(contactItem.trustLevel)
+        TrustIndicatorShort(authorInfo.status)
     }
-    if (showConnectionState)
+    if (isConnected != null)
         ConnectionIndicator(
             modifier = Modifier.requiredSize(12.dp),
-            isConnected = contactItem.isConnected
+            isConnected = isConnected
         )
 }
 
 private fun getDescription(
-    contactItem: ContactItem,
-    showConnectionState: Boolean,
+    displayName: String,
+    isConnected: Boolean?,
 ) = buildBlankAnnotatedString {
-    append(i18nF("access.contact.with_name", contactItem.displayName))
+    append(i18nF("access.contact.with_name", displayName))
     // todo: trust level!
-    if (showConnectionState)
+    if (isConnected != null)
         appendCommaSeparated(
-            if (contactItem.isConnected) i18n("access.contact.connected.yes")
+            if (isConnected) i18n("access.contact.connected.yes")
             else i18n("access.contact.connected.no")
         )
     append('.')
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt
index 571b132e8f40a1305548cb274501e518e0924e2b..bc50e66a90aee257fb9ee2912eda2c17d08da637 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/conversation/PrivateGroupDropdownMenu.kt
@@ -23,6 +23,7 @@ import androidx.compose.material.DropdownMenuItem
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
+import org.briarproject.briar.desktop.privategroup.sharing.PrivateGroupMemberDrawerContent
 import org.briarproject.briar.desktop.privategroup.sharing.PrivateGroupSharingViewModel
 import org.briarproject.briar.desktop.ui.getInfoDrawerHandler
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
@@ -32,17 +33,33 @@ fun PrivateGroupDropdownMenu(
     privateGroupSharingViewModel: PrivateGroupSharingViewModel,
     expanded: Boolean,
     onClose: () -> Unit,
-    onLeaveForumClick: () -> Unit,
+    onLeaveForumClick: () -> Unit, // todo: rename
 ) = DropdownMenu(
     expanded = expanded,
     onDismissRequest = onClose,
 ) {
     val infoDrawerHandler = getInfoDrawerHandler()
+    DropdownMenuItem(
+        onClick = {
+            onClose()
+            infoDrawerHandler.open {
+                PrivateGroupMemberDrawerContent(
+                    close = infoDrawerHandler::close,
+                    viewModel = privateGroupSharingViewModel,
+                )
+            }
+        }
+    ) {
+        Text(
+            i18n("group.member.title"),
+            style = MaterialTheme.typography.body2,
+        )
+    }
 //    DropdownMenuItem(
 //        onClick = {
 //            onClose()
 //            infoDrawerHandler.open {
-//                ForumSharingActionDrawerContent(
+//                ForumSharingStatusDrawerContent(
 //                    close = infoDrawerHandler::close,
 //                    viewModel = forumSharingViewModel,
 //                )
@@ -50,35 +67,19 @@ fun PrivateGroupDropdownMenu(
 //        }
 //    ) {
 //        Text(
-//            i18n("forum.sharing.action.title"),
+//            i18n("forum.sharing.status.title"),
 //            style = MaterialTheme.typography.body2,
 //        )
 //    }
 //    DropdownMenuItem(
 //        onClick = {
 //            onClose()
-//            infoDrawerHandler.open {
-//                ForumSharingStatusDrawerContent(
-//                    close = infoDrawerHandler::close,
-//                    viewModel = forumSharingViewModel,
-//                )
-//            }
+//            onLeaveForumClick()
 //        }
 //    ) {
 //        Text(
-//            i18n("forum.sharing.status.title"),
+//            i18n("forum.leave.title"), // todo: change
 //            style = MaterialTheme.typography.body2,
 //        )
 //    }
-    DropdownMenuItem(
-        onClick = {
-            onClose()
-            onLeaveForumClick()
-        }
-    ) {
-        Text(
-            i18n("forum.leave.title"),
-            style = MaterialTheme.typography.body2,
-        )
-    }
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/sharing/PrivateGroupMemberDrawerContent.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/sharing/PrivateGroupMemberDrawerContent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..45c8ea00a0bcf575ab754305ddb4bd488b79b340
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/sharing/PrivateGroupMemberDrawerContent.kt
@@ -0,0 +1,121 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2023 The Briar Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package org.briarproject.briar.desktop.privategroup.sharing
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Close
+import androidx.compose.material.icons.filled.Info
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import org.briarproject.briar.api.identity.AuthorInfo.Status.OURSELVES
+import org.briarproject.briar.api.privategroup.GroupMember
+import org.briarproject.briar.desktop.contact.ContactItemViewSmall
+import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
+import org.briarproject.briar.desktop.ui.HorizontalDivider
+import org.briarproject.briar.desktop.ui.ListItemView
+import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
+import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18nF
+import org.briarproject.briar.desktop.utils.UiUtils.getContactDisplayName
+
+@Composable
+fun PrivateGroupMemberDrawerContent(
+    close: () -> Unit,
+    viewModel: PrivateGroupSharingViewModel,
+) = Column {
+    Row(Modifier.fillMaxWidth().height(HEADER_SIZE)) {
+        IconButton(
+            icon = Icons.Filled.Close,
+            contentDescription = i18n("access.group.member.close"),
+            onClick = close,
+            modifier = Modifier.padding(start = 24.dp).size(24.dp).align(Alignment.CenterVertically)
+        )
+        Text(
+            text = i18n("group.member.title"),
+            modifier = Modifier.align(Alignment.CenterVertically).padding(start = 16.dp),
+            style = MaterialTheme.typography.h3,
+        )
+    }
+    HorizontalDivider()
+    Row(
+        verticalAlignment = Alignment.CenterVertically,
+        horizontalArrangement = spacedBy(8.dp),
+        modifier = Modifier.padding(8.dp),
+    ) {
+        Icon(
+            imageVector = Icons.Filled.Info,
+            contentDescription = null,
+            modifier = Modifier.size(16.dp)
+        )
+        Text(
+            text = i18n("group.member.info"),
+            style = MaterialTheme.typography.body2,
+        )
+    }
+    HorizontalDivider()
+    LazyColumn(Modifier.fillMaxSize()) {
+        items(viewModel.members) { groupMember ->
+            PrivateGroupMemberListItem(groupMember)
+        }
+    }
+}
+
+@Composable
+private fun PrivateGroupMemberListItem(
+    groupMember: GroupMember,
+) = ListItemView {
+    Column(
+        verticalArrangement = Arrangement.spacedBy(8.dp),
+        modifier = Modifier.padding(8.dp)
+    ) {
+        ContactItemViewSmall(
+            displayName = groupMember.author.name,
+            authorId = groupMember.author.id,
+            authorInfo = groupMember.authorInfo,
+            // todo: Android shows connection status if contact
+            isConnected = null,
+        )
+        if (groupMember.isCreator) {
+            Text(
+                if (groupMember.authorInfo.status == OURSELVES) i18n("group.member.created_you")
+                else i18nF(
+                    "group.member.created_contact",
+                    getContactDisplayName(groupMember.author.name, groupMember.authorInfo.alias)
+                ),
+                style = MaterialTheme.typography.caption,
+            )
+        }
+    }
+}
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/sharing/PrivateGroupSharingViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/sharing/PrivateGroupSharingViewModel.kt
index c6607bc35128b202eceaada1e3fe93705a170d72..729c86059c744707ec1846b4b5ac633a3d2ba0ee 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/sharing/PrivateGroupSharingViewModel.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/privategroup/sharing/PrivateGroupSharingViewModel.kt
@@ -19,6 +19,7 @@
 package org.briarproject.briar.desktop.privategroup.sharing
 
 import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.mutableStateOf
 import mu.KotlinLogging
 import org.briarproject.bramble.api.connection.ConnectionRegistry
@@ -32,9 +33,11 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager
 import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent
 import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent
 import org.briarproject.briar.api.conversation.ConversationManager
-import org.briarproject.briar.api.forum.ForumSharingManager
-import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent
 import org.briarproject.briar.api.identity.AuthorManager
+import org.briarproject.briar.api.privategroup.GroupMember
+import org.briarproject.briar.api.privategroup.PrivateGroupManager
+import org.briarproject.briar.api.privategroup.event.GroupInvitationResponseReceivedEvent
+import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager
 import org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH
 import org.briarproject.briar.api.sharing.SharingManager.SharingStatus
 import org.briarproject.briar.api.sharing.SharingManager.SharingStatus.SHAREABLE
@@ -46,12 +49,15 @@ import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.UiExecutor
 import org.briarproject.briar.desktop.utils.InternationalizationUtils
 import org.briarproject.briar.desktop.utils.StringUtils.takeUtf8
+import org.briarproject.briar.desktop.utils.clearAndAddAll
+import org.briarproject.briar.desktop.viewmodel.asList
 import org.briarproject.briar.desktop.viewmodel.asState
 import org.briarproject.briar.desktop.viewmodel.update
 import javax.inject.Inject
 
 class PrivateGroupSharingViewModel @Inject constructor(
-    private val forumSharingManager: ForumSharingManager,
+    private val privateGroupManager: PrivateGroupManager,
+    private val privateGroupInvitationManager: GroupInvitationManager,
     contactManager: ContactManager,
     authorManager: AuthorManager,
     conversationManager: ConversationManager,
@@ -79,9 +85,8 @@ class PrivateGroupSharingViewModel @Inject constructor(
     private val _shareableSelected = mutableStateOf(emptySet<ContactId>())
     private val _sharingMessage = mutableStateOf("")
 
-    val currentlySharedWith = derivedStateOf {
-        _contactList.filter { _sharingStatus.value[it.id] == SHARING }
-    }
+    private val _members = mutableStateListOf<GroupMember>()
+    val members = _members.asList()
 
     data class ShareableContactItem(val status: SharingStatus, val contactItem: ContactItem)
 
@@ -113,6 +118,12 @@ class PrivateGroupSharingViewModel @Inject constructor(
         super.reload()
         _shareableSelected.value = emptySet()
         _sharingMessage.value = ""
+        runOnDbThreadWithTransaction(true) { txn ->
+            val members = privateGroupManager.getMembers(txn, _groupId!!)
+            txn.attach {
+                _members.clearAndAddAll(members)
+            }
+        }
     }
 
     @UiExecutor
@@ -129,12 +140,13 @@ class PrivateGroupSharingViewModel @Inject constructor(
         _sharingMessage.value = message.takeUtf8(MAX_INVITATION_TEXT_LENGTH)
     }
 
+    // todo: only possible if group creator
     @UiExecutor
     fun shareForum() = runOnDbThreadWithTransaction(false) { txn ->
         val groupId = _groupId ?: return@runOnDbThreadWithTransaction
         val message = _sharingMessage.value.ifEmpty { null }
         _shareableSelected.value.forEach { contactId ->
-            forumSharingManager.sendInvitation(txn, groupId, contactId, message)
+            // privateGroupInvitationManager.sendInvitation(txn, groupId, contactId, message)
         }
         txn.attach { reload() }
     }
@@ -145,7 +157,7 @@ class PrivateGroupSharingViewModel @Inject constructor(
 
         val groupId = _groupId ?: return
         when {
-            e is ForumInvitationResponseReceivedEvent && e.messageHeader.shareableId == groupId -> {
+            e is GroupInvitationResponseReceivedEvent && e.messageHeader.shareableId == groupId -> {
                 if (e.messageHeader.wasAccepted()) {
                     _sharingStatus.value += e.contactId to SHARING
                     val connected = connectionRegistry.isConnected(e.contactId)
@@ -155,6 +167,10 @@ class PrivateGroupSharingViewModel @Inject constructor(
                 }
             }
 
+            // todo: update/reload member list on member join and leave(?)
+            //  e is GroupMessageAddedEvent && e.groupId == groupId && e.header is JoinMessageHeader
+
+            // todo: those could be moved to GroupSharingViewModel
             e is ContactLeftShareableEvent && e.groupId == groupId -> {
                 _sharingStatus.value += e.contactId to SHAREABLE
                 val connected = connectionRegistry.isConnected(e.contactId)
@@ -176,7 +192,7 @@ class PrivateGroupSharingViewModel @Inject constructor(
     override fun loadSharingStatus(txn: Transaction) {
         val groupId = _groupId ?: return
         val map = contactManager.getContacts(txn).associate { contact ->
-            contact.id to forumSharingManager.getSharingStatus(txn, groupId, contact)
+            contact.id to privateGroupInvitationManager.getSharingStatus(txn, contact, groupId)
         }
         txn.attach {
             val sharing = map.filterValues { it == SHARING }.keys
diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties
index 80dd5e2f3a09ef3dc8aa89de5693aaa73948f896..b1628600406d93b6d8f552441b106dc682795b3f 100644
--- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties
+++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties
@@ -89,6 +89,7 @@ access.forums.jump_to_prev_unread=Jump to previous unread post
 access.forums.jump_to_next_unread=Jump to next unread post
 access.forum.sharing.action.close=Close sharing form
 access.forum.sharing.status.close=Close sharing status
+access.group.member.close=Close member list
 
 access.group.list=private group list
 access.group.reply.close=Close reply
@@ -190,7 +191,10 @@ group.leave.title=Leave Group
 group.leave.dialog.title=Confirm Leaving Group
 group.leave.dialog.message=Are you sure that you want to leave this private group?
 group.leave.dialog.button=Leave
-
+group.member.title=Member List
+group.member.info=Only the creator can invite new members to the group. Below are all current members of the group.
+group.member.created_you=You created the group
+group.member.created_contact={0} created the group
 
 # Introduction
 introduction.introduce=Make Introduction