JWT tokens and guest access

Have you restarted prosody?
This is exactly how meet.jit.si is configured at the moment and you can enter without token.

I just restarted the server (just to make sure :)).

I am getting a pop-up asking for a username and password:


Maybe I forgot to say that this server is also configured as a secured domain, so maybe that is why it is throwing the username and password to the guests!?

But in the configuration, I also have the guest.my_domain.com virtual host, which is configured with anonymous authentication!

So, how does Jitsi chooses between my_domain.com (tokens), auth.my_domain.com(internal_plain) and guest.my_domain.com(anonymous)?

U can’t have both, either choose token or secure domain

@Tanvir I think I currently have both, when there is no token specified, I get the username and password popup, and that does work for users without tokens.

So, I guess I need to disable the secured domain to enable anonymous access with tokens.

A final update on this post.

The only way I was able to get anonymous users to work was to update ‘/etc/prosody/conf.avail/vc.my_domain.com.cfg.lua’ guest’s virtual host with the following config:

VirtualHost “guest.my_domain.com”
–authentication = “anonymous”;
authentication = “token”
c2s_require_encryption = false
allow_empty_token = true;

At the end, I have users authenticating through ‘JWT tokens’ and the guests wait until the room is created by the actual authenticated users.


This is almost perfect, there is only one detail that does not work: if the user that has been authenticated with the JWT tries to create another room, even if the token has restriction to only create a single room, it will let the user create as many rooms as he wants, without restriction. It seems that it authenticates via the guest host together with his sessionId stored at the local storage. Cleaning it makes the user unable to create more rooms. Is there any explanation to this?

In case anybody is stumbling upon this while searching via google:

Please see this issue on github about this: https://github.com/jitsi/docker-jitsi-meet/issues/143
Specifically the change in this pullrequest: https://github.com/jitsi/jitsi-meet/pull/5025

The added line in mod_auth_token.lua will enable the guest feature for jwt in such a way that clients without a valid token will be guests and will have to wait for someone with a valid jwt token to join the room.


I Have the same problem on the latest stable version of Jitsi-Meet.
When the client refreshes the web page he still can open a conference without the JWT in the URL thanks to sessionId variable in the Local Storage.

@damencho @saghul @Boris_Grozev is this a bug or a feature ?

@damencho Same problem: how is it possible to avoid that a user with JWT for a specific room can then create any other rooms without token thanks to local storage?
Is it definitely possible to combine secure-domain with token authentication?

Unfortunately the workaround here suggested in virtual host configuration has this heavy drawback.
It would be very useful to have a moderator with token that can create a specific room, basis on token attribute, and the other users as guest without token, so they can only join to the already created room.

Thanks for your precious help!

That is something I mentioned earlier in the forum. These are two different features and they were never supposed to work together. The fact that they work is pure luck:), but seems there are edge cases that will not work. You can fix it, I suppose, by disabling auto-login, users will always been asked for password, no matter what.

1 Like

Ok, thanks Damian for your suggestion. :+1:

Hi @damencho!

Sorry for this question, maybe it is a silly one but I’m kind of lost with the authentication.

When we talk about secure domain, we are talking about HTTPS and the Lets Encrypt cert, right?
I have this enabled and also JWT authentication.

So if I’m using JWT authentication, there is no need to have the secure domain, right?

On the other hand, I’m looking forward to having JWT authentication for both guests and moderators, I saw the enableUserRolesBasedOnToken, but in this case, it won’t work since both are using JWT tokens.
I read a lot of posts here, but I just want to be sure, the only way to achieve this is by using the jitsi-token-moderation-plugin, right?
Also, I need to restrict the kick feature just for the moderator. Is it possible?

I’m using Docker, this is my .env configuration, don’t know if it helps:

    # Security
    # Set these to strong passwords to avoid intruders from impersonating a service account
    # The service(s) won't start unless these are specified
    # Running ./gen-passwords.sh will update .env with strong passwords
    # You may skip the Jigasi and Jibri passwords if you are not using those
    # DO NOT reuse passwords

# XMPP component password for Jicofo

# XMPP password for Jicofo client connections

# XMPP password for JVB client connections

# XMPP password for Jigasi MUC client connections

# XMPP recorder password for Jibri client connections

# XMPP password for Jibri client connections

# Basic configuration options

# Directory where all configuration will be stored

# Exposed HTTP port

# Exposed HTTPS port

# System time zone

# Public URL for the web service

# IP address of the Docker host
# See the "Running behind NAT or on a LAN environment" section in the README

# Let's Encrypt configuration

# Enable Let's Encrypt certificate generation

# Domain for which to generate the certificate

# E-Mail for receiving important account notifications (mandatory)

# Etherpad integration (for document sharing)

# Set etherpad-lite URL (uncomment to enable)

# Basic Jigasi configuration options (needed for SIP gateway support)

# SIP URI for incoming / outgoing calls

# Password for the specified SIP account as a clear text

# SIP server (use the SIP account domain if in doubt)

# SIP server port

# SIP server transport

# Authentication configuration (see README for details)

# Enable authentication

# Enable guest access

# Select authentication type: internal, jwt or ldap

# JWT authentication

# Application identifier

# Application secret known only to your token

# (Optional) Set asap_accepted_issuers as a comma separated list

# (Optional) Set asap_accepted_audiences as a comma separated list


# LDAP authentication (for more information see the Cyrus SASL saslauthd.conf man page)

# LDAP url for connection

# LDAP base DN. Can be empty

# LDAP user DN. Do not specify this parameter for the anonymous bind

# LDAP user password. Do not specify this parameter for the anonymous bind

# LDAP filter. Tokens example:
# %1-9 - if the input key is user@mail.domain.com, then %1 is com, %2 is domain and %3 is mail
# %s - %s is replaced by the complete service string
# %r - %r is replaced by the complete realm string

# LDAP authentication method

# LDAP version

# LDAP TLS using

# List of SSL/TLS ciphers to allow

# Require and verify server certificate

# Path to CA cert file. Used when server certificate verify is enabled

# Path to CA certs directory. Used when server certificate verify is enabled

# Wether to use starttls, implies LDAPv3 and requires ldap:// instead of ldaps://

# Advanced configuration options (you generally don't need to change these)

# Internal XMPP domain

# Internal XMPP server

# Internal XMPP server URL

# Internal XMPP domain for authenticated services

# XMPP domain for the MUC

# XMPP domain for the internal MUC used for jibri, jigasi and jvb pools

# XMPP domain for unauthenticated users

# Custom Prosody modules for XMPP_DOMAIN (comma separated)

# Custom Prosody modules for MUC component (comma separated)

# Custom Prosody modules for internal MUC component (comma separated)

# MUC for the JVB pool

# XMPP user for JVB client connections

# STUN servers used to discover the server's public IP

# Media port for the Jitsi Videobridge

# TCP Fallback for Jitsi Videobridge for when UDP isn't available

# A comma separated list of APIs to enable when the JVB is started [default: none]
# See https://github.com/jitsi/jitsi-videobridge/blob/master/doc/rest.md for more information

# XMPP user for Jicofo client connections.
# NOTE: this option doesn't currently work due to a bug

# Base URL of Jicofo's reservation REST API

# Enable Jicofo's health check REST API (http://<jicofo_base_url>:8888/about/health)

# XMPP user for Jigasi MUC client connections

# MUC name for the Jigasi pool

# Minimum port for media used by Jigasi

# Maximum port for media used by Jigasi

# Enable SDES srtp

# Keepalive method

# Health-check extension

# Health-check interval
# Enable Jigasi transcription

# Jigasi will record audio when transcriber is on [default: false]

# Jigasi will send transcribed text to the chat when transcriber is on [default: false]

# Jigasi will post an url to the chat with transcription file [default: false]

# Credentials for connect to Cloud Google API from Jigasi
# Please read https://cloud.google.com/text-to-speech/docs/quickstart-protocol
# section "Before you begin" paragraph 1 to 5
# Copy the values from the json to the related env vars

# Enable recording

# XMPP domain for the jibri recorder

# XMPP recorder user for Jibri client connections

# Directory for recordings inside Jibri container

# The finalizing script. Will run after recording is complete

# XMPP user for Jibri client connections

# MUC name for the Jibri pool

# MUC connection timeout

# When jibri gets a request to start a service for a room, the room
# jid will look like: roomName@optional.prefixes.subdomain.xmpp_domain
# We'll build the url for the call by transforming that into:
# https://xmpp_domain/subdomain/roomName
# So if there are any prefixes in the jid (like jitsi meet, which
# has its participants join a muc at conference.xmpp_domain) then
# list that prefix here so it can be stripped out to generate
# the call url correctly

# Directory for logs inside Jibri container

# Disable HTTPS: handle TLS connections outside of this setup

# Redirect HTTP traffic to HTTPS
# Necessary for Let's Encrypt, relies on standard HTTPS port (443)

# Container restart policy
# Defaults to unless-stopped

Thanks in advance!



Yep, by default those not using tokens are guests and the rest are moderators. You need extra logic on top if you want to have different tokens for different roles.

Can guest without jwt create rooms?


Hi @damencho, I want to make sure regarding your answer, when the guest submit a Jitsi URL with room route, i.e. https://meet.jit.si/TheGuestsRoom, but it still showing “Waiting for host” modal which mean the guests need to wait for an authenticated user to join the same room, still counted as “Guest without JWT can create rooms”?

So in my case, I wonder if it possible to have these following scenarios:

  • Guests can create their own room between them (guests)
  • Guests can be invited by authenticated users to join their (authenticated users) room

Hi @damencho @Boris_Grozev @Osama_Hamzah
I’ve enabled the token base. What my requirement is, only the moderator should log by using the token. For the other participants, they should be able to access without token. I’ve made the changes as I’ve mentioned below. But my requirement wasn’t successful. What happened for me is disable of the token flow. Can you support me to get this successful?

These are the configurations which include in conf.avail.

VirtualHost "jitsi.videocec.net"
        -- enabled = false -- Remove this line to enable this host
        authentication = "token"
        -- Properties below are modified by jitsi-meet-tokens package config
        -- and authentication above is switched to "token"
        -- Assign this host a certificate for TLS, otherwise it would use the one
        -- set in the global section (if any).
        -- Note that old-style SSL on port 5223 only supports one certificate, and will always
        -- use the global one.
        ssl = {
                key = "/etc/prosody/certs/jitsi.videocec.net.key";
                certificate = "/etc/prosody/certs/jitsi.videocec.net.crt";
        speakerstats_component = "speakerstats.jitsi.videocec.net"
        conference_duration_component = "conferenceduration.jitsi.videocec.net"
        -- we need bosh
        modules_enabled = {
            "ping"; -- Enable mod_ping
        c2s_require_encryption = false
        allow_empty_token = false;
        consider_bosh_secure = true;
        lobby_muc = "lobby.jitsi.videocec.net"
        main_muc = "conference.jitsi.videocec.net"
        -- muc_lobby_whitelist = { "recorder.jitsi.videocec.net" } -- Here we can whitelist jibri to enter lobby enabled rooms
VirtualHost "guest.jitsi.videocec.net"
        authentication = "token"
        c2s_require_encryption = false
        allow_empty_token = true;

These are the configurations which include in jitsi meet config

 hosts: {
        // XMPP domain.
        domain: 'jitsi.videocec.net',
        anonymousdomain: 'guest.jitsi.videocec.net',
        // When using authentication, domain for guest users.
        // anonymousdomain: 'guest.example.com',

        // Domain for authenticated users. Defaults to <domain>.
        // authdomain: 'jitsi.videocec.net',

        // Jirecon recording component domain.
        // jirecon: 'jirecon.jitsi.videocec.net',

        // Call control component (Jigasi).
        // call_control: 'callcontrol.jitsi.videocec.net',

        // Focus component domain. Defaults to focus.<domain>.
        // focus: 'focus.jitsi.videocec.net',

        // XMPP MUC domain. FIXME: use XEP-0030 to discover it.
        muc: 'conference.<!--# echo var="subdomain" default="" -->jitsi.videocec.net'

Thank you very much

I am not sure what is the scenario that you trying to run, but the moderator needs to use his token to login to the room first, then the participants can join the same room.

Otherwise it would not work.

You are mixing username/password setting about anonymous domain and tokens.

Remove anonymousdomain from config.js and add allow_empty_token = true; to VirtualHost "jitsi.videocec.net". Those that use token will be moderators and the rest will be guests.
You may want to also set enableUserRolesBasedOnToken: true in config.js.