diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetCamBroadcastPermissionReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetCamBroadcastPermissionReqMsgHdlr.scala
new file mode 100755
index 0000000000000000000000000000000000000000..900665c6b0606f94387dc3fed4cf47848f64c3f1
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetCamBroadcastPermissionReqMsgHdlr.scala
@@ -0,0 +1,34 @@
+package org.bigbluebutton.core2.message.handlers
+
+import org.bigbluebutton.common2.msgs._
+import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
+import org.bigbluebutton.core.models.{ Users2x, Webcams }
+import org.bigbluebutton.core2.message.senders.MsgBuilder
+
+trait GetCamBroadcastPermissionReqMsgHdlr {
+  this: MeetingActor =>
+
+  val outGW: OutMsgRouter
+
+  def handleGetCamBroadcastPermissionReqMsg(msg: GetCamBroadcastPermissionReqMsg) {
+    var allowed = false
+
+    for {
+      user <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId)
+    } yield {
+      if (!user.userLeftFlag.left
+        && user.authed
+        && liveMeeting.props.meetingProp.intId == msg.body.meetingId) {
+        allowed = true
+      }
+    }
+
+    val event = MsgBuilder.buildGetCamBroadcastPermissionRespMsg(
+      liveMeeting.props.meetingProp.intId,
+      msg.body.userId,
+      msg.body.sfuSessionId,
+      allowed
+    )
+    outGW.send(event)
+  }
+}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetCamSubscribePermissionReqMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetCamSubscribePermissionReqMsgHdlr.scala
new file mode 100755
index 0000000000000000000000000000000000000000..a89260ff2bc0f077e4c2b9783ac3b11bf72f9f0e
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/users/GetCamSubscribePermissionReqMsgHdlr.scala
@@ -0,0 +1,42 @@
+package org.bigbluebutton.core2.message.handlers
+
+import org.bigbluebutton.common2.msgs._
+import org.bigbluebutton.core.running.{ MeetingActor, OutMsgRouter }
+import org.bigbluebutton.core.models.{ Users2x, Webcams }
+import org.bigbluebutton.core2.message.senders.MsgBuilder
+
+trait GetCamSubscribePermissionReqMsgHdlr {
+  this: MeetingActor =>
+
+  val outGW: OutMsgRouter
+
+  def handleGetCamSubscribePermissionReqMsg(msg: GetCamSubscribePermissionReqMsg) {
+    var allowed = false
+
+    for {
+      user <- Users2x.findWithIntId(liveMeeting.users2x, msg.body.userId)
+    } yield {
+      if (!user.userLeftFlag.left
+        && user.authed
+        && liveMeeting.props.meetingProp.intId == msg.body.meetingId) {
+        Webcams.findWithStreamId(liveMeeting.webcams, msg.body.streamId) match {
+          case Some(stream) => {
+            allowed = true
+          }
+          case None => {
+            allowed = false
+          }
+        }
+      }
+    }
+
+    val event = MsgBuilder.buildGetCamSubscribePermissionRespMsg(
+      liveMeeting.props.meetingProp.intId,
+      msg.body.userId,
+      msg.body.streamId,
+      msg.body.sfuSessionId,
+      allowed
+    )
+    outGW.send(event)
+  }
+}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala
index 786102eb92564525358f86e84fc579832722d33e..d672d08574075efe40f1b907c6602dc8beccec11 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala
@@ -118,6 +118,10 @@ class ReceivedJsonMsgHandlerActor(
         routeGenericMsg[UserBroadcastCamStartMsg](envelope, jsonNode)
       case UserBroadcastCamStopMsg.NAME =>
         routeGenericMsg[UserBroadcastCamStopMsg](envelope, jsonNode)
+      case GetCamBroadcastPermissionReqMsg.NAME =>
+        routeGenericMsg[GetCamBroadcastPermissionReqMsg](envelope, jsonNode)
+      case GetCamSubscribePermissionReqMsg.NAME =>
+        routeGenericMsg[GetCamSubscribePermissionReqMsg](envelope, jsonNode)
 
       // Voice
       case RecordingStartedVoiceConfEvtMsg.NAME =>
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
index f58b6825e27677796696061242b6192ff7b7b853..d160ff77e9f9f568c1a664cdc9ae6497d3882e75 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
@@ -77,6 +77,8 @@ class MeetingActor(
   with GetGlobalAudioPermissionReqMsgHdlr
   with GetScreenBroadcastPermissionReqMsgHdlr
   with GetScreenSubscribePermissionReqMsgHdlr
+  with GetCamBroadcastPermissionReqMsgHdlr
+  with GetCamSubscribePermissionReqMsgHdlr
 
   with EjectUserFromVoiceCmdMsgHdlr
   with EndMeetingSysCmdMsgHdlr
@@ -319,6 +321,9 @@ class MeetingActor(
       case m: UserLeaveReqMsg                     => state = handleUserLeaveReqMsg(m, state)
       case m: UserBroadcastCamStartMsg            => handleUserBroadcastCamStartMsg(m)
       case m: UserBroadcastCamStopMsg             => handleUserBroadcastCamStopMsg(m)
+      case m: GetCamBroadcastPermissionReqMsg     => handleGetCamBroadcastPermissionReqMsg(m)
+      case m: GetCamSubscribePermissionReqMsg     => handleGetCamSubscribePermissionReqMsg(m)
+
       case m: UserJoinedVoiceConfEvtMsg           => handleUserJoinedVoiceConfEvtMsg(m)
       case m: MeetingActivityResponseCmdMsg =>
         state = usersApp.handleMeetingActivityResponseCmdMsg(m, state)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
index 767b3d148298eb8b7f60c898ee7ccd527ae2158f..bb6a4cedd8900f88d40a4c1d8879cb789ad9937e 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
@@ -391,4 +391,47 @@ object MsgBuilder {
 
     BbbCommonEnvCoreMsg(envelope, event)
   }
+
+  def buildGetCamSubscribePermissionRespMsg(
+      meetingId:    String,
+      userId:       String,
+      streamId:     String,
+      sfuSessionId: String,
+      allowed:      Boolean
+  ): BbbCommonEnvCoreMsg = {
+    val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
+    val envelope = BbbCoreEnvelope(GetCamSubscribePermissionRespMsg.NAME, routing)
+    val header = BbbClientMsgHeader(GetCamSubscribePermissionRespMsg.NAME, meetingId, userId)
+    val body = GetCamSubscribePermissionRespMsgBody(
+      meetingId,
+      userId,
+      streamId,
+      sfuSessionId,
+      allowed
+    )
+    val event = GetCamSubscribePermissionRespMsg(header, body)
+
+    BbbCommonEnvCoreMsg(envelope, event)
+  }
+
+  def buildGetCamBroadcastPermissionRespMsg(
+      meetingId:    String,
+      userId:       String,
+      sfuSessionId: String,
+      allowed:      Boolean
+  ): BbbCommonEnvCoreMsg = {
+    val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
+    val envelope = BbbCoreEnvelope(GetCamBroadcastPermissionRespMsg.NAME, routing)
+    val header = BbbClientMsgHeader(GetCamBroadcastPermissionRespMsg.NAME, meetingId, userId)
+
+    val body = GetCamBroadcastPermissionRespMsgBody(
+      meetingId,
+      userId,
+      sfuSessionId,
+      allowed
+    )
+    val event = GetCamBroadcastPermissionRespMsg(header, body)
+
+    BbbCommonEnvCoreMsg(envelope, event)
+  }
 }
diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala
index 0bbffb0cccf62d19e8b5b9d01082740a5724c069..efb1457c0f82485f2c6965c458092579ca145f14 100755
--- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala
+++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/WebcamsMsgs.scala
@@ -50,3 +50,59 @@ case class GetWebcamStreamsRespMsg(header: BbbClientMsgHeader, body: GetWebcamSt
 
 case class GetWebcamStreamsRespMsgBody(webcamStreams: Vector[String])
 
+/* Sent by bbb-webrtc-sfu to ask permission for broadcasting a webcam
+ */
+object GetCamBroadcastPermissionReqMsg { val NAME = "GetCamBroadcastPermissionReqMsg" }
+case class GetCamBroadcastPermissionReqMsg(
+    header: BbbClientMsgHeader,
+    body:   GetCamBroadcastPermissionReqMsgBody
+) extends StandardMsg
+case class GetCamBroadcastPermissionReqMsgBody(
+    meetingId:    String,
+    userId:       String,
+    sfuSessionId: String
+)
+
+/* Sent to bbb-webrtc-sfu to grant or deny webcam broadcasting permission
+ */
+object GetCamBroadcastPermissionRespMsg { val NAME = "GetCamBroadcastPermissionRespMsg" }
+case class GetCamBroadcastPermissionRespMsg(
+    header: BbbClientMsgHeader,
+    body:   GetCamBroadcastPermissionRespMsgBody
+) extends StandardMsg
+case class GetCamBroadcastPermissionRespMsgBody(
+    meetingId:    String,
+    userId:       String,
+    sfuSessionId: String,
+    allowed:      Boolean
+)
+
+/* Sent by bbb-webrtc-sfu to ask permission for subscring to a broadcasted
+ * webcam stream
+ */
+object GetCamSubscribePermissionReqMsg { val NAME = "GetCamSubscribePermissionReqMsg" }
+case class GetCamSubscribePermissionReqMsg(
+    header: BbbClientMsgHeader,
+    body:   GetCamSubscribePermissionReqMsgBody
+) extends StandardMsg
+case class GetCamSubscribePermissionReqMsgBody(
+    meetingId:    String,
+    userId:       String,
+    streamId:     String,
+    sfuSessionId: String
+)
+
+/* Sent to bbb-webrtc-sfu to grant or deny a webcam request
+ */
+object GetCamSubscribePermissionRespMsg { val NAME = "GetCamSubscribePermissionRespMsg" }
+case class GetCamSubscribePermissionRespMsg(
+    header: BbbClientMsgHeader,
+    body:   GetCamSubscribePermissionRespMsgBody
+) extends StandardMsg
+case class GetCamSubscribePermissionRespMsgBody(
+    meetingId:    String,
+    userId:       String,
+    streamId:     String,
+    sfuSessionId: String,
+    allowed:      Boolean
+)