diff --git a/opentech/apply/funds/templates/funds/includes/review_sidebar_item.html b/opentech/apply/funds/templates/funds/includes/review_sidebar_item.html
index be0bba5a1275fcdfecc6d6f717fddc1b7adf7df0..e0c246e865ba6f32b88caa6c94737e174c5db467 100644
--- a/opentech/apply/funds/templates/funds/includes/review_sidebar_item.html
+++ b/opentech/apply/funds/templates/funds/includes/review_sidebar_item.html
@@ -9,6 +9,7 @@
         <div>-</div>
         <div>-</div>
     {% else %}
+        {% if request.user == reviewer or request.user.is_reviewer and review.reviewer_visibility or request.user.is_apply_staff %}
         {% if request.user.is_apply_staff or request.user == reviewer %}
             <div>
                 <a href="{% url 'apply:submissions:reviews:review' submission_pk=review.submission.id pk=review.id %}">
diff --git a/opentech/apply/review/models.py b/opentech/apply/review/models.py
index 2faaec2d6a062558e3dea69469b3c153b4f3d89d..7d6afded11cdff1efd147413a9f5fe363974a16c 100644
--- a/opentech/apply/review/models.py
+++ b/opentech/apply/review/models.py
@@ -5,12 +5,12 @@ from django.db import models
 from django.db.models.signals import post_save
 from django.dispatch import receiver
 from django.urls import reverse
+from django.utils.functional import cached_property
 from django.utils.translation import ugettext_lazy as _
 from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
 from wagtail.core.fields import StreamField
 
 from opentech.apply.funds.models.mixins import AccessFormData
-from opentech.apply.review.options import YES, NO, MAYBE, RECOMMENDATION_CHOICES, OPINION_CHOICES, VISIBILITY, PRIVATE, REVIEWER
 from opentech.apply.stream_forms.models import BaseStreamForm
 from opentech.apply.users.models import User
 
@@ -21,7 +21,7 @@ from .blocks import (
     ScoreFieldBlock,
     VisibilityBlock,
 )
-from .options import NA
+from .options import NA, YES, NO, MAYBE, RECOMMENDATION_CHOICES, OPINION_CHOICES, VISIBILITY, PRIVATE, REVIEWER
 
 
 class ReviewFormFieldsMixin(models.Model):
@@ -172,13 +172,9 @@ class Review(ReviewFormFieldsMixin, BaseStreamForm, AccessFormData, models.Model
     def get_compare_url(self):
         return self.revision.get_compare_url_to_latest()
 
-    @classmethod
-    def visibility_for(cls, user):
-        if user.is_apply_staff:
-            return [PRIVATE, REVIEWER]
-        if user.is_reviewer:
-            return [REVIEWER]
-        return [PRIVATE]
+    @cached_property
+    def reviewer_visibility(self):
+        return self.visibility == REVIEWER
 
 
 @receiver(post_save, sender=Review)
diff --git a/opentech/apply/review/views.py b/opentech/apply/review/views.py
index b73244785370b8f037bbb58743b6c3aa6df1bf65..611de4fb3398ba59b499b54e073316a0b65cca47 100644
--- a/opentech/apply/review/views.py
+++ b/opentech/apply/review/views.py
@@ -169,9 +169,10 @@ class ReviewDisplay(DetailView):
 
     def dispatch(self, request, *args, **kwargs):
         review = self.get_object()
+        user = request.user
         author = review.author
 
-        if request.user != author and not request.user.is_superuser and not request.user.is_apply_staff:
+        if user != author and not (user.is_reviewer and review.reviewer_visibility) and not user.is_apply_staff:
             raise PermissionDenied
 
         if review.is_draft: