diff --git a/src/backoffice/forms.py b/src/backoffice/forms.py
index e211c295b2811608523cb20bbac3b89daf2ea2de..1ddb05345dd80e3d5d4153fdd30e7b7466e5d150 100644
--- a/src/backoffice/forms.py
+++ b/src/backoffice/forms.py
@@ -126,6 +126,11 @@ class AssemblyEditForm(forms.ModelForm):
         # call original .clean() which e.g. removes 'slug' from cleaned_data if that isn't a slug
         super().clean()
 
+        # ensure assembly is either a channel or an assembly
+        if self.cleaned_data.get('state_assembly') == Assembly.State.NONE and self.cleaned_data.get('state_channel') == Assembly.State.NONE:
+            self.add_error('state_assembly', _('Assembly__states_must_not_be_none'))
+            self.add_error('state_channel', _('Assembly__states_must_not_be_none'))
+
         # slug must not already exist in the conference
         slug = self.cleaned_data.get('slug')
         if slug is not None and Assembly.objects.filter(conference=self.instance.conference, slug=slug).exclude(pk=self.instance.pk).exists():
diff --git a/src/backoffice/locale/de/LC_MESSAGES/django.po b/src/backoffice/locale/de/LC_MESSAGES/django.po
index 3b8348d13a5a80e3e3f97b08054bb15938b83841..ed050947c6b1200740614f04665a14ced2e75c39 100644
--- a/src/backoffice/locale/de/LC_MESSAGES/django.po
+++ b/src/backoffice/locale/de/LC_MESSAGES/django.po
@@ -545,6 +545,9 @@ msgstr "Übersicht"
 msgid "nav_assemblies"
 msgstr "Assembly-Team"
 
+msgid "nav_channels"
+msgstr "Channels-Team"
+
 msgid "nav_users"
 msgstr "Teilnehmer"
 
@@ -901,6 +904,21 @@ msgstr ""
 msgid "UserCommunicationChannel__address"
 msgstr ""
 
+msgid "nav_channels_all"
+msgstr "alle"
+
+msgid "nav_channels_accepted"
+msgstr "akzeptiert"
+
+msgid "nav_channels_pending"
+msgstr "wartend"
+
+msgid "nav_channels_planned"
+msgstr "geplant"
+
+msgid "nav_channels_rejected"
+msgstr "abgelehnt"
+
 msgid "backoffice:assembly-organisational-data"
 msgstr "Organisatorisches"
 
diff --git a/src/backoffice/locale/en/LC_MESSAGES/django.po b/src/backoffice/locale/en/LC_MESSAGES/django.po
index 2586b84e04eabc5b857b4aefacbc0c1ca894788a..198043ad86366eb491bbf6a8a14ee5aa70ede5b2 100644
--- a/src/backoffice/locale/en/LC_MESSAGES/django.po
+++ b/src/backoffice/locale/en/LC_MESSAGES/django.po
@@ -546,6 +546,9 @@ msgstr "Home"
 msgid "nav_assemblies"
 msgstr "assemblies team"
 
+msgid "nav_channels"
+msgstr "channels team"
+
 msgid "nav_users"
 msgstr "users"
 
@@ -901,6 +904,21 @@ msgstr ""
 msgid "UserCommunicationChannel__address"
 msgstr ""
 
+msgid "nav_channels_all"
+msgstr "all"
+
+msgid "nav_channels_accepted"
+msgstr "accepted"
+
+msgid "nav_channels_pending"
+msgstr "pending"
+
+msgid "nav_channels_planned"
+msgstr "planned"
+
+msgid "nav_channels_rejected"
+msgstr "rejected"
+
 msgid "backoffice:assembly-organisational-data"
 msgstr "Organisational Data"
 
diff --git a/src/backoffice/static/backoffice.css b/src/backoffice/static/backoffice.css
index 53fff09e9e385113f43a3f4c1866470141239d28..2d06111ba1a3b0246cd896f39b116ed12f1785c3 100644
--- a/src/backoffice/static/backoffice.css
+++ b/src/backoffice/static/backoffice.css
@@ -2,6 +2,7 @@
     display: flex;
     width: 100%;
     align-items: stretch;
+    min-height: calc(100vh - 56px);
 }
 
 .legal-footer {
@@ -21,7 +22,7 @@
 }
 
 #sidebar .list-group-item,
-#sidebar .list-group-item > a { 
+#sidebar .list-group-item > a {
     align-items: center;
     background: #7386D5;
     border: none;
@@ -29,13 +30,13 @@
     display: flex;
 }
 
-#sidebar .list-group-item.active, 
+#sidebar .list-group-item.active,
 #sidebar .list-group-item.active a {
     color: #ff0;
     font-weight: bold;
 }
 
-#sidebar .list-group-item.child, 
+#sidebar .list-group-item.child,
 #sidebar .list-group-item.child a {
     background: #6d7fcc;
 }
diff --git a/src/backoffice/templates/backoffice/assembly_auth.html b/src/backoffice/templates/backoffice/assembly_auth.html
index d836514b443d81664107afd9c8b397309dbbcf78..f9315bf8498ae420f0098642704169a17e91217b 100644
--- a/src/backoffice/templates/backoffice/assembly_auth.html
+++ b/src/backoffice/templates/backoffice/assembly_auth.html
@@ -31,7 +31,7 @@
   </div>
 </div>
 
-<div class="row mt-3">
+<div class="row mt-3 pb-10rem">
   <div class="col-md-12">
     <div class="card border-primary">
       <div class="card-header bg-primary text-white">
@@ -72,4 +72,4 @@
     </form>
   </div>
 </div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/src/backoffice/templates/backoffice/assembly_edit.html b/src/backoffice/templates/backoffice/assembly_edit.html
index 6196f384aaab18ff9f87f189447cd23eb7eb9db7..32810db10719d125de3892d7768fa677ec836bef 100644
--- a/src/backoffice/templates/backoffice/assembly_edit.html
+++ b/src/backoffice/templates/backoffice/assembly_edit.html
@@ -35,7 +35,7 @@
         {% if not field.disabled %}
           {% render_field field class+="form-control" %}
         {% else %}
-          <input type="hidden" name="{{ field.name }}" value="{{ field.value }}">{{ field.value }}
+          <input type="hidden" name="{{ field.name }}" value="{{ field.value }}">{% render_field field class+="form-control" disabled="disabled" %}
         {% endif %}
         {% if field.help_text %}
         <small class="form-text text-muted">{{ field.help_text }}</small>
diff --git a/src/backoffice/templates/backoffice/assembly_editlinks.html b/src/backoffice/templates/backoffice/assembly_editlinks.html
index debb0553780072833fb7b90253584f6ae26a411e..79111c38111c971d7ffa1b07d48c2f5d955df1e7 100644
--- a/src/backoffice/templates/backoffice/assembly_editlinks.html
+++ b/src/backoffice/templates/backoffice/assembly_editlinks.html
@@ -37,7 +37,7 @@
   </div>
 </div>
 
-<div class="row">
+<div class="row pb-10rem">
   <div class="col-md-12">
     <div class="card mb-3">
       <div class="card-header">
@@ -65,4 +65,4 @@
 </div>
 {% endwith %}
 
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/src/backoffice/templates/backoffice/assembly_members.html b/src/backoffice/templates/backoffice/assembly_members.html
index cabe71263e0aecece3fb46b7105276a58a46e1ed..34b6ebe7030cc60ee3446da9076b82685ba34a9f 100644
--- a/src/backoffice/templates/backoffice/assembly_members.html
+++ b/src/backoffice/templates/backoffice/assembly_members.html
@@ -9,7 +9,7 @@
 {% block content %}
 {% include "backoffice/assembly_edit_header.html" %}
 
-<div class="row pb-5">
+<div class="row pb-10rem">
   <div class="col-md-12">
     <div class="card border-default">
       <div class="card-header bg-default">
@@ -51,10 +51,10 @@
               <td>{% if member.show_public %}S{% else %}-{% endif %}</td>
               {% if can_manage %}<td>
                 <a class="btn btn-secondary btn-sm" href="{% url 'backoffice:assembly-members-edit' pk=assembly.id uname=member.member.username %}">{% trans 'Assembly__members__edit' %}</a>
-                <input 
-                    type="submit" 
-                    class="btn btn-default btn-sm" 
-                    name="{% if member.show_public %}hide{% else %}show{% endif %}-{{ member.member.id }}" 
+                <input
+                    type="submit"
+                    class="btn btn-default btn-sm"
+                    name="{% if member.show_public %}hide{% else %}show{% endif %}-{{ member.member.id }}"
                     value="{% if member.show_public %}{% trans 'Assembly__members__hide' %}{% else %}{% trans 'Assembly__members__show' %}{% endif %}">
                 <input type="submit" class="btn btn-default btn-sm" name="delete-{{ member.member.id }}" value="{% trans 'Assembly__members__delete' %}">
               </td>{% endif %}
diff --git a/src/backoffice/templates/backoffice/base.html b/src/backoffice/templates/backoffice/base.html
index c626c6184ea2b90f1432e704c106aecfc44fb280..a7d32af6d6c0d8a8f9b3c645ddc8768b6dac973b 100644
--- a/src/backoffice/templates/backoffice/base.html
+++ b/src/backoffice/templates/backoffice/base.html
@@ -29,6 +29,11 @@
             <a class="nav-link" href="{% url 'backoffice:assemblies' %}">{% trans "nav_assemblies" %}{% if active_page == 'assemblies' %} <span class="sr-only">{{ activetab_srmarker }}</span>{% endif %}</a>
           </li>
           {% endif %}
+          {% if has_channel %}
+          <li class="nav-item{% if active_page == 'channels' %} active{% endif %}">
+            <a class="nav-link" href="{% url 'backoffice:channels' %}">{% trans "nav_channels" %}{% if active_page == 'channels' %} <span class="sr-only">{{ activetab_srmarker }}</span>{% endif %}</a>
+          </li>
+          {% endif %}
           {% if has_users %}
           <li class="nav-item{% if active_page == 'users' %} active{% endif %}">
             <a class="nav-link" href="{% url 'backoffice:users' %}">{% trans "nav_users" %}{% if active_page == 'users' %} <span class="sr-only">{{ activetab_srmarker }}</span>{% endif %}</a>
diff --git a/src/backoffice/urls.py b/src/backoffice/urls.py
index 6420101d079918df378d657d781482c072fdac78..03a4aa2f64895c522881fbbab047a313881134c1 100644
--- a/src/backoffice/urls.py
+++ b/src/backoffice/urls.py
@@ -4,6 +4,7 @@ from .views import \
     assemblies, \
     assemblyteam, \
     auth, \
+    channelteam, \
     events, \
     misc, \
     pages, \
@@ -45,6 +46,8 @@ urlpatterns = [
 
     path('assemblies', assemblyteam.AssembliesView.as_view(), name='assemblies'),
     path('assemblies/list/<str:variant>', assemblyteam.AssembliesListsView.as_view(), name='assemblieslist'),
+    path('channels', channelteam.ChannelsView.as_view(), name='channels'),
+    path('channels/list/<str:variant>', channelteam.ChannelsListView.as_view(), name='channelslist'),
 
     path('assembly/create', assemblies.CreateAssemblyView.as_view(), name='assembly-create'),
     path('assembly/<uuid:pk>', assemblies.AssemblyView.as_view(), name='assembly'),
diff --git a/src/backoffice/views/assemblies.py b/src/backoffice/views/assemblies.py
index e83022d22057323ff050dabbe539da79f4823943..96409a3c4f6d56c921367cd8d8189920ad18235c 100644
--- a/src/backoffice/views/assemblies.py
+++ b/src/backoffice/views/assemblies.py
@@ -90,12 +90,20 @@ class EditAssemblyView(AssemblyMixin, UpdateView):
             form['is_virtual'].disabled = True
 
         if not self.staff_access:
-            form['state_assembly'].disabled = True
-            form['state_channel'].disabled = True
             for x in AssemblyEditForm.Meta.staff_fields:
                 if x in form.fields:
                     del(form.fields[x])
 
+        # disable assembly-related field editing for everyone except assembly team
+        if not self.assembly_staff_access:
+            form['state_assembly'].disabled = True
+            # but allow setting 'is_official' if only the channel team has access
+            form['is_official'].disabled = not (self.assembly.state_assembly == Assembly.State.NONE and self.channel_staff_access)
+
+        # disable channel state editing for everyone except channel team
+        if not self.channel_staff_access:
+            form['state_channel'].disabled = True
+
         return form
 
     def form_valid(self, form):
@@ -128,6 +136,8 @@ class EditAssemblyView(AssemblyMixin, UpdateView):
             assembly.add_tag(tag, autocreate=True)
         if assembly.state_assembly == Assembly.State.PLANNED:
             assembly.state_assembly = Assembly.State.REGISTERED
+        if assembly.state_channel == Assembly.State.PLANNED:
+            assembly.state_channel = Assembly.State.REGISTERED
 
         if assembly.hierarchy == Assembly.Hierarchy.REGULAR:
             parent_id = form.cleaned_data.get('parent_id', '') if self.conference.support_clusters else None
diff --git a/src/backoffice/views/assemblyteam.py b/src/backoffice/views/assemblyteam.py
index 8258b870642375974c90c5872a4535a045daaab4..f6a56c552c02f2f5636588c6e515b982ecd4b6aa 100644
--- a/src/backoffice/views/assemblyteam.py
+++ b/src/backoffice/views/assemblyteam.py
@@ -23,6 +23,10 @@ logger = logging.getLogger(__name__)
 class AssemblyTeamMixin(ConferenceMixin):
     require_conference = True
     permission_required = ['core.assembly_team']
+    active_page = 'assemblies'
+    base_view_name = 'backoffice:assemblies'
+    list_view_name = 'backoffice:assemblieslist'
+    sidebar_caption = _("nav_assemblies")
 
     MODES = {
         'all': (Q(), _('nav_assemblies_all')),
@@ -34,13 +38,14 @@ class AssemblyTeamMixin(ConferenceMixin):
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
-        context['active_page'] = 'assemblies'
+        context['active_page'] = self.active_page
+        self.request.session['assembly_back'] = {'link': self.request.get_full_path(), 'title': str(self.sidebar_caption)}
 
         assemblies = []
         lists = []
         context['sidebar'] = {
-            'title': _('nav_assemblies'),
-            # 'title_link': reverse('backoffice:assemblies'),
+            'title': self.sidebar_caption,
+            # 'title_link': reverse(self.base_view_name),
             'items': [
                 {
                     'caption': _('Assemblys'),
@@ -57,24 +62,28 @@ class AssemblyTeamMixin(ConferenceMixin):
 
         for m, (q, t) in self.MODES.items():
             assemblies.append({
+                'mode': m,
                 'caption': t,
                 'count': self.conference.assemblies.filter(q).count(),
-                'link': reverse('backoffice:assemblies') + '?mode=' + m,
+                'link': reverse(self.base_view_name) + '?mode=' + m,
             })
 
         lists.append({
             'caption': format_lazy('{accepted}: slug+name', accepted=_('nav_assemblies_accepted')),
-            'link': reverse('backoffice:assemblieslist', kwargs={'variant': 'slugname'}) + '?mode=accepted',
+            'link': reverse(self.list_view_name, kwargs={'variant': 'slugname'}) + '?mode=accepted',
+            'variant': 'slugname',
         })
 
         lists.append({
             'caption': format_lazy('{accepted}: contacts', accepted=_('nav_assemblies_accepted')),
-            'link': reverse('backoffice:assemblieslist', kwargs={'variant': 'assemblycontacts'}) + '?mode=accepted',
+            'link': reverse(self.list_view_name, kwargs={'variant': 'assemblycontacts'}) + '?mode=accepted',
+            'variant': 'assemblycontacts',
         })
 
         lists.append({
             'caption': format_lazy('{accepted}: contact mails', accepted=_('nav_assemblies_accepted')),
-            'link': reverse('backoffice:assemblieslist', kwargs={'variant': 'contactsmail'}) + '?mode=accepted',
+            'link': reverse(self.list_view_name, kwargs={'variant': 'contactsmail'}) + '?mode=accepted',
+            'variant': 'contactsmail',
         })
 
         return context
@@ -86,6 +95,13 @@ class AssembliesListMixin(AssemblyTeamMixin):
     def get_queryset(self, **kwargs):
         # not using .accessible_by_user() here as we're the Assembly Team anyway
         qs = Assembly.objects.filter(conference=self.conference)
+        if self.active_page == 'assemblies':
+            qs = qs.exclude(state_assembly=Assembly.State.NONE)
+        elif self.active_page == 'channels':
+            qs = qs.exclude(state_channel=Assembly.State.NONE)
+        else:
+            logging.warning('AssembliesListMixin: unexpected active_page="%s"', self.active_page)
+            qs = Assembly.objects.none()
 
         # mode selection
         mode = (self.request.POST if self.request.method == 'POST' else self.request.GET).get('mode', self.default_assemblies_mode)
@@ -111,6 +127,12 @@ class AssembliesView(AssembliesListMixin, ListView):
         context['mode'] = self.assemblies_mode
         context['mode_display'] = self.MODES[self.assemblies_mode][1]
 
+        # activate current sidebar item
+        for sidebar_item in context['sidebar']['items'][0]['children']:
+            if sidebar_item['mode'] == self.assemblies_mode:
+                sidebar_item['active'] = True
+                break
+
         for obj in context['object_list']:
             obj.user_can_edit = property(lambda x: x.user_can_manage(self.request.user, staff_can_manage=True))
 
@@ -211,6 +233,12 @@ class AssembliesListsView(AssembliesListMixin, View):
         ctx['fields'] = variant_fields
         ctx['data'] = data
 
+        # activate current sidebar item
+        for sidebar_item in ctx['sidebar']['items'][1]['children']:
+            if sidebar_item['variant'] == variant:
+                sidebar_item['active'] = True
+                break
+
         ctx['download_available'] = len(data) > 0
         ctx['download_default_delimiter'] = self.DEFAULT_DELIMITER_CHAR
         ctx['download_default_quotechar'] = self.DEFAULT_QUOTE_CHAR
diff --git a/src/backoffice/views/channelteam.py b/src/backoffice/views/channelteam.py
new file mode 100644
index 0000000000000000000000000000000000000000..e996f98db465b707ef74e50d7ba617d9b2e836d9
--- /dev/null
+++ b/src/backoffice/views/channelteam.py
@@ -0,0 +1,30 @@
+from django.utils.translation import gettext_lazy as _
+from django.db.models import Q
+
+from core.models.assemblies import Assembly
+
+from .assemblyteam import AssembliesView, AssembliesListsView
+
+
+class ChannelsMixin:
+    """ sets options that configure the Assemblies views to work in Channels mode """
+    MODES = {
+        'all': (Q(), _('nav_channels_all')),
+        'accepted': (Q(state_channel__in=Assembly.PUBLIC_STATES), _('nav_channels_accepted')),
+        'pending': (Q(state_channel__in=[Assembly.State.REGISTERED]), _('nav_channels_pending')),
+        'planned': (Q(state_channel__in=[Assembly.State.PLANNED]), _('nav_channels_planned')),
+        'rejected': (Q(state_channel__in=[Assembly.State.REJECTED, Assembly.State.HIDDEN]), _('nav_channels_rejected')),
+    }
+    permission_required = ['core.channel_team']
+    active_page = 'channels'
+    base_view_name = 'backoffice:channels'
+    list_view_name = 'backoffice:channelslist'
+    sidebar_caption = _("nav_channels")
+
+
+class ChannelsView(ChannelsMixin, AssembliesView):
+    pass
+
+
+class ChannelsListView(ChannelsMixin, AssembliesListsView):
+    pass
diff --git a/src/backoffice/views/misc.py b/src/backoffice/views/misc.py
index c5f350e8e3af640f6abe93318dfd9307c258b994..e995f2f290320ba05fef2fd8c0d77476c225b366 100644
--- a/src/backoffice/views/misc.py
+++ b/src/backoffice/views/misc.py
@@ -43,6 +43,9 @@ class IndexView(ConferenceMixin, View):
     def get(self, *args, **kwargs):
         if self.request.user.is_authenticated:
             myassemblies = list(Assembly.objects.associated_to_user(conference=self.conference, user=self.request.user))
+
+            # remove stored backlink for assembly pages from the session if it is set, so the backlink will go to the overview, which is the default
+            self.request.session.pop('assembly_back', None)
         else:
             myassemblies = None
 
diff --git a/src/backoffice/views/mixins.py b/src/backoffice/views/mixins.py
index eea0265eaffe894bf0c43a6b429de8bd53e2857e..a152c06b213f81fd2c8bfd491829fa4894b1c644 100644
--- a/src/backoffice/views/mixins.py
+++ b/src/backoffice/views/mixins.py
@@ -63,6 +63,10 @@ class ConferenceMixin(PermissionRequiredMixin):
     def is_assembly_team(self):
         return self.request.user.has_conference_staffpermission(self.conference, 'core.assembly_team')
 
+    @property
+    def is_channel_team(self):
+        return self.request.user.has_conference_staffpermission(self.conference, 'core.channel_team')
+
     def dispatch(self, request, *args, **kwargs):
         if self.require_conference and self.conference is None:
             return redirect('conference_selection')
@@ -91,6 +95,7 @@ class ConferenceMixin(PermissionRequiredMixin):
         if self.request.user.is_authenticated:
             context.update({
                 'has_assemblies': self.is_assembly_team,
+                'has_channel': self.is_channel_team,
                 'has_pages': self.request.user.has_conference_staffpermission(self.conference, 'core.static_pages'),
                 'has_users': self.request.user.has_conference_staffpermission(self.conference, 'core.platformusers'),
                 'has_schedules': self.request.user.has_conference_staffpermission(self.conference, 'core.scheduleadmin'),
@@ -99,6 +104,7 @@ class ConferenceMixin(PermissionRequiredMixin):
         else:
             context.update({
                 'has_assemblies': False,
+                'has_channel': False,
                 'has_pages': False,
                 'has_users': False,
                 'has_schedules': False,
@@ -126,9 +132,19 @@ class AssemblyMixin(LoginRequiredMixin, ConferenceMixin, SingleObjectMixin):
 
         super().__init__(*args, **kwargs)
 
+        # if _can_manage is set, user can edit assembly. This is a cache variable for the can_manage property
         self._can_manage = None
+        # if _staff_access is set, extra staff fields can be modified (internal comment, is_official)
         self._staff_access = False
-        self._staff_mode = None
+        # if _assembly_staff_access is set, the field state_assembly can be modified
+        self._assembly_staff_access = False
+        # if _channels_staff_access is set, the field state_channel can be modified
+        self._channels_staff_access = False
+
+        # configures the staff warning
+        self._staff_mode = False
+
+        # ensure self.object is present
         if not hasattr(self, 'object'):
             self.object = property(self._get_assembly)
 
@@ -140,12 +156,19 @@ class AssemblyMixin(LoginRequiredMixin, ConferenceMixin, SingleObjectMixin):
 
         # check if it's the assembly team
         if self.request.user.has_conference_staffpermission(self.conference, 'assembly_team'):
-            self._staff_access = True
+            self._assembly_staff_access = True
+            self._staff_access = self._staff_access or assembly.state_assembly != Assembly.State.NONE
+            self._staff_mode = True
+
+        # check if it's the channel team
+        if self.request.user.has_conference_staffpermission(self.conference, 'channel_team'):
+            self._channels_staff_access = True
+            self._staff_access = self._staff_access or assembly.state_channel != Assembly.State.NONE
             self._staff_mode = True
 
         # check if the current user is associated as a contact
         if assembly.has_user(self.request.user):
-            self._staff_mode = False
+            # don't set self._staff_mode = False here as this would prevent assembly team members to edit their own assemblies
 
             if not self._staff_access and \
                assembly.state_assembly in [Assembly.State.NONE, Assembly.State.HIDDEN] and \
@@ -153,7 +176,7 @@ class AssemblyMixin(LoginRequiredMixin, ConferenceMixin, SingleObjectMixin):
                 raise Assembly.DoesNotExist()
 
         # neither owner/manager nor assembly team? go away
-        elif not self._staff_access:
+        elif not self._assembly_staff_access and not self._channels_staff_access:
             raise PermissionDenied()
 
         self._assembly = assembly
@@ -179,6 +202,14 @@ class AssemblyMixin(LoginRequiredMixin, ConferenceMixin, SingleObjectMixin):
     def staff_access(self):
         return self._staff_access
 
+    @property
+    def assembly_staff_access(self):
+        return self._assembly_staff_access
+
+    @property
+    def channel_staff_access(self):
+        return self._channels_staff_access
+
     @property
     def staff_mode(self):
         return self._staff_mode
@@ -206,8 +237,12 @@ class AssemblyMixin(LoginRequiredMixin, ConferenceMixin, SingleObjectMixin):
             'items': sidebar,
         }
 
-        if self.staff_mode:
-            context['sidebar']['back_link'] = {'link': reverse('backoffice:assemblies'), 'caption': _('nav_assemblies')}
+        # load backlink from the session if it set. Set by Assemblyteam / Channelsteam pages as there are a bunch of
+        # pages that will link to assembly views
+        if 'assembly_back' in self.request.session:
+            assembly_back = self.request.session['assembly_back']
+            if 'link' in assembly_back and 'title' in assembly_back:
+                context['sidebar']['back_link'] = {'link': assembly_back['link'], 'caption': assembly_back['title']}
 
         organisation = []
         sidebar.append({'caption': _('backoffice:assembly-organisational-data'), 'children': organisation})
diff --git a/src/core/locale/de/LC_MESSAGES/django.po b/src/core/locale/de/LC_MESSAGES/django.po
index 3dd97efba4264f33b02e344a0ca15d7ad5bf5e0a..7dad9e681166152bcb9e6862b7bb53cd76c48b52 100644
--- a/src/core/locale/de/LC_MESSAGES/django.po
+++ b/src/core/locale/de/LC_MESSAGES/django.po
@@ -255,6 +255,9 @@ msgstr "Die Assembly muss einen Typ haben (zumindest eins von physisch/virtuell/
 msgid "Assembly__technical_user__must_be_assembly"
 msgstr "Der technische Benutzer muss vom Typ 'Assembly' sein."
 
+msgid "Assembly__states_must_not_be_none"
+msgstr "Assemblystate oder Channelstate muss gesetzt sein!"
+
 msgid "Assembly__slug__is_forbidden"
 msgstr "Dieser Kurzname ist verboten!"
 
@@ -381,6 +384,9 @@ msgstr "Art/Verwendung"
 msgid "ConferenceMember__permission-assembly_team"
 msgstr "Assembly-Team: alle Assemblies verwaltbar, auch noch nicht fertig angelegte und abgelehnte sind sichtbar"
 
+msgid "ConferenceMember__permission-channel_team"
+msgstr "Channel-Team: alle Assemblies verwaltbar, auch noch nicht fertig angelegte und abgelehnte sind sichtbar"
+
 msgid "ConferenceMember__permission-static_pages"
 msgstr "Statische Seiten: Verwaltung von Info-Seiten"
 
diff --git a/src/core/locale/en/LC_MESSAGES/django.po b/src/core/locale/en/LC_MESSAGES/django.po
index b4a7655850a23dc0739330483e6856636b7832a9..62b73f72e1abfe58c9d8f43659f22b751b977d9f 100644
--- a/src/core/locale/en/LC_MESSAGES/django.po
+++ b/src/core/locale/en/LC_MESSAGES/django.po
@@ -255,6 +255,9 @@ msgstr "The assembly requires a type (at least one of physical/virtual/remote)."
 msgid "Assembly__technical_user__must_be_assembly"
 msgstr "The technical user must be of type 'assembly'."
 
+msgid "Assembly__states_must_not_be_none"
+msgstr "assembly state or channel state must be set!"
+
 msgid "Assembly__slug__is_forbidden"
 msgstr "this short name is forbidden"
 
@@ -379,7 +382,10 @@ msgid "BadgeToken__badge_class"
 msgstr "class"
 
 msgid "ConferenceMember__permission-assembly_team"
-msgstr "assembly team: manage all assemblies, see also incomplete and rejected registrations"
+msgstr "assemblies team: manage all assemblies, see also incomplete and rejected registrations"
+
+msgid "ConferenceMember__permission-channel_team"
+msgstr "channel team: manage all assemblies, see also incomplete and rejected registrations"
 
 msgid "ConferenceMember__permission-static_pages"
 msgstr "static pages: manage information pages"
diff --git a/src/core/migrations/0074_channel_team_permission.py b/src/core/migrations/0074_channel_team_permission.py
new file mode 100644
index 0000000000000000000000000000000000000000..681c61803987ff4d6fc016d31e2400df43d333a1
--- /dev/null
+++ b/src/core/migrations/0074_channel_team_permission.py
@@ -0,0 +1,17 @@
+# Generated by Django 3.2.10 on 2021-12-16 23:06
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0073_alter_room_assembly'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='conferencemember',
+            options={'permissions': [('assembly_team', 'ConferenceMember__permission-assembly_team'), ('channel_team', 'ConferenceMember__permission-channel_team'), ('static_pages', 'ConferenceMember__permission-static_pages'), ('platformusers', 'Orga: Users List'), ('rename_platformuser', 'Orga: Rename User'), ('block_platformuser', 'ConferenceMember__permission-block_platformuser'), ('change_conferencemember__active_angel', 'ConferenceMember__permission-change_conferencemember__active_angel'), ('view_platformuser__guardian', 'ConferenceMember__permission-view_platformuser__guardian'), ('scheduleadmin', 'ConferenceMember__permission-scheduleadmin'), ('workadventure_admin', 'ConferenceMember__permission-workadventure_admin')]},
+        ),
+    ]
diff --git a/src/core/models/assemblies.py b/src/core/models/assemblies.py
index c530ffa3f14d456dc7e665459c32b511b9f7a321..6756f2d2eb9bb86a10dac58d8a3a99450a25511d 100644
--- a/src/core/models/assemblies.py
+++ b/src/core/models/assemblies.py
@@ -374,7 +374,7 @@ class Assembly(TaggedItemMixin, models.Model):
         if not user.is_authenticated:
             return False
 
-        if staff_can_manage and user.has_conference_staffpermission(self.conference, 'assembly_team'):
+        if staff_can_manage and user.has_conference_staffpermission(self.conference, 'assembly_team', 'channel_team'):
             return True
 
         return self.members.filter(member=user, can_manage_assembly=True).exists()
diff --git a/src/core/models/conference.py b/src/core/models/conference.py
index 7766e1841b0fedb188075430c4913f0c118a0b51..f22452d8c9addd5da476104a42c2e0dc11b524f7 100644
--- a/src/core/models/conference.py
+++ b/src/core/models/conference.py
@@ -34,6 +34,9 @@ class ConferenceMember(models.Model):
             ('assembly_team', _('ConferenceMember__permission-assembly_team')),
             # See all assemblies, not only the accepted ones.
 
+            ('channel_team', _("ConferenceMember__permission-channel_team")),
+            # Channelteam, Assemblyteam for Channel-Type Assemblies (Assemblies that provide their own content)
+
             ('static_pages', _('ConferenceMember__permission-static_pages')),
             # Access to static pages, can be further limited by configuring static_page_groups.