Skip to Content

Implementing Roles and Permissions for Custom Entities in Liferay: Our Approach

12 September 2025 by
Implementing Roles and Permissions for Custom Entities in Liferay: Our Approach
ReactorBee

At ReactorBee, we recently worked on a client project where we needed to implement Roles and Permissions for custom entities built on Liferay 7.4.

Instead of building a custom permission system, we smartly leveraged Liferay's Out-of-the-Box (OOTB) Roles and Permissions framework — but with a few important extensions.

Here’s a step-by-step walkthrough of how we achieved it.

Why We Needed This

  • The client had multiple custom modules (entities) inside Liferay.
  • They needed granular control over what different roles could do with each entity.
  • Permissions needed to be manageable from Liferay's Control Panel without custom UIs.

Step-by-Step Implementation


Step 1: Add a default.xml in the Service Module


In the Service Module of each custom entity, we created a default.xml file under the resource-actions folder.

This file defined Model Resource Permissions for each entity and listed the actions supported.

Sample (service/src/main/resources/resource-actions/default.xml):

<?xml version="1.0"?>

<!DOCTYPE resource-action-mapping PUBLIC "-//Liferay//DTD Resource Action Mapping 7.4.0//EN" "http://www.liferay.com/dtd/liferay-resource-action-mapping_7_4_0.dtd">

<resource-action-mapping>

    <model-resource>

        <model-name>com.example.model.EntityName</model-name>

        <portlet-ref>

            <portlet-name>com_example_web_EntityPortlet</portlet-name>

        </portlet-ref>

        <root>true</root>

        <weight>1</weight>

        <permissions>

            <supports>

                <action-key>VIEW</action-key>

                <action-key>EDIT</action-key>

                <action-key>DELETE</action-key>

                <action-key>CUSTOM_ACTION</action-key>

            </supports>

            <site-member-defaults />

            <guest-defaults />

            <guest-unsupported />

        </permissions>

    </model-resource>

</resource-action-mapping>

action-key placeholders represent the actions you want to define for your entity. 

model-name is your entity's fully qualified class name.


Step 2: Add a default.xml in the Web Module


In the Web Module (Portlet Module) associated with the entity, we also created a⁣ default.xml

This file defined Portlet Resource Permissions.


Sample (web/src/main/resources/resource-actions/default.xml):

<?xml version="1.0"?>

<!DOCTYPE resource-action-mapping PUBLIC "-//Liferay//DTD Resource Action Mapping 7.4.0//EN" "http://www.liferay.com/dtd/liferay-resource-action-mapping_7_4_0.dtd">


<resource-action-mapping>

    <portlet-resource>

        <portlet-name>com_example_web_EntityPortlet</portlet-name>

        <permissions>

            <supports />

            <site-member-defaults />

            <guest-defaults />

            <guest-unsupported />

        </permissions>

    </portlet-resource>

</resource-action-mapping>

  • This ensures the portlet itself is recognized in the Roles UI and can be assigned permissions.


Step 3: Create/Update portlet.properties


In the Web Module and Service Module, we created a portlet.properties file (if not already existing) and added the following line:

resource.actions.configs=resource-actions/default.xml

  • This tells Liferay to load the default.xml we created, so action keys are properly registered when the module deploys.


Step 4: Add Action Key Labels


We updated the module’s Language.properties to define readable labels for each action key.

Example:

model.resource.com.example.model.EntityName=Entity

action.VIEW=View

action.EDIT=Edit

action.DELETE=Delete

action.CUSTOM_ACTION=Custom Action

  • These appear in the Liferay Control Panel under Roles → Define Permissions.


Step 5: Handle Liferay’s 64 Action Keys Limit

    -    In Liferay, one entity can only have up to 64 action keys because of internal storage as bit fields.

    -    To manage hundreds of permissions across many entities:

                -    We designed modular entities with focused sets of action keys.

                -    Split large functionality into smaller logical modules when needed.

Result: No entity exceeded 64 keys, ensuring stability and smooth upgrades later.


Step 6: Provide a Headless API for Frontend


To simplify frontend integration:

  • We exposed a custom Headless API that returns all action keys available to the logged-in user, grouped by entity.

  • The frontend team only needed one API call to fetch all permissions at once.

✅ This minimized complexity and accelerated frontend development.


Additional Note

  • Custom Action Keys for Liferay Objects:

    We also implemented custom action keys for Liferay Objects (dynamic entities).

    we’ll explain it separately in the next blog post.


Conclusion

By correctly setting up resource actions in both Service and Web modules, and by aligning closely with Liferay’s framework:

  • We delivered a scalableadmin-manageable, and future-proof permissions system.

  • No heavy custom development was needed beyond smart configuration.

At ReactorBee, we always aim to maximize platform capabilities to deliver elegant, enterprise-ready solutions quickly and reliably.

Implementing Roles and Permissions for Custom Entities in Liferay: Our Approach
ReactorBee 12 September 2025
Share this post
Tags