Lua Security Examples

lua security examples restrictive restrictive small

When the Lua Security Mode property is set to Restrictive, permissions need to be explicitly granted. Especially when the Lua Require Mode is also set to Restrictive, things can quickly get complicated.

This page illustrates Lua Security configuration for a number of common use-cases. Whenever Lua Libraries are involved, Lua Require Permissions need to configured before the obstacles resulting from general Lua Security configuration can be identified. The section on Granting General Lua Security Permissions illustrates how to configure Lua Security when all library-related issues have been solved or don’t occur at all.

Example 1 - Installing Examples With the Esi-Examples Library

According to DemoData Examples a number of objects which generate demo data can easily installed by running the following two lines of Lua code in the Console display:

local exm = require('esi-examples')
exm:SETUP({{"demodata", "iomodel"}})

In the Permissive Lua Security Mode, this works without any problems.

The First Attempt

But when you click the 'Run' icon when the Lua Require Mode is set to Restrictive, instead of the demo data objects being created in the I/O Model, the following error messages will be displayed :

Library Access Denied
Figure 1. Library Access Denied

Enabling Libraries for the Console Display

In this case, to allow the requiring of esi-examples, …​

  1. Go to Core > Lua Security Options > Strict Security Options and open Lua Library Permissions table property.

    The Lua Library Permissions Table Property
    Figure 2. The Lua Library Permissions Table Property
  2. There, enter esi-examples into the Library Name column. With the Script Library Object and the Security Subject set to <null>. This will allow all available libraries which called esi-examples.

  3. To make sure that only the built-in library can be required, right-click on Script Library Object column in this row, and select Set built-in.

  4. Additionally, the Security Subject could be specified by dragging-and-dropping the Profile for which the user is logged-in into the Security Subject column.

    The Esi-Examples Library in the Lua Library Permissions Table
    Figure 3. The Esi-Examples Library in the Lua Library Permissions Table
  5. Click OK and Apply the property changes.

  6. Go back to the Console Display and run the code again. Now the Examples/Demo Data branch is created in the I/O Model.

Enabling Libraries for Lua Executing Objects

When you expand the newly generated Examples/Demo Data branch, you will find all generic items in a bad state.

Generic Items Still in Bad State
Figure 4. Generic Items Still in Bad State

Looking at the properties panel for Examples/Demo Data/Process Data/DC4711, you will see the following error message in the Faceplate.

Error Message in the Properties Panel
Figure 5. Error Message in the Properties Panel

To see the full error message, right-click on the error message and select Zoom from the Context Menu.

The Expanded Error Message
Figure 6. The Expanded Error Message

So the Lua script on DC4711 actually started but stopped again, since 'esi-examples-samplehelpers' could not be found.

Adding Another Built-in Lua Library - for Lua Executing Objects

The 'esi-examples-samplehelpers' library needs to be added to Core > Lua Security Options > Strict Security Options > Lua Library Permissions.

To do this, …​

  1. Open the Lua Library Permissions table property, and …​

    The Lua Library Permissions Table Property
    Figure 7. The Lua Library Permissions Table Property
  2. …​ add a new row with esi-examples-samplehelpers in Library name column.

  3. This library is hosted by the Examples folder. To set this as the Script Library Object, click on the …​ icon in the respective table cell and select this folder in the Object Picker dialog, confirming the selection by clicking OK.

  4. Click OK to close the Lua Library Permissions table and Apply the property changes.

The Esi-Examples-samplehelpers Library in the Lua Library Permissions Table
Figure 8. The Esi-Examples-Samplehelpers Library in the Lua Library Permissions Table

Looking at the object states, nothing changes - at first glance.

Generic Items in Bad State
Figure 9. Generic Items in Bad State

Taking a closer look at the error message in the faceplate for object DC4711 reveals that the problem only occurs in line number 26, so the previous error has been resolved and the esi-examples-samplehelpers library successfully included by the script. Now the script fails due to some access being denied.

Inspecting the Next Error Message
Figure 10. Inspecting the Next Error Message

Granting General Lua Security Permissions

So far, only the Lua Library Permissions for the LEOs are configured but no Lua Security Permission in general.

Before the script running on DC4711 can access any system object, access rights need to granted for the connection between this targeted system object (or its parent branch in the I/O Model) and the Lua Executing Object DC4711 (or parent branch).

  1. In the Access Model, create a new Script Profile, enabling the I/O Model in the Model Authorization section. In this example, this Script Profile is called DemoData Script Profile. It fulfills the role of the Security Subject, which means that it connects system objects and Lua Executing Objects, controlling the access rights.

  2. To link the Lua Executing Objects to this Security Subject …​

    1. …​ open the Properties Panel for the newly created Script Profile object and open the Assigned Objects property table, and …​

    2. …​ in the I/O Model, select the DemoData folder and drag-and-drop it into the Assigned Objects column of the first empty row of the table and click OK. This adds this folder itself as well as all its descendants as allowed Lua Executing Objects to this Script Profile in its role as the Security Subject.
      Alternatively, Assigned Objects can be added by clicking on the …​ icon and using the Object Picker dialog.

      The Assigned Objects Table of the DemoData Script Profile
      Figure 11. The Assigned Objects Table of the DemoData Script Profile
  3. To connect the system objects which are to be accessed by the Lua scripts with the Security Subject …​

    1. drag-and-drop the Script Profile from the Access Model onto the Examples/Demo Data folder in the I/O Model and grant List, Read, Write, and Inheritable permissions. This adds the padlock-icon to the Demo Data folder.

Now the all the Generic Items in the Examples/Demo Data branch change into a good state. For some objects this may take a little longer, depending on the value configured for their Generation Period property.

Generic Items in Good State
Figure 12. Generic Items in Good State

Example 2 - ODBC DataSource

Building upon the first example, where we granted permissions for the esi-examples library and succesfully created the Examples > Demo Data branch in the I/O Model, in this example we create an ODBC connection to this demo data.

So execute the following code in the Console:

local exm = require('esi-examples')
exm:SETUP({{"odbc"}})

This should generate Examples/LUA/ODBC Access branch in the I/O Model. If this fails, check the section on Enabling Libraries for the Console Display above.

When you expand the newly generated branch in the I/O Model, your will see something similar to this:

The Lua/ODBC Branch With Generic Objects in Bad State
Figure 13. The Lua/ODBC Branch With Generic Objects in Bad State

The Read and Wrtite Generic Items are not working correctly. Looking at the Faceplate of the Read object, you see that the library called luasql.odbc can not be found.

The Error Message in the Faceplate of the Read Object
Figure 14. The Error Message in the Faceplate of the Read Object

Right-click on the Faceplate and select Zoom from the context menu to get more detailed information: access to the luasql.odbc library which was attempted on line number 1, is denied.

Zoom-View of the Error Message for the Read Object
Figure 15. Zoom-View of the Error Message for the Read Object

The library luasql.odbc needs be added to the Lua Library Permissions table property in Core > Lua Security Settings > Strict Security Options

+

The Lua Library Permissions Table Property
Figure 16. The Lua Library Permissions Table Property
The 'luasql.odbc' Library in the Lua Library Permissions Table
Figure 17. The 'luasql.odbc' Library in the Lua Library Permissions Table

To make sure that only the built-in library can be included into Lua scripts, right-click on Script Library Object and select Set built-in from the context menu. To restrict which Lua Executing Objects can require the specified library, add the object which acts as the Security Subject for these scripts into the Security Subject column. This object can either be selected from the Object Picker dialog or dragged-and-dropped into this table cell.

Once the Lua Library Permissions for the luasql.odbc library are granted, the Read object turns green - indicating that the script hosted by this object could successfully read via the ODBC connection.

First Success - Read ODBC Connection is Working
Figure 18. First Success - Read ODBC Connection is Working

The Write object is still red.

The 'Read' Object Showing an Error on Line Number 18
Figure 19. The 'Read' Object Showing an Error on Line Number 18

The error is shown for line number 18, where the value of nil for the variable pdatafldr causes problems. But the original problem actually occurs on line number16, where the function syslib.findobjects() searching for the string Process Data among the system object names, does not return a useful result. This happens because -at the current state of configuration- the script is not allowed to access any object in the system. Again, access needs to be granted via a Security Subject.

  1. Create a new Script Profile in the Access Model, e.g. called ODBC Script Profile.

    Adding a New Script Profile for the ODBC Example
    Figure 20. Adding a New Script Profile for the ODBC Example
  2. Add the ODBC Access Folder object to the Assigned Objects table propery of the Script Profile created in the previous step.

    The 'Assigned Objects' of the ODBC Script Profile
    Figure 21. The 'Assigned Objects' of the ODBC Script Profile
  3. Drag-and-drop this Script Profile onto the sub-branch in the I/O Model which you want to make accessible to all Lua Executing Objects listed in the Script Profile’s Assigned Objects table property. As this example looks for objects called Process Data, so drag-and-drop onto an ancestor of the Process Data folder and grant List, Read and Inherit permissions.

  4. After a brief moment the Read object will turn green.

Second Success - The Example for ODBC Write is Also Working
Figure 22. Second Success - The Example for ODBC Write is Also Working

Example 3 - WebAPI

The Web API Server makes use of Lua libraries. Therefore -if the Lua Require Mode is set to Restrictive- libraries need to be actively permitted for the WebAPI Server.
As the WebAPI Server by definition uses the webapi Profile in the Access Model, this Profile already acts as the Security Subject for the WebAPI Server. Therefore the easiest solution is to add a row to the Lua Library Permissions table, limiting access to libraries by the Security Subject only. To do so …​

  1. Select the Core in the I/O Model, …​

  2. …​ navigate to Common > Lua Security Settings > Restrictive Security Settings and click on the table icon for Lua Library Permissions.

    The Lua Library Permissions Table Property
    Figure 23. The Lua Library Permissions Table Property
  3. Next, drag-and-drop the webapi Profile from the Access Model into the Security Subject column of the last/'new' row of the Lua Library Permissions table.

    Granting Library Permissions for the WebAPI Server
    Figure 24. Granting Library Permissions for the WebAPI Server
  4. Then click OK to close the table and confirm the changes to the properties by clicking Apply.