Building and Testing Your Plugin's PACL

Liferay’s Plugin Security Manager requires that a plugin specify in advance the portal resources that it intends to access. If a plugin tries to access something it hasn’t told the Security Manager about, the Security Manager puts a stop to it. A plugin’s Portal Access Control List (PACL) is its way of telling the Security Manager what it intends to access.

This tutorial shows you how to build and test your plugin’s PACL through the following steps:

  • Develop Your Plugin
  • Build Your Plugin’s PACL
  • Test Your Plugin with the Security Manager Enabled
  • Use a Java Security Policy File, if Necessary
  • Convert PACL Absolute File Paths into Relative Paths

Lastly, this tutorial explains some of the subtle details about the PACL properties.

Now go ahead and get started–you don’t want to run afoul of the Security Manager!

Develop Your Plugin

Start by creating your plugin the way you normally do. Design your application, write the code, unit test your code, and have users beta test your app. In essence, do everything you normally do. Do all of this with the Plugin Security Manager disabled via your plugin’s file:


Before the Plugin Security Manager is enabled, you must specify the resources your plugin accesses. You do this by building a list of these resources in your plugin’s PACL.

Build Your Plugin’s PACL

Rather than tediously figuring out all of the resources your plugin accesses on your own, let Liferay’s PACL Policy Generation tool to give you a head start! The generation tool detects the resources your plugin accesses and writes the corresponding PACL properties to a policy file. You can then merge the PACL properties from this policy file into your plugin’s file.

Here’s how to generate a PACL policy for your plugin:

  1. Make sure your Liferay Portal instance has liferay set as its security manager strategy value and that the security manager was activated during application server startup.

    To set your portal’s security manager strategy value to liferay, simply specify the following in your file:

    Your app server may require certain startup arguments to be used for activiting the security manager. Check the PACL and security manager instructions for your app server in the Installation and Setup chapter of Using Liferay Portal. Some app servers, like Tomcat, output a terminal message like “Using Security Manager”, indicating that it’s using the security manager.

    Unless you already started Liferay with the security manager enabled and activated as described above, you must restart Liferay with these settings.

  2. Enable the security manager to generate a security policy for your plugin by setting the following property in your plugin’s file:

  3. Deploy your plugin.

    The PACL Policy Generation tool writes a PACL policy file with the following path:


    Liferay Portal’s Security Manager performs security checks on your plugin at deployment time and as you exercise your plugin’s features. Rather than throwing errors on failed checks, the generator tool writes suggested rules that specify access to the resources your plugin accesses.

    Unless you’ve turned off logging for the generator tool, messages like the ones below are logged, reporting the various authorization properties that the tool generated:

    DEBUG [localhost-startStop-2][GeneratingPACLPolicy:230] my-pacl-portlet
    generated authorization property {key=security-manager-properties-read,
    DEBUG [localhost-startStop-2][GeneratingPACLPolicy:230] my-pacl-portlet
    generated authorization property {key=security-manager-properties-read,
  4. Lastly, merge the properties that the security manager wrote (i.e., your newly generated PACL policy file [liferay.home]/pacl-policy/[servletContextName].policy) into your plugin’s file. It’s just a matter of merging the properties that start with the “security-manager-” prefix.

Now that you’ve thoroughly specified the resources your plugin accesses, you can enable the security manager and do final testing of your PACL properties.

Test Your Plugin with the Security Manager Enabled

If you want to distribute plugins, either through the Liferay Marketplace or your web site, you have to assume potential users will insist that the Security Manager be enabled in your plugin. For this reason, you should enable it when testing your plugins.

To enable the Security Manger set the following property to true:


Then re-deploy your plugin and re-test its functionality. The Security Manager throws Java security exceptions if your plugin accesses resources that are not specified in your plugin’s security policy. As you test, keep track of these Java security exceptions so you can authorize access to the respective resources in the PACL properties of your file. Save your changes to the file, re-deploy the plugin, and re-test. Make sure everything works. If it doesn’t, there are more rules you must declare for your plugin. For additional details, refer to the online definition of the Portal Access Control List Properties for the file and refer to the PACL properties section at the end of this tutorial.

If you’re not finding an adequate way to specify a security rule with PACL, you can specify it in a Java Security Policy file. It’s almost impossible for Liferay and PACL to be aware of every possible security implementation check, because developers, libraries, and the Java Security API can always call for new types of security checks. Liferay, therefore, provides a Java Security Policy file as fallback to PACL . The policy file lets you specify operations permissible within the context of your app’s plugins.

In case you need it for your plugin, go ahead and get familiar with the Java Security Policy file.

Use a Java Security Policy File, if Necessary

If you can’t find a way to specify PACL permissions for an operation that your plugin must access, you can specify the permission in a Java Security Policy file. You can create the policy file (java.policy) in your plugin’s WEB-INF folder. The policy file must follow Policy File syntax as described in detail at Like the rules you define in your plugin’s PACL, the additional rules you define in your plugin’s Java Policy File, WEB-INF/java.policy, only apply to that plugin. Plugins aren’t privy to each other’s security policies.

Importantly, the Java policy file should only be used to specify rules Liferay’s PACL property implementation does not already support. You should not specify any rules in a Java policy file that you can specify in a PACL.

Here’s a scenario that calls for using a Java Security Policy:

Java has a security implementation called It checks a whole bunch of networking operations that Liferay’s implementation doesn’t check. In case you want to perform one of these operations, like using a custom Stream Handler, you can grant your plugin permission to do so in its WEB-INF/java.policy Java Security Policy file. Here’s one way to specify that rule:

grant codeBase "file:${my-supercool-portlet}${/}-" {
    permission "specifyStreamHandler";

This grant entry defines permission for the plugin’s code to access the specifyStreamHandler target operation of the class. The codeBase value, in this example, specifies the following:

  • file: indicates the code resides on the server’s file system.
  • ${my-supercool-portlet} represents the context path of a plugin named “My Supercool Portlet”. The context path is a system property Liferay generates for the plugin. It maps the context path name to the plugin’s fully qualified deployment path.
  • ${/} represents the system’s path separator.
  • - matches files and folders, in this folder and below.

On reading this plugin’s .jar file, the JVM creates a codebase for it. The codebase uses properties that Liferay sets for the plugin that in effect say, “If a file originates within the plugin, then this plugin can perform the specifyStreamHandler operation on it.” The codebase narrows the scope for the permission. This plugin is permitted to perform the defined operation specifyStreamHandler, as long as it is done within the scope the plugin.

How do you add more permissions to a codebase? Just define them on separate lines in the grant entry:

grant codeBase "file:${my-supercool-portlet}${/}-" {
    permission java.lang.RuntimePermission "loadLibrary.test_b";
    permission "specifyStreamHandler";

In this example, the plugin is granted permission to invoke native code that’s in some library ( This is another type of operation that Liferay’s PACL does not support. It, therefore, makes sense to specify permission for it in the Java Security Policy file.

With Liferay’s PACL policy and Java Security Policy files, you can precisely specify all of the resources your plugin needs to access! Now it’s time to revisit the file path values that the PACL Policy Generation Tool wrote to your file.

Convert PACL Absolute File Paths into Relative Paths

As mentioned earlier in this tutorial, using the PACL generation tool to give you a head start on specifying your plugin’s security rules is recommended. The generator, however, is only aware of file paths with respect to the current system. The file paths it genereates are absolute paths. To use your security policy in production, the policy should use only relative file paths. As a final step after testing the generated PACL, you must massage the generated file paths into the appropriate relative file paths. For example, you can specify paths relative to your Liferay web portal directory:


This example uses a dash (-) character at the end of the paths. It’s used as a wildcard character. Oracle defines wildcards to use with Java Security, and Liferay provides some too. You can leverage the following wildcard characters for files and file paths:

  • Dash (-) matches everything in the current directory and below, like you might expect with the normal GLOB operation in UNIX. The current directory is excluded from the match.
  • Star (*) matches every file (not directory) in the current directory. The current directory and subdirectories are excluded from the match.

For example, if you want to match all of your theme files and directories, specify…



NOT this:


The star means “every file in this single directory.” The dash, however, matches everything in this directory and below.

One more note. This:


does not include this:


The dash lets you read the contents of the directory, but not the directory itself. Also, when defining the directory don’t include a trailing slash–otherwise the directory itself won’t be included. For example, this specifies the themes directory and all its contents:


For file path separators, you can use the ${/} alias.

For example:

grant codeBase "file:${my-supercool-portlet}${/}-" {
    permission "specifyStreamHandler";

Congratulations! You now know how to specify your policy’s file paths appropriately for deployment on any server. Once you’ve completed testing your plugin without getting any Java security exceptions, you can distribute it as an app on Liferay Marketplace. You can do so with confidence because you’ve specified all of the resources it uses in the application’s PACL, and possibly its Java Security Policy. Your application satisfies Liferay Portal’s Security Manager.

The next section provides some additional details regarding PACL properties.

Portal Access Control List (PACL) Details

Liferay Portal’s Plugin Security Manager checks all your plugin’s API access attempts against the Security Manager properties specified in your plugin’s file. If your plugin tries to access a portal resource that is not specified in these properties, the Plugin Security Manager prevents it from happening. Consider this a virtual finger waggin’. To prevent this from happening, you have to tell the Plugin Security Manager up-front the access your plugin needs.

The online definitions for the PACL properties can be found at If you have the Liferay Portal source code, you can find the file in the liferay-portal/definitions folder.

Some of the properties accept wildcard characters that have special meaning. The following properties address file deletion, execution, reading, writing, and replacement operations.

  • The * character in a path name indicates all files in the current directory.
  • The - character in a path name indicates all files in the current directory and in its subdirectories.

Here’s an example that uses the - character to specify that the plugin is permitted to delete files in the ../webapps/chat-portlet/WEB-INF/src/com/liferay/chat/temp directory and its subdirectories:


Note that you can use relative paths in the file security properties.

You can also use a mix of UNIX/Linux and Windows style paths, as demonstrated here:


The following example uses the * character to specify that the plugin reads files in the ../webapps/chat-portlet/images and ../webapps/chat-portlet/WEB-INF/* directories, but not in their subdirectories:


For socket security properties, the * character represents any hostname. For example, * matches any host ending in, such as and In addition, *:* matches every socket and every port.

Awesome! Now you know how to build and test your plugin’s PACL. You also know how to use a Java Security Policy file in cases where the PACL just isn’t cutting it. Armed with this knowledge, you can confidently build, test, and deploy plugins that don’t end up on the wrong side of Liferay’s Plugin Security Manager.

Setting Permissions

Developing with the Plugins SDK

Developing Plugins with Liferay IDE

Developing with Maven

MVC Portlets

Liferay Faces

« Common Plugin Security PitfallsGDPR: Right to be Forgotten and Data Portability »
Was this article helpful?
0 out of 0 found this helpful