Persistent Passwords on Self Hosted Rooms

I believe I had some trouble when returning anything else but nil, so your return res; statement could be a problem. However, as mentioned before, I do not really know Lua, nor the prosody API.

Still the same…

-- For Prosody 0.9 /usr/lib/prosody/modules/
module:hook("muc-room-created", function (event)
    local room =;
    module:log("debug", "hooked room create for %s", tostring(room));
    local pass = tostring(randPW(8));
    local res = room:set_password(pass);
    module:log("info", "Set password '%s' for %s.", pass, tostring(room));
    return nil;
end, 0);

@damencho Damian, maybe you can help?

Did you try the muc-room-pre-create hook? Did not work for me on prosody 0.11 because jicofo failed to join the room but this may be different when using prosody 0.9.

Well, you need to let jicofo in the room, as jicofo is the first one to join normally.

Well, you need to let jicofo in the room, as jicofo is the first one to join normally.

Yes, thats why I switched to using the muc-room-created hook, to set the password only after jicofo joined.

@osys Another idea: have you tried to lower the priority of your hook to some negative value instead of 0?

Merging my discussion into this as I’m now in the same situation.

1 Like

Using the muc_room_default_persistent = true method I now have a different error: connection.GET_SESSION_ID_ERROR
I just closed the browser and joined in a private tab.

Folks, I’ve finally made it working by updating to the freshest version of Prosody

Prosody 0.11.5

# Lua environment
Lua version:                    Lua 5.2
LuaRocks:               Not installed

# Network

Backend: select

# Lua module versions
DBI:            0.7
lfs:            LuaFileSystem 1.6.3
lxp:            LuaExpat 1.3.0
socket:         LuaSocket 3.0-rc1
ssl:            0.6
1 Like

You can try to adjust the module posted above to fit your needs, that is do not allow to delete the password and don’t let rooms go stale (perhaps just remove the muc-room-destroyed hook.
Restart prosody to enable the module.

Now create a room, set a password and leave the room. Check that a plaintext file has been created in prosody’s data folder in a folder called <your-muc-component>/persistent_muc_passwords/<urlencoded_muc_name>.dat

Then also enable the prosody module described here: and add the muc#roomconfig_roomsecret option. Restart prosody again. For each room you want to setup, create a file similar to the file you checked in the last step. Make sure these are only readable by the prosody user.

This is still just a workaround, as anybody who joins a room first (i.e. the moderator) will see the Remove Password button. However, clicking this button shows an error message stating that passwords were not supported.

Hope this helps!


I am using docker as well and would to have this setup. Is it possible for you to layout in a more detailed guide? I am struggling on where the modules locations are and if we need to turn that on in the docker-compose.yml file (via .env).

I am using docker too in a test system.

If you do not change CONFIG in .env, file location in a standard configuration are

In docker-compose.yml you have a add a line for a prosody module

    image: jitsi/prosody
        - '5222'
        - '5347'
        - '5280'
        - ${CONFIG}/prosody:/config
        - ${CONFIG}/prosody-plugins-custom:/prosody-plugins-custom

And you have to create the directory ~/.jitsi-meet-cfg/prosody-plugins-custom/

1 Like

Alternatively, if you don’t want to change the docker-compose.yml, just change the plugin_paths option in ~/.jitsi-meet-cfg/prosody/conf.d/jitsi-meet.cfg.lua to include "/config/prosody-plugins-custom". Then put the module in ~/.jitsi-meet-cfg/prosody/prosody-plugins-custom/mod_persist_muc_passwords.lua

1 Like

Thanks a lot for your script! I managed to install it and it works - half-way:

  • It still asks for the operator’s password. Am I supposed to turn the restrict_create_room(?) off again?
  • It’s still possible to delete the password.

Sorry if I misunderstood any of the above instructions. I came from a “quick install” and didn’t expect to deep dive into the system just to set up a password.

(edit: found some details I have to re-read)

To prevent the password from being deleted, you can enable the mod_muc_config_restrict.lua module mentioned above.

You are asked to provide the operator’s password because you setup a secure domain - if everybody should be able to create a room try to undo the respective configuration. Note that in this case whoever joins the room first will be the room’s moderator which is likely not what you want.

Thanks for everyone that’s helped as well, and I think it is working as intended.

  • I have authentication turned on (internal)
  • When I “create” a room and set the password, that password carries over from session to session (i.e. I close out the window completely and go back in), so that is working as intended
  • However, because I have authentication on, when a room does not have a participant anymore (everyone left) and then join back in, it requires someone to authenticate first, and then the room password kicks in; is there a way to not have authentication on a room that had been created?

I’m stuck on the very same problem right now.
I wonder if it makes sense to remove the authentication and just use the room’s password. Using any unknown room would require a password nobody knows.
As soon as I figured out why my settings don’t apply, I’ll start tinkering with the script @plokta provided.

My concern is that I have this running on a public-facing VPS and I don’t want anyone and everyone to use up my bandwidth. With my scenario, ideally I would like to only let authenticated users create persistent rooms that require passwords.

That being said, I think @plokta solution is the best workaround. I have authentication so not everyone can just create a room, and passwords are persistent.

I have an almost working version for my needs (only pre-configured rooms with passwords - no accounts):

I’m not using any secure domain.


Component "conference.domain.tld" "muc"
    modules_enabled = {
    admins = { "focus@auth.domain.tld" }
    default_storage = "memory";
    storage = {
	persistent_muc_passwds = "internal";
    muc_config_restricted = {

/usr/lib/prosody/modules/mod_persist_muc_passwords.lua (modified script of @plokta )

local store = module:open_store("persistent_muc_passwds", "map");
if not store then
    module:log("error","Failed to open storage.");
    return nil;

module:hook("muc-room-created", function (event)    
    local room =;
    module:log("debug","hooked room create for %s", room);

    local old_pass = store:get(room.jid, "password");
    if not old_pass then
        -- default password for unknown rooms; not to be shared with anyone
	old_pass = "some-admin-password" -- should be moved into some config file
        module:log("debug", "No password to restore for room %s", room);

    module:log("debug", "Loaded old password '%s' for room %s", old_pass, room);

    -- restore old pass for the mucroom
    local success = room:set_password(old_pass);
    if not success then 
        module:log("warn", "Failed to set old password %s for restored room %s.", old_pass, room);
    module:log("debug", "Set password '%s' for restored room %s.", old_pass, room);
    return nil;
end, 0);

For each room: /var/lib/prosody/conference%2edomain%2etld/persistent_muc_passwds/name_of_the_room%40conference%2edomain%2etld.dat

return {
	["password"] = "shared room password";

Current issues:

  • It’s still possible to delete the password when entering the room. But that has only temporary effect. @plokta any idea why my configuration of mod_muc_config_restrict doesn’t work? Is muc#roomconfig_roomsecret available on secured domains only?

My setup is somewhat different but I can confirm that mod_muc_config_restrict also works without secured domain: The Remove Password button is visible but an error message pops up when the button is clicked.

Did you check the prosody logs to see whether the module was loaded successfully? Also, in my config the focus user is only set as admin in the global section and not in the muc component. And I don’t have the modules muc_meeting_id and muc_domain_mapper enabled but to be honest, I don’t know if this could affect the muc_config_restrict module.

1 Like

@plokta Couldn’t you remove the Remove Password button from the react template?

Thanks for the thread, this has been a super helpful discussion.