diff --git a/synapse/handlers/_base.py b/synapse/handlers/_base.py
index d8d86d6ff3fb2397a4e5e56553dc1a0e2ca0e225..ac09d03ba9ad1124003f57a2a30641a9caff86dc 100644
--- a/synapse/handlers/_base.py
+++ b/synapse/handlers/_base.py
@@ -165,6 +165,7 @@ class BaseHandler(object):
                     member_event.room_id,
                     "leave",
                     ratelimit=False,
+                    require_consent=False,
                 )
             except Exception as e:
                 logger.exception("Error kicking guest user: %s" % (e,))
diff --git a/synapse/handlers/deactivate_account.py b/synapse/handlers/deactivate_account.py
index 75fe50c42c82cccaeb8789af5feb66f85c3c72a4..97d3f31d9887204c703e5e65b4a3a44f2facb838 100644
--- a/synapse/handlers/deactivate_account.py
+++ b/synapse/handlers/deactivate_account.py
@@ -164,6 +164,7 @@ class DeactivateAccountHandler(BaseHandler):
                     room_id,
                     "leave",
                     ratelimit=False,
+                    require_consent=False,
                 )
             except Exception:
                 logger.exception(
diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py
index 345a3e0ecd423836bf46988504e3595a1f256f00..587fbfbe86320064f88ffd2177732e85ecffebef 100644
--- a/synapse/handlers/message.py
+++ b/synapse/handlers/message.py
@@ -255,7 +255,7 @@ class EventCreationHandler(object):
 
     @defer.inlineCallbacks
     def create_event(self, requester, event_dict, token_id=None, txn_id=None,
-                     prev_events_and_hashes=None):
+                     prev_events_and_hashes=None, require_consent=True):
         """
         Given a dict from a client, create a new event.
 
@@ -276,6 +276,9 @@ class EventCreationHandler(object):
                 where *hashes* is a map from algorithm to hash.
 
                 If None, they will be requested from the database.
+
+            require_consent (bool): Whether to check if the requester has
+                consented to privacy policy.
         Raises:
             ResourceLimitError if server is blocked to some resource being
             exceeded
@@ -317,7 +320,7 @@ class EventCreationHandler(object):
                     )
 
         is_exempt = yield self._is_exempt_from_privacy_policy(builder, requester)
-        if not is_exempt:
+        if require_consent and not is_exempt:
             yield self.assert_accepted_privacy_policy(requester)
 
         if token_id is not None:
@@ -388,17 +391,6 @@ class EventCreationHandler(object):
         if self._block_events_without_consent_error is None:
             return
 
-        # exempt AS users from needing consent
-        if requester.app_service is not None:
-            return
-
-        # Check if the user has accepted the privacy policy. We only do this if
-        # the requester has an associated access_token_id, which indicates that
-        # this action came from a user request rather than an automatice server
-        # or admin action.
-        if requester.access_token_id is None:
-            return
-
         user_id = requester.user.to_string()
 
         # exempt the system notices user
diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py
index aead9e4608e3df9ab4df1b5f957c4f8a05333313..71ce5b54e50f7c259d836476c3ea5c8ecc3d6d7b 100644
--- a/synapse/handlers/room_member.py
+++ b/synapse/handlers/room_member.py
@@ -160,6 +160,7 @@ class RoomMemberHandler(object):
         txn_id=None,
         ratelimit=True,
         content=None,
+        require_consent=True,
     ):
         user_id = target.to_string()
 
@@ -185,6 +186,7 @@ class RoomMemberHandler(object):
             token_id=requester.access_token_id,
             txn_id=txn_id,
             prev_events_and_hashes=prev_events_and_hashes,
+            require_consent=require_consent,
         )
 
         # Check if this event matches the previous membership event for the user.
@@ -305,6 +307,7 @@ class RoomMemberHandler(object):
             third_party_signed=None,
             ratelimit=True,
             content=None,
+            require_consent=True,
     ):
         key = (room_id,)
 
@@ -319,6 +322,7 @@ class RoomMemberHandler(object):
                 third_party_signed=third_party_signed,
                 ratelimit=ratelimit,
                 content=content,
+                require_consent=require_consent,
             )
 
         defer.returnValue(result)
@@ -335,6 +339,7 @@ class RoomMemberHandler(object):
             third_party_signed=None,
             ratelimit=True,
             content=None,
+            require_consent=True,
     ):
         content_specified = bool(content)
         if content is None:
@@ -516,6 +521,7 @@ class RoomMemberHandler(object):
             ratelimit=ratelimit,
             prev_events_and_hashes=prev_events_and_hashes,
             content=content,
+            require_consent=require_consent,
         )
         defer.returnValue(res)
 
diff --git a/synapse/rest/client/v1/admin.py b/synapse/rest/client/v1/admin.py
index 56ad65515a96ea4e7e35fb635f1aa610db922894..e78876963925c4ced71ea9b11a2bfde9106cee16 100644
--- a/synapse/rest/client/v1/admin.py
+++ b/synapse/rest/client/v1/admin.py
@@ -516,7 +516,8 @@ class ShutdownRoomRestServlet(ClientV1RestServlet):
                     room_id=room_id,
                     action=Membership.LEAVE,
                     content={},
-                    ratelimit=False
+                    ratelimit=False,
+                    require_consent=False,
                 )
 
                 yield self.room_member_handler.forget(target_requester.user, room_id)
@@ -527,7 +528,8 @@ class ShutdownRoomRestServlet(ClientV1RestServlet):
                     room_id=new_room_id,
                     action=Membership.JOIN,
                     content={},
-                    ratelimit=False
+                    ratelimit=False,
+                    require_consent=False,
                 )
 
                 kicked_users.append(user_id)