diff --git a/aleksis/apps/alsijil/migrations/0026_add_global_permissions.py b/aleksis/apps/alsijil/migrations/0026_add_global_permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffee911dadb7d20aa96eb241f2c4f8532ca6e6a5
--- /dev/null
+++ b/aleksis/apps/alsijil/migrations/0026_add_global_permissions.py
@@ -0,0 +1,17 @@
+# Generated by Django 5.1.4 on 2025-01-10 17:52
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('alsijil', '0025_remove_old_models'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='alsijilglobalpermissions',
+            options={'managed': False, 'permissions': (('view_lesson', 'Can view lesson overview'), ('view_week', 'Can view week overview'), ('view_full_register', 'Can view full register'), ('view_all_coursebooks', 'Can view all coursebooks including all related information (e. g. personal notes)'), ('manage_all_coursebooks', 'Can manage all coursebooks including all related information (e. g. personal notes)'), ('register_absence', 'Can register absence'), ('list_personal_note_filters', 'Can list all personal note filters'))},
+        ),
+    ]
diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index 6e8465376fad8816f65ab28204d60e367a97221b..d843d6172a07985ae7fe9e176c0615b4f0e945cb 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -659,6 +659,14 @@ class AlsijilGlobalPermissions(GlobalPermissionModel):
             ("view_lesson", _("Can view lesson overview")),
             ("view_week", _("Can view week overview")),
             ("view_full_register", _("Can view full register")),
+            (
+                "view_all_coursebooks",
+                _("Can view all coursebooks including all related information"),
+            ),
+            (
+                "manage_all_coursebooks",
+                _("Can manage all coursebooks including all related information"),
+            ),
             ("register_absence", _("Can register absence")),
             ("list_personal_note_filters", _("Can list all personal note filters")),
         )
diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index c0a697b1c8248413e96d339279d7a278852f4b20..93db2dd87f8415f997200104337d248807a1713d 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -52,19 +52,6 @@ register_absence_predicate = has_person & (
 )
 add_perm("alsijil.register_absence_rule", register_absence_predicate)
 
-# View full register for group
-view_full_register_predicate = has_person & (
-    is_group_owner
-    | (
-        is_parent_group_owner
-        & is_site_preference_set("alsijil", "inherit_privileges_from_parent_group")
-    )
-    | has_global_perm("alsijil.view_full_register")
-    | has_object_perm("core.view_full_register_group")
-)
-add_perm("alsijil.view_full_register_rule", view_full_register_predicate)
-
-
 # View extra mark list
 view_extramarks_predicate = has_person & has_global_perm("alsijil.view_extramark")
 add_perm("alsijil.view_extramarks_rule", view_extramarks_predicate)
@@ -147,12 +134,15 @@ view_register_objects_list_predicate = has_person & (
 add_perm("alsijil.view_register_objects_list_rule", view_register_objects_list_predicate)
 
 view_documentation_predicate = has_person & (
-    has_global_perm("alsijil.view_documentation") | can_view_documentation
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.view_documentation")
+    | can_view_documentation
 )
 add_perm("alsijil.view_documentation_rule", view_documentation_predicate)
 
 view_documentations_for_course_predicate = has_person & (
-    has_global_perm("alsijil.view_documentation")
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.view_documentation")
     | is_course_teacher
     | is_course_member
     | is_course_group_owner
@@ -160,28 +150,46 @@ view_documentations_for_course_predicate = has_person & (
 add_perm("alsijil.view_documentations_for_course_rule", view_documentations_for_course_predicate)
 
 view_documentations_for_group_predicate = has_person & (
-    has_global_perm("alsijil.view_documentation")
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.view_documentation")
     | is_group_owner
     | is_group_member
     | is_parent_group_owner
 )
 add_perm("alsijil.view_documentations_for_group_rule", view_documentations_for_group_predicate)
 
+print_documentations_for_group_predicate = has_person & (
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.view_full_register")
+    | is_group_owner
+    | (
+        is_parent_group_owner
+        & is_site_preference_set("alsijil", "inherit_privileges_from_parent_group")
+    )
+    | has_object_perm("core.view_full_register_group")
+)
+add_perm("alsijil.print_documentations_for_group_rule", print_documentations_for_group_predicate)
+
 view_documentations_menu_predicate = has_person
 add_perm("alsijil.view_documentations_menu_rule", view_documentations_menu_predicate)
 
 view_documentations_for_teacher_predicate = has_person & (
-    has_global_perm("alsijil.view_documentation") | is_current_person
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.view_documentation")
+    | is_current_person
 )
 add_perm("alsijil.view_documentations_for_teacher_rule", view_documentations_for_teacher_predicate)
 
 add_documentation_for_course_predicate = has_person & (
-    has_global_perm("alsijil.add_documentation") | is_course_teacher
+    has_global_perm("alsijil.manage_all_coursebooks")
+    | has_global_perm("alsijil.add_documentation")
+    | is_course_teacher
 )
 add_perm("alsijil.add_documentation_for_course_rule", add_documentation_for_course_predicate)
 
 add_documentation_for_lesson_event_predicate = has_person & (
-    has_global_perm("alsijil.add_documentation")
+    has_global_perm("alsijil.manage_all_coursebooks")
+    | has_global_perm("alsijil.add_documentation")
     | is_lesson_event_teacher
     | is_lesson_event_group_owner
 )
@@ -191,14 +199,19 @@ add_perm(
 
 edit_documentation_predicate = (
     has_person
-    & (has_global_perm("alsijil.change_documentation") | can_edit_documentation)
+    & (
+        has_global_perm("alsijil.manage_all_coursebooks")
+        | has_global_perm("alsijil.change_documentation")
+        | can_edit_documentation
+    )
     & is_in_allowed_time_range
 )
 add_perm("alsijil.edit_documentation_rule", edit_documentation_predicate)
 add_perm("alsijil.delete_documentation_rule", edit_documentation_predicate)
 
 view_participation_status_for_documentation_predicate = has_person & (
-    has_global_perm("alsijil.change_participationstatus")
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.change_participationstatus")
     | can_view_participation_status_for_documentation
 )
 add_perm(
@@ -209,7 +222,8 @@ add_perm(
 edit_participation_status_for_documentation_with_time_range_predicate = (
     has_person
     & (
-        has_global_perm("alsijil.change_participationstatus")
+        has_global_perm("alsijil.manage_all_coursebooks")
+        | has_global_perm("alsijil.change_participationstatus")
         | can_edit_participation_status_for_documentation
     )
     & is_in_allowed_time_range_for_participation_status
@@ -220,7 +234,8 @@ add_perm(
 )
 
 edit_participation_status_for_documentation_predicate = has_person & (
-    has_global_perm("alsijil.change_participationstatus")
+    has_global_perm("alsijil.manage_all_coursebooks")
+    | has_global_perm("alsijil.change_participationstatus")
     | can_edit_participation_status_for_documentation
 )
 add_perm(
@@ -245,7 +260,9 @@ add_perm(
 )
 
 view_personal_note_predicate = has_person & (
-    has_global_perm("alsijil.change_newpersonalnote") | can_view_personal_note
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.change_newpersonalnote")
+    | can_view_personal_note
 )
 add_perm(
     "alsijil.view_personal_note_rule",
@@ -254,7 +271,11 @@ add_perm(
 
 edit_personal_note_predicate = (
     has_person
-    & (has_global_perm("alsijil.change_newpersonalnote") | can_edit_personal_note)
+    & (
+        has_global_perm("alsijil.manage_all_coursebooks")
+        | has_global_perm("alsijil.change_newpersonalnote")
+        | can_edit_personal_note
+    )
     & is_in_allowed_time_range
 )
 add_perm(
@@ -263,7 +284,9 @@ add_perm(
 )
 
 view_group_statistics_predicate = has_person & (
-    has_global_perm("alsijil.view_participationstatus") | is_group_owner
+    has_global_perm("alsijil.view_all_coursebooks")
+    | has_global_perm("alsijil.view_participationstatus")
+    | is_group_owner
 )
 add_perm(
     "alsijil.view_group_statistics_rule",
@@ -272,6 +295,7 @@ add_perm(
 
 view_person_statistics_predicate = has_person & (
     is_current_person
+    | has_global_perm("alsijil.view_all_coursebooks")
     | has_global_perm("alsijil.view_participationstatus")
     | can_view_statistics_for_person
 )
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index f337be4f836c8f73383e952c88f79e229613e02a..545173b3130b268cb105788d51f325db5da07c76 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -150,6 +150,7 @@ class Query(graphene.ObjectType):
         event_params = {
             "own": own,
         }
+
         if obj_type is not None and obj_id is not None:
             event_params.update(
                 {
@@ -168,6 +169,9 @@ class Query(graphene.ObjectType):
             info.context,
             event_params,
             with_reference_object=True,
+            bypass_permission_and_person_filters=info.context.user.has_perm(
+                "alsijil.view_all_coursebooks"
+            ),
         )
 
         # Lookup or create documentations and return them all.
@@ -193,9 +197,10 @@ class Query(graphene.ObjectType):
 
         school_term = get_active_school_term(info.context)
 
-        return (
-            Group.objects.for_school_term(school_term)
-            .filter(
+        if info.context.user.has_perm("alsijil.view_all_coursebooks"):
+            qs = Group.objects.for_school_term(school_term)
+        else:
+            qs = Group.objects.for_school_term(school_term).filter(
                 pk__in=Group.objects.filter(members=person)
                 .values_list("id", flat=True)
                 .union(Group.objects.filter(owners=person).values_list("id", flat=True))
@@ -203,14 +208,13 @@ class Query(graphene.ObjectType):
                     Group.objects.filter(parent_groups__owners=person).values_list("id", flat=True)
                 )
             )
-            .annotate(
-                is_priority=ExpressionWrapper(
-                    Q(group_type=get_site_preferences()["alsijil__group_type_priority_coursebook"]),
-                    output_field=BooleanField(),
-                )
+
+        return qs.annotate(
+            is_priority=ExpressionWrapper(
+                Q(group_type=get_site_preferences()["alsijil__group_type_priority_coursebook"]),
+                output_field=BooleanField(),
             )
-            .order_by("is_priority")
-        )
+        ).order_by("is_priority")
 
     @staticmethod
     def resolve_courses_of_person(root, info, person=None):
@@ -225,19 +229,28 @@ class Query(graphene.ObjectType):
 
         school_term = get_active_school_term(info.context)
 
-        return Course.objects.filter(
-            pk__in=(
-                Course.objects.filter(teachers=person)
-                .values_list("id", flat=True)
-                .union(Course.objects.filter(groups__members=person).values_list("id", flat=True))
-                .union(Course.objects.filter(groups__owners=person).values_list("id", flat=True))
-                .union(
-                    Course.objects.filter(groups__parent_groups__owners=person).values_list(
-                        "id", flat=True
+        if info.context.user.has_perm("alsijil.view_all_coursebooks"):
+            qs = Course.objects.all()
+        else:
+            qs = Course.objects.filter(
+                pk__in=(
+                    Course.objects.filter(teachers=person)
+                    .values_list("id", flat=True)
+                    .union(
+                        Course.objects.filter(groups__members=person).values_list("id", flat=True)
+                    )
+                    .union(
+                        Course.objects.filter(groups__owners=person).values_list("id", flat=True)
+                    )
+                    .union(
+                        Course.objects.filter(groups__parent_groups__owners=person).values_list(
+                            "id", flat=True
+                        )
                     )
                 )
             )
-        ).filter(groups__in=Group.objects.for_school_term(school_term))
+
+        return qs.filter(groups__in=Group.objects.for_school_term(school_term))
 
     @staticmethod
     def resolve_absence_creation_persons(root, info, **kwargs):
diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py
index ad88b2de383217984eb4cb8e2e2704daf68c84e9..2f21846461fe5dbca38c98ff864babe3a0e705fe 100644
--- a/aleksis/apps/alsijil/schema/documentation.py
+++ b/aleksis/apps/alsijil/schema/documentation.py
@@ -7,7 +7,6 @@ from reversion import create_revision, set_comment, set_user
 
 from aleksis.apps.alsijil.util.predicates import (
     can_edit_documentation,
-    can_edit_participation_status_for_documentation,
     is_in_allowed_time_range,
     is_in_allowed_time_range_for_participation_status,
 )
@@ -96,7 +95,9 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp
     @staticmethod
     def resolve_can_edit_participation_status(root: Documentation, info, **kwargs):
         """Shows whether the user can edit all participation statuses of the documentation"""
-        return can_edit_participation_status_for_documentation(info.context.user, root)
+        return info.context.user.has_perm(
+            "alsijil.edit_participation_status_for_documentation_rule", root
+        )
 
     @staticmethod
     def resolve_can_view_participation_status(root: Documentation, info, **kwargs):
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index 71b4cbdd6ee85c3eb280c9f15549e31736b060ab..8cf6f512ae28c69418c35b6dc6da039ea040cbb9 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -54,7 +54,7 @@ def full_register_for_group(request: HttpRequest, ids: str) -> HttpResponse:
     groups = []
     for id_ in ids:
         group = get_object_or_404(Group, pk=id_)
-        if not request.user.has_perm("alsijil.view_full_register_rule", group):
+        if not request.user.has_perm("alsijil.print_documentations_for_group_rule", group):
             raise PermissionDenied()
         groups.append(group)