Domain validation with JWT tokens

According to this doc, the “sub” field in the token should contain either the lowercase name of the tenant or the domain.

I take this to mean that for a meeting on https://my.server/RoomName, (ignoring wildcards) the token is only valid if:

{ ...
    "sub": "my.server",
    "room": "roomname",

and for https://my.server/tenantX/RoomName:

{ ...
    "sub": "tenantx",
    "room": "roomname",

Is this a correct interpretation?

I’m running (jitsi-meet=2.0.5142-1) and unfortunately the above does not match my observations.

  1. The “sub” field appears to be ignored completely – both the tokens above work with https://my.server/RoomName and both fail on https://my.server/tenantX/RoomName
  2. Working backwards from the logs, I eventually managed to authenticate using:
    { ...
        "sub": "anything",
        "room": "[tenantx]roomname",

I tried to adding enable_domain_verification = true to see if this helps with validating domain specified in “sub” but this resulted in the following traceback in the logs:

Traceback[c2s]: /usr/share/jitsi-meet/prosody-plugins/token/util.lib.lua:390: bad argument #1 to 'lower' (string expected, got nil

I would ideally want to validate both the domain and the tenant, but can settle for just the domain validation if necessary. Any suggestions greatly appreciated.


  1. How do I enable domain verification with tokens
  2. Is [tenant]roomname the correct way to specify room name for a multi-tenant setup?

Finally had a chance to dig further.

From what I can tell, when enable_domain_verification = true, the subdomain check logic in token.Util.verify_room is exercised but the session.jitsi_meet_domain value is nil hence the failure mentioned above. Full traceback:

Jan 04 22:52:00 c2s559bb84a8f80	error	Traceback[c2s]: /usr/share/jitsi-meet/prosody-plugins/token/util.lib.lua:396: bad argument #1 to 'lower' (string expected, got nil)
stack traceback:
	[C]: in function 'lower'
	/usr/share/jitsi-meet/prosody-plugins/token/util.lib.lua:396: in function 'verify_room' in function 'verify_user' in function '?'
	/usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
	(...tail calls...)
	/usr/lib/prosody/modules/muc/muc.lib.lua:442: in function </usr/lib/prosody/modules/muc/muc.lib.lua:431>
	(...tail calls...)
	/usr/lib/prosody/util/events.lua:79: in function </usr/lib/prosody/util/events.lua:75>
	(...tail calls...)
	/usr/lib/prosody/core/stanza_router.lua:180: in function 'core_post_stanza'
	/usr/lib/prosody/core/stanza_router.lua:198: in function 'core_route_stanza'
	/usr/lib/prosody/core/stanza_router.lua:184: in function 'core_post_stanza'
	/usr/lib/prosody/core/stanza_router.lua:127: in function 'core_process_stanza'
	/usr/lib/prosody/modules/mod_c2s.lua:276: in function 'func'
	/usr/lib/prosody/util/async.lua:127: in function </usr/lib/prosody/util/async.lua:125>

The session.jitsi_meet_domain value is meant to be set from the token’s “sub” claim by token.Util.process_and_verify_token which is called by mod_auth_token but not mod_token_verification.

I’ve logged out session.auth_token, session.jitsi_meet_domain, and session.jitsi_meet_room from mod_token_verification.verify_user and they indeed all show up as nil.

Are there additional configs other than what’s mentioned in lib-jitsi-meet/ at master · jitsi/lib-jitsi-meet · GitHub to enable domain verification?

What version of jitsi-meet package do you use?

2.0.5142-1, which I believe is latest stable from

Can you test latest from unstable?

I tried replacing /usr/share/jitsi-meet/prosody-plugins with the latest version from master (32fb08c) and see the same error.

I’ve narrowed down the error further – it appears to be triggered by the verify_user call from the muc-room-pre-create event handler in mod_token_verification. focus user does not use token auth so nil value for session.jitsi_meet_domain when creating room.

There is a branch which skips verify_room if is_admin(user_jid), and I do have focus user listed as admin in my conference config so I’m wondering what else I’m missing.

Noticed that the is_admin call in that module was done without specifying the host. Everything now works as expected with this patch:

Is this the right thing to do?

With that patch in place and enable_domain_verification = true, I can now authenticate on https://my.server/tenantX/RoomName using:

{ ...
    "sub": "tenantx",
    "room": "roomname",

Or "room": "[tenantx]roomname" if enable_domain_verification is not set.

Seems correct, yep.

is_admin implementation will use ‘*’ if you do not specify host, so I suspect your configuration is setting focus user as admin only for this host and not globally. Which by the way is the default configuration:

We have never experienced a problem with that code as we always set the admin globally.

Thanks for the confirmation. Indeed my config has admins defined per host rather than globally which, iirc, is how it was set by the install process.

Would you recommend I set the admin settings globally? or should the code be patched? Happy to raise a PR if it helps.

A PR is the way to go, I think. Maybe others are facing same with default configuration.

Sure thing.

I’ve signed the contributor license agreement and submitted this PR: fixed admin check for token verification by shawnchin · Pull Request #8331 · jitsi/jitsi-meet · GitHub

Thank you.