diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py
index 2dcedcfea096226eab04be6b01fb0bec5bcbba8b..1234dbfca5d208180f565ede00b20dd5ec720f5e 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/lofar_viewset.py
@@ -55,9 +55,23 @@ class LOFARViewSet(viewsets.ModelViewSet):
     filter_fields = '__all__'
     ordering_fields = '__all__'
 
+    def _get_permitted_methods(self, request):
+        # Django returns an "Allow" header that reflects what methods the model supports in principle, but not what
+        # the current user is actually has permission to perform. We use the "Access-Control-Allow-Methods" header
+        # to disclose read/write permission to the frontend, so that it can render its views accordingly.
+        allowed_methods = []
+        for method in ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']:
+            request.method = method
+            if TMSSPermissions().has_permission(request=request, view=self):
+                allowed_methods.append(method)
+        return allowed_methods
+
     @swagger_auto_schema(responses={403: 'forbidden'})
     def list(self, request, **kwargs):
-        return super(LOFARViewSet, self).list(request, **kwargs)
+        response = super(LOFARViewSet, self).list(request, **kwargs)
+        if "Access-Control-Allow-Methods" not in response:
+            response["Access-Control-Allow-Methods"] = ", ".join(self._get_permitted_methods(request))
+        return response
 
     @swagger_auto_schema(responses={400: 'invalid specification', 403: 'forbidden'})
     def create(self, request, **kwargs):
@@ -65,7 +79,10 @@ class LOFARViewSet(viewsets.ModelViewSet):
 
     @swagger_auto_schema(responses={403: 'forbidden', 404: 'not found'})
     def retrieve(self, request, pk=None, **kwargs):
-        return super(LOFARViewSet, self).retrieve(request, pk, **kwargs)
+        response = super(LOFARViewSet, self).retrieve(request, pk, **kwargs)
+        if "Access-Control-Allow-Methods" not in response:
+            response["Access-Control-Allow-Methods"] = ", ".join(self._get_permitted_methods(request))
+        return response
 
     @swagger_auto_schema(responses={400: 'invalid specification', 403: 'forbidden', 404: 'not found'})
     def update(self, request, pk=None, **kwargs):
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py
index 168eca7c7d3c50f4efe5a8054dc4b83404cc4ba4..effe24b408c55dbd4b1151971f61b079c35d1281 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/permissions.py
@@ -34,8 +34,8 @@ def get_project_roles_for_user(user):
 
         try:
             return tuple(user.project_roles)
-        except AttributeError:
-            # the user is a non-TMSSUser, for example anonyous/not-logged-in
+        except (AttributeError, TypeError):
+            # the user is a non-TMSSUser, for example anonyous/not-logged-in, or project_roles are None
             # return empty project roles
             return tuple()