diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js
--- a/lib/shared/search-utils.js
+++ b/lib/shared/search-utils.js
@@ -4,11 +4,7 @@
 
 import { messageID } from './message-utils.js';
 import SearchIndex from './search-index.js';
-import {
-  getContainingThreadID,
-  threadMemberHasPermission,
-  userIsMember,
-} from './thread-utils.js';
+import { getContainingThreadID, userIsMember } from './thread-utils.js';
 import {
   searchMessagesActionTypes,
   useSearchMessages as useSearchMessagesAction,
@@ -21,6 +17,7 @@
 import genesis from '../facts/genesis.js';
 import { useIdentitySearch } from '../identity-search/identity-search-context.js';
 import { useLegacyAshoatKeyserverCall } from '../keyserver-conn/legacy-keyserver-call.js';
+import { decodeThreadRolePermissionsBitmaskArray } from '../permissions/minimally-encoded-thread-permissions.js';
 import type {
   ChatMessageInfoItem,
   MessageListData,
@@ -28,9 +25,14 @@
 import { useUserSearchIndex } from '../selectors/nav-selectors.js';
 import { relationshipBlockedInEitherDirection } from '../shared/relationship-utils.js';
 import type { MessageInfo, RawMessageInfo } from '../types/message-types.js';
-import type { ThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js';
+import type {
+  RoleInfo,
+  ThreadInfo,
+  RelativeMemberInfo,
+} from '../types/minimally-encoded-thread-permissions-types.js';
 import { userRelationshipStatus } from '../types/relationship-types.js';
 import { threadPermissions } from '../types/thread-permission-types.js';
+import type { ThreadRolePermissionsBlob } from '../types/thread-permission-types.js';
 import { type ThreadType, threadTypes } from '../types/thread-types-enum.js';
 import type {
   AccountUserInfo,
@@ -70,14 +72,23 @@
   if (excludeUserIDs.includes(id) || id in results) {
     return;
   }
-  if (
-    communityThreadInfo &&
-    !threadMemberHasPermission(
-      communityThreadInfo,
-      id,
-      threadPermissions.KNOW_OF,
-    )
-  ) {
+
+  const memberInfo: ?RelativeMemberInfo = communityThreadInfo?.members.find(
+    m => m.id === id,
+  );
+
+  const role: ?RoleInfo = memberInfo?.role
+    ? communityThreadInfo?.roles[memberInfo.role]
+    : null;
+
+  const decodedRolePermissions: ?ThreadRolePermissionsBlob = role?.permissions
+    ? decodeThreadRolePermissionsBitmaskArray(role.permissions)
+    : null;
+
+  const hasKnowOfPermission =
+    decodedRolePermissions?.[threadPermissions.KNOW_OF] === true;
+
+  if (communityThreadInfo && !hasKnowOfPermission) {
     return;
   }
   results[id] = {
diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js
--- a/lib/shared/thread-utils.js
+++ b/lib/shared/thread-utils.js
@@ -1236,20 +1236,6 @@
   }
 }
 
-function threadMemberHasPermission(
-  threadInfo: ThreadInfo,
-  memberID: string,
-  permission: ThreadPermission,
-): boolean {
-  for (const member of threadInfo.members) {
-    if (member.id !== memberID) {
-      continue;
-    }
-    return hasPermission(member.permissions, permission);
-  }
-  return false;
-}
-
 function checkIfDefaultMembersAreVoiced(threadInfo: ThreadInfo): boolean {
   const defaultRoleID = Object.keys(threadInfo.roles).find(roleID =>
     roleIsDefaultRole(threadInfo.roles[roleID]),
@@ -1699,7 +1685,6 @@
   threadLabel,
   useExistingThreadInfoFinder,
   getThreadTypeParentRequirement,
-  threadMemberHasPermission,
   checkIfDefaultMembersAreVoiced,
   draftKeySuffix,
   draftKeyFromThreadID,