Roles and permissions

This page describes Prosody’s permissions system. It mainly focuses on the new API provided in versions after 0.12 (not yet released).


The new permissions API is available directly to modules via a handful of simple module API methods:

module:may(permission, context)

Returns true if the current actor is permitted to perform the permission identified by the permission string. Returns false otherwise.

context is used to determine the actor (and possibly other information that might influence the result), and should be either:

  • a table containing a stanza field and either an origin or session field (most event objects are compatible)
  • a string containing the actor’s JID

The first option should generally be preferred. The second option (supplying a JID as context) should only be used when no session or stanza is available to the current code, or the actor is some remote JID.

module:default_permission(role_name, permission)

This is used to seed the permissions system with a rule to allow the named role to perform the named permission.

For example, if your module creates a new permission called ":engage-thrusters", and you think this should be restricted to admins by default, you would write:

module:default_permission("prosody:admin", ":engage-thrusters");

Note that this is just a default and it may be overridden in any deployment.

If you neglect to grant permission to any roles by default, and the admin doesn’t configure any, then nobody will be able to perform your custom permission.

module:default_permission(role_name, permission_list)

In the case where you have a lot of permissions to register, this is a convenience function that accepts an array of permissions (permission_list). It is otherwise identical to module:default_permission().

Role management API

A more in-depth API is part of core.usermanager, and it allows accessing and managing the roles assigned to users. Most modules should not use these APIs directly, but instead prefer the module API methods when doing permission checks.

Get the default role of a user
get_user_role(username, host)
Set the default role of a user
set_user_role(username, host, role_name)
Get the secondary roles of a user (returns a map of role name to role)
get_user_secondary_roles(username, host)
Add a new secondary roles to a user
add_user_secondary_roles(username, host, role_name)
Remove a secondary roles from a user
remove_user_secondary_roles(username, host, role_name)
Look up a role by name
get_role_by_name(role_name, host)
Check whether a user is allowed to assume a role
user_can_assume_role(user, host, role_name)
Get JID role
get_jid_role(jid, host)
Set JID role
set_jid_role(jid, host, role_name)
Get users with role (avoid in large deployments)
get_users_with_role(role_name, host)
Get JIDs with role (avoid in large deployments)
get_jids_with_role(role_name, host)

Compatibility with 0.12

If your module needs to be compatible with Prosody 0.12 and also later versions, you can lean on mod_compat_roles to provide (most of) the new API on older Prosody versions.

Legacy API

For completeness, this section documents the original permissions API (which should not be used for most new modules).

usermanager.is_admin(jid[, host])

This core method has existed in most Prosody versions. It checks to see whether the provided JID is an admin of the provided host. If no host is provided, it checks whether the JID is configured as a global (server-wide) admin.

It does not support fine-grained permissions, or per-session authorization. Therefore it has been deprecated and entirely removed in versions after 0.12.