diff --git a/scipost_django/profiles/forms.py b/scipost_django/profiles/forms.py
index 92d6cd4fbfe9bd215f5142b111ca496c97e2514d..bfe37850141465446c2a917fc05a8f3233265ec4 100644
--- a/scipost_django/profiles/forms.py
+++ b/scipost_django/profiles/forms.py
@@ -225,12 +225,22 @@ class ProfileMergeForm(forms.Form):
         profile_old.publicationauthorstable_set.all().update(profile=profile)
 
         # Move all invitations to the "new" profile
-        profile_old.refereeinvitation_set.all().update(profile=profile)
+        profile_old.refereeinvitation_set.all().update(
+            profile=profile,
+            referee=getattr(profile, "contributor", None)
+            or getattr(profile_old, "contributor", None),
+        )
         profile_old.registrationinvitation_set.all().update(profile=profile)
 
         # Move all PotentialFellowships to the "new" profile
         profile_old.potentialfellowship_set.all().update(profile=profile)
 
+        # Move all RedFlags to the "new" profile
+        profile.red_flags.add(*profile_old.red_flags.all())
+
+        # Move all Nomination instances to the "new" profile
+        profile.fellowship_nominations.add(*profile_old.fellowship_nominations.all())
+
         profile_old.delete()
         return Profile.objects.get(
             id=profile.id
diff --git a/scipost_django/profiles/views.py b/scipost_django/profiles/views.py
index 88989f6ab9b6bb95cb04c3ac052692090f792e5c..1c0a05e8bfe697c740e50b664c267759d7edc6f6 100644
--- a/scipost_django/profiles/views.py
+++ b/scipost_django/profiles/views.py
@@ -5,6 +5,7 @@ __license__ = "AGPL v3"
 from functools import reduce
 import re
 from django.contrib import messages
+from django.contrib.auth.decorators import login_required
 from django.contrib.auth.mixins import UserPassesTestMixin
 from django.urls import reverse, reverse_lazy
 from django.db import transaction
@@ -319,6 +320,8 @@ class ProfileListView(PermissionsMixin, PaginationMixin, ListView):
         return context
 
 
+@login_required
+@permission_required("scipost.can_merge_profiles")
 def profile_duplicates(request):
     """
     List Profiles with potential duplicates; allow to merge if necessary.
@@ -332,7 +335,7 @@ def profile_duplicates(request):
 
 @transaction.atomic
 @permission_required_htmx(
-    "scipost.can_create_profiles",
+    "scipost.can_merge_profiles",
     "You do not have permission to create profiles.",
 )
 def _hx_profile_mark_non_duplicate(request, profile1: int, profile2: int):
@@ -349,7 +352,7 @@ def _hx_profile_mark_non_duplicate(request, profile1: int, profile2: int):
 
 @transaction.atomic
 @permission_required_htmx(
-    "scipost.can_create_profiles",
+    "scipost.can_merge_profiles",
     "You do not have permission to create profiles.",
 )
 def _hx_profile_merge(request, to_merge: int, to_merge_into: int):
@@ -384,6 +387,7 @@ def _hx_profile_merge(request, to_merge: int, to_merge_into: int):
     return render(request, "profiles/_hx_profile_merge.html", context)
 
 
+@permission_required("scipost.can_merge_profiles")
 def _hx_profile_comparison(request):
     if request.method == "GET":
         try:
diff --git a/scipost_django/scipost/management/commands/add_groups_and_permissions.py b/scipost_django/scipost/management/commands/add_groups_and_permissions.py
index e57c7baca207ba325135c8803b0b4797534c49bb..3ff2dc98017de4d240ac5f29c1c27eff7a07e2f8 100644
--- a/scipost_django/scipost/management/commands/add_groups_and_permissions.py
+++ b/scipost_django/scipost/management/commands/add_groups_and_permissions.py
@@ -117,6 +117,18 @@ class Command(BaseCommand):
             content_type=content_type,
         )
 
+        # Profile Management
+        can_merge_profiles, created = Permission.objects.get_or_create(
+            codename="can_merge_profiles",
+            name="Can merge Profiles",
+            content_type=content_type,
+        )
+        can_merge_contributors, created = Permission.objects.get_or_create(
+            codename="can_merge_contributors",
+            name="Can merge Contributors",
+            content_type=content_type,
+        )
+
         # Communications
         can_email_group_members, created = Permission.objects.get_or_create(
             codename="can_email_group_members",
@@ -443,6 +455,8 @@ class Command(BaseCommand):
                 can_view_statistics,
                 can_create_profiles,
                 can_view_profiles,
+                can_merge_profiles,
+                can_merge_contributors,
                 can_manage_ontology,
                 can_manage_organizations,
                 can_view_potentialfellowship_list,
@@ -503,6 +517,8 @@ class Command(BaseCommand):
                 can_view_statistics,
                 can_create_profiles,
                 can_view_profiles,
+                can_merge_profiles,
+                can_merge_contributors,
                 can_manage_ontology,
                 can_manage_organizations,
                 can_view_potentialfellowship_list,
diff --git a/scipost_django/scipost/views.py b/scipost_django/scipost/views.py
index 5ab19f51a5e37e5a6f242248224a9bda053a050b..bd5fefbebcb2cf0b6fa171dd89092f3d2cf18d82 100644
--- a/scipost_django/scipost/views.py
+++ b/scipost_django/scipost/views.py
@@ -1583,8 +1583,8 @@ class ContributorDuplicateListView(PermissionsMixin, ListView):
 
 @transaction.atomic
 @permission_required_htmx(
-    "scipost.can_vet_registration_requests",
-    "You do not have permission to vet registration requests.",
+    "scipost.can_merge_contributors",
+    "You are not allowed to merge Contributors.",
 )
 def _hx_contributor_comparison(request):
     """
@@ -1616,8 +1616,8 @@ def _hx_contributor_comparison(request):
 
 @transaction.atomic
 @permission_required_htmx(
-    "scipost.can_vet_registration_requests",
-    "You do not have permission to vet registration requests.",
+    "scipost.can_merge_contributors",
+    "You are not allowed to merge Contributors.",
 )
 def _hx_contributor_merge(request, to_merge: int, to_merge_into: int):
     """