diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py
index 9dc736e8d0396f1d93f24d0d49ae4484fee3ca6b..9d1e8ee55756dec1cdfc40e3e9c51c4a9b2f7e6e 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/keycloak.py
@@ -45,7 +45,10 @@ def get_users_by_role_in_project(role, project):
     returns the list of users that have the specified role in the specified project
     """
     project_persons = get_project_persons()
-    return project_persons[project][role]
+    if project in project_persons:
+        return project_persons[project][role]
+    else:
+        return []
 
 
 @cachetools.func.ttl_cache(ttl=600)
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py
index effe24b408c55dbd4b1151971f61b079c35d1281..914f7dd9e15d534f567382535576a09064e06323 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py
@@ -28,7 +28,8 @@ def get_project_roles_for_user(user):
         try:
             if user == models.User.objects.get(username='paulus'):
                 return ({'project': 'test_user_is_shared_support', 'role': 'shared_support'},
-                        {'project': 'test_user_is_contact', 'role': 'contact'})
+                        {'project': 'test_user_is_contact', 'role': 'contact'},
+                        {'project': 'test_user_is_friend', 'role': 'friend_of_project'})
         except:
             pass
 
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
index 752ea356aaa6ec0ba81abe864314030ccbefb7ea..dc897e8d234ba0a9b0acf2c3fd85a310bf224f1a 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
@@ -25,6 +25,7 @@ from lofar.sas.tmss.tmss.tmssapp.viewsets.lofar_viewset import LOFARViewSet, LOF
 from lofar.sas.tmss.tmss.tmssapp import models
 from lofar.sas.tmss.tmss.tmssapp import serializers
 from lofar.sas.tmss.tmss.tmssapp.adapters.reports import create_cycle_report, create_project_report
+from lofar.sas.tmss.tmss.tmssapp.adapters.keycloak import get_users_by_role_in_project
 from django.http import JsonResponse
 
 from datetime import datetime
@@ -32,7 +33,7 @@ from lofar.common.json_utils import get_default_json_object_for_schema
 from lofar.common.datetimeutils import formatDatetime
 from lofar.sas.tmss.tmss.tmssapp.tasks import *
 from lofar.sas.tmss.tmss.tmssapp.subtasks import *
-from lofar.sas.tmss.tmss.tmssapp.viewsets.permissions import TMSSDjangoModelPermissions
+from lofar.sas.tmss.tmss.tmssapp.viewsets.permissions import TMSSDjangoModelPermissions, get_project_roles_for_user
 
 from django.urls  import resolve, get_script_prefix,Resolver404
 from rest_framework.filters import OrderingFilter
@@ -394,6 +395,28 @@ class ProjectViewSet(LOFARViewSet):
         result = create_project_report(request, project)
         return Response(result, status=status.HTTP_200_OK)
 
+    @swagger_auto_schema(responses={200: 'List of users that have the "friend of project" role for this project',
+                                    403: 'forbidden'},
+                         operation_description="Get the list of users that have the 'friend of project' role for this project")
+    @action(methods=['get'], detail=True, url_name="friend", name="Friend(s) of this project")
+    def friend(self, request, pk=None):
+        project = get_object_or_404(models.Project, pk=pk)
+        result = get_users_by_role_in_project(models.ProjectRole.Choices.FRIEND_OF_PROJECT.value, project.name)
+        return Response(result, status=status.HTTP_200_OK)
+
+    @swagger_auto_schema(responses={200: 'List of roles that the requesting user has in this project',
+                                    403: 'forbidden'},
+                         operation_description="Get the list of roles that the requesting user has in this project")
+    @action(methods=['get'], detail=True, url_name="my_roles", name="My roles in this project")
+    def my_roles(self, request, pk=None):
+        project = get_object_or_404(models.Project, pk=pk)
+        project_roles = get_project_roles_for_user(request.user)
+        result = []
+        for project_role in project_roles:
+            if project.name == project_role['project']:
+                result.append(project_role['role'])
+        return Response(result, status=status.HTTP_200_OK)
+
 
 class ProjectNestedViewSet(LOFARNestedViewSet):
     queryset = models.Project.objects.all()
diff --git a/SAS/TMSS/backend/test/t_permissions_project_roles.py b/SAS/TMSS/backend/test/t_permissions_project_roles.py
index 40ec90a4850a149636986c3eccbedb49c606b6bb..0c42f025fdbfe5f87da61aad84752754d442c820 100755
--- a/SAS/TMSS/backend/test/t_permissions_project_roles.py
+++ b/SAS/TMSS/backend/test/t_permissions_project_roles.py
@@ -51,6 +51,9 @@ from lofar.sas.tmss.test.tmss_test_data_rest import TMSSRESTTestDataCreator
 
 from django.test import TestCase
 
+from django.contrib.auth import get_user_model
+User = get_user_model()
+
 class ProjectPermissionTestCase(TestCase):
     # This tests that the project permissions are enforced in light of the project roles that are externally provided
     # for the user through the user admin. This test does not rely on the project permissions as defined in the system,
@@ -66,7 +69,8 @@ class ProjectPermissionTestCase(TestCase):
         cls.project_permission_patcher = mock.patch('lofar.sas.tmss.tmss.tmssapp.viewsets.get_project_roles_for_user')  # todo: fix namespace so we get the get_project_roles that gets actually used
         cls.project_permission_mock = cls.project_permission_patcher.start()
         cls.project_permission_mock.return_value = ({'project': 'test_user_is_shared_support', 'role': 'shared_support'},
-                                                    {'project': 'test_user_is_contact', 'role': 'contact_author'})
+                                                    {'project': 'test_user_is_contact', 'role': 'contact_author'},
+                                                    {'project': 'test_user_is_friend', 'role': 'friend_of_project'})
 
         # create some stuff as the standard super user, as setup for the tests below
         cls.test_data_creator = TMSSRESTTestDataCreator(BASE_URL, AUTH)
@@ -75,8 +79,9 @@ class ProjectPermissionTestCase(TestCase):
         # create projects with magic names for which permission exists (or which have no whitelisted generic name)
         cls.project_shared_support_url = cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.Project(name='test_user_is_shared_support', cycle_urls=[cycle_url]), '/project/')
         cls.project_contact_url = cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.Project(name='test_user_is_contact', cycle_urls=[cycle_url]), '/project/')
+        cls.project_friend_url = cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.Project(name='test_user_is_friend', cycle_urls=[cycle_url]), '/project/')
         cls.project_forbidden_url = cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.Project(name='forbidden', cycle_urls=[cycle_url]), '/project/')
-
+        cls.project_keycloak_url = cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.Project(name="2014LOFAROBS", cycle_urls=[cycle_url]), '/project/')  # project is known to Keycloak
 
         # user is shared_support
         cls.scheduling_set_shared_support_url = cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.SchedulingSet(project_url=cls.project_shared_support_url), '/scheduling_set/')
@@ -92,8 +97,10 @@ class ProjectPermissionTestCase(TestCase):
 
         # create the required permission entries to control what endpoint action requires which project role
         shared_support_role_url = BASE_URL + '/project_role/shared_support/'
+        friend_of_project_role_url = BASE_URL + '/project_role/friend_of_project/'
         cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.ProjectPermission(name='taskdraft', GET=[shared_support_role_url], POST=[shared_support_role_url]), '/project_permission/')
         cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.ProjectPermission(name='taskdraft-create_task_blueprint', POST=[shared_support_role_url]), '/project_permission/')
+        cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.ProjectPermission(name='project-my_roles', GET=[shared_support_role_url, friend_of_project_role_url]), '/project_permission/')
 
         cls.task_template_url = cls.test_data_creator.post_data_and_get_url(cls.test_data_creator.TaskTemplate(), '/task_template/')
 
@@ -230,6 +237,37 @@ class ProjectPermissionTestCase(TestCase):
 
     # todo: add tests for other models with project permissions
 
+    def test_project_get_friend_returns_correct_user(self):
+        """
+        Note: This test relies on real data from Keycloak.
+        """
+        r = GET_and_assert_equal_expected_code(self, self.project_keycloak_url + '/friend/', 200)
+        self.assertEqual(len(r), 2)
+        for friend in r:
+            # Todo: find a way to mock the Keycloak response so we can assert more strictly.
+            self.assertTrue(friend.endswith('@astron.nl'))  # redacted expected full email due to GDPR
+
+    def test_project_get_friend_returns_403_if_no_permission_for_project(self):
+
+        r = GET_and_assert_equal_expected_code(self, self.project_forbidden_url + '/my_roles/', 403, auth=self.auth)
+        self.assertIn('permission', str(r))
+
+
+    def test_project_get_my_roles_returns_correct_roles(self):
+
+        # r = GET_and_assert_equal_expected_code(self, self.project_shared_support_url + '/my_roles/', 200, auth=self.auth)
+        # expected_reply = ['shared_support']
+        # self.assertEqual(expected_reply, r)
+
+        r = GET_and_assert_equal_expected_code(self, self.project_friend_url + '/my_roles/', 200, auth=self.auth)
+        expected_reply = ['friend_of_project']
+        self.assertEqual(expected_reply, r)
+
+    def test_project_get_my_roles_returns_403_if_no_permission_for_project(self):
+
+        r = GET_and_assert_equal_expected_code(self, self.project_forbidden_url + '/my_roles/', 403, auth=self.auth)
+        self.assertIn('permission', str(r))
+
 
 if __name__ == "__main__":
     logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',