diff --git a/lib/CF/Controller/Users.pm b/lib/CF/Controller/Users.pm
index 6d6ba2c48a524028a35659396dad211b0fe06c22..96bb7e024a14244b2878757376381661da1bf9b0 100644
--- a/lib/CF/Controller/Users.pm
+++ b/lib/CF/Controller/Users.pm
@@ -7,7 +7,23 @@ no warnings qw{ experimental::signatures };
 
 sub me ($c){
     my $user = $c->_get( $c->user->{id} ) // return;
-    $c->render(openapi => $c->spec_filter($user->formatted, 'User'));
+
+    my $formatted = $user->formatted;
+
+    if (
+        ( $user->jitsi_allowed || $user->roles =~ /chairman/ )
+        && $c->cfg->{jitsi_base_url}
+        && $c->cfg->{jitsi_room}
+    ) {
+        $formatted->{jitsi_url} = join ('',
+            $c->cfg->{jitsi_base_url},
+            $c->cfg->{jitsi_room},
+            '?jwt=',
+            $c->jitsi_token($c->cfg->{jitsi_room}),
+        );
+    }
+
+    $c->render(openapi => $c->spec_filter($formatted, 'User'));
 }
 
 sub ban ($c){
@@ -45,6 +61,18 @@ sub unban ($c){
     $c->render(status => 204, text => '');
 }
 
+sub jitsi ($c){
+    $c->openapi->valid_input or return;
+    my $args   = $c->req->json;
+    my $user   = $c->_get( $c->stash->{id} ) // return;
+    my $guard  = $c->schema->txn_scope_guard;
+
+    $user->update({ jitsi_allowed => $args->{allowed} });
+
+    $guard->commit;
+    $c->render(status => 204, text => '');
+}
+
 sub _get ($c, $id ) {
 
     my $user;
diff --git a/lib/CF/Controller/Websockets.pm b/lib/CF/Controller/Websockets.pm
index 28ad69a8b504a9aabf6a12eaf5d481f610f1d979..8647e9dfa32a0d8b88788b5dd3a4cf1bffc333d1 100644
--- a/lib/CF/Controller/Websockets.pm
+++ b/lib/CF/Controller/Websockets.pm
@@ -24,19 +24,22 @@ sub main {
     $c->on(json => sub( $c, $message ) {
 
         if ( $message->{event} eq 'KEEPALIVE' ) {
-            my $user_id;
+            my $user;
 
             if ($message->{payload} =~ /^(\d+)$/) {
                 # TODO: check signtaure
-                $user_id = $1;
+
+                $user = $c->schema->resultset('User')->find(
+                    { id => $1 }
+                );
             }
 
             $c->schema->resultset('Socket')->update_or_create({
                 id        => $c->req->headers->header('Sec-WebSocket-Key'),
                 ip        => $ip,
                 keepalive => \'now()',
-                user_id   => $user_id,
-            }, { key => $user_id ? 'user':'primary'} );
+                user_id   => $user ? $user->id : undef,
+            }, { key => $user ? 'user':'primary'} );
 
             my $all = $c->schema->resultset('Socket_view')->count(
                 { is_alive => 't', }
@@ -49,6 +52,15 @@ sub main {
                 all     => $all,
                 members => $members,
             }}});
+
+            if ( $user ) {
+                my $jitsi = $user->jitsi_allowed || $user->roles =~ /chairman/;
+
+                $c->send({json => { event => 'user_status', payload => {
+                    jitsi_allowed => $jitsi ? \1:\0,
+#                   is_banned     => $user->banned_until ? 1:0,
+                }}});
+            }
         }
 
     });
diff --git a/lib/CF/Schema/Result/User.pm b/lib/CF/Schema/Result/User.pm
index 07c925c6a4bd06940e2218ed5bd20786a28a7fad..0f81aa6b551b30e862847ab43d9c0dc42f1646d4 100644
--- a/lib/CF/Schema/Result/User.pm
+++ b/lib/CF/Schema/Result/User.pm
@@ -28,6 +28,7 @@ __PACKAGE__->add_columns(
         main_group_name
         keepalive
         banned_until
+        jitsi_allowed
     ),
 );
 
diff --git a/openapi.yaml b/openapi.yaml
index 79731d4f7a57c146146c5268dcd49e74a2a92d0c..84bd655669b2d2ae27e116df4cac5410c11c3ee6 100644
--- a/openapi.yaml
+++ b/openapi.yaml
@@ -116,6 +116,8 @@ components:
             type: string
         secret:
             type: string
+        jitsi_url:
+            type: string
         is_banned:
             type: boolean
     Announcement:
@@ -462,7 +464,7 @@ paths:
                   enum: [0, 1, 2, 3, 4]
                 content:
                   type: string
-                isr_archived:
+                is_archived:
                   type: boolean
       responses:
         204:
@@ -564,3 +566,25 @@ paths:
       responses:
         204:
           description: User banned
+
+  /users/{id}/jitsi:
+    patch:
+      security:
+        - Bearer: ['chairman']
+      x-mojo-to: users#jitsi
+      tags:
+        - users
+      summary: Set jitsi access
+      operationId: jitsi
+      requestBody:
+        content:
+          application/json:
+            schema:
+              type: object
+              properties:
+                allowed:
+                  type: boolean
+      responses:
+        204:
+          description: Status changed
+
diff --git a/sql/5/up.sql b/sql/5/up.sql
index e221e7849bba9a6214eb3d7bbba3ebda50caca7e..bb439426569918913626ba3e82c1e52001fcd7f6 100644
--- a/sql/5/up.sql
+++ b/sql/5/up.sql
@@ -1,4 +1,5 @@
 alter table "users" add "roles" text;
+alter table "users" add "jitsi_allowed" bool not null default false;
 
 create table "sockets" (
     "id" varchar(64),