Writing Lua scripts
This page explains how to integrate Lua scripts in Airlock IAM with the Input Value Providers and the Expected Output properties of the Scriptable Step plugin. For more information on Lua itself see The Programming Language Lua.
When programming a Lua script, the following configuration properties are available:
Property | Mandatory | Description |
---|---|---|
Input Value Providers | optional | List of value map providers that provide input values for the Lua script. |
Script | mandatory | Source code of the Lua script |
Expected Output | optional | List of keys and data types to return values to Airlock IAM. |
Input Secrets | optional | Secrets provided to the Lua script. |
Namespace | optional | Namespace for output values to segregate output from multiple Lua scripts. |
The following screenshot gives an impression of a fully configured scriptable step:
Output Map
A list of keys must be configured to return output values to Airlock IAM.
To integrate a script correctly, the following conditions must be met:
- The script must return all mandatory keys.
- The script cannot return undeclared keys.
- The data types of the output values must match the declaration.
- If no Output Map is configured, the
return
statement is optional.
If one of these conditions is not met, an error will result, and the flow will be terminated as failed.
To convert output values into a strongly typed value provider map in Airlock IAM, each key must be configured with its data types and whether this key is optional.
IAM currently supports the following data types for output values of scripts:
- The output value must be a string (UTF-8 format).
- Boolean: The output value must either be
true
orfalse
.
Binary digits are not allowed. - Number: The output value must be an integer (64-bit constraints).
Floating point values are currently not supported. - Date-Time must be an integer-type Unix timestamp with millisecond precision.
- The Date must be a valid date string in the format
yyyy-MM-dd
(e.g. 2021-06-04)
To use the examples below, the Output Map property must be configured with a Key full_name
and a Script Output Declaration plugin with an Output Value Type property set to STRING
.
Script
To successfully run a script in the scripting step plugin, at least the following function must be defined in the script property:
function iam_on_step_init () <your code> return iam.output_map end
The iam_on_step_init()
function is called by IAM when starting the execution of a script.
Input Map
Input values are configured in the scriptable step plugin through value map providers. For this purpose, Airlock IAM provides a large number of plugins. Refer to the plugin documentation for further information on a particular value map provider.
All the examples in this text configure the Input Map property with a Context Data Map plugin. To read a context data item, the iam.input_map[<key>]
table must be used in the script code.
The following example shows how a user's givenname
and surname
are concatenated into a property full_name
. This property is then logged and finally returned to IAM for further use.
function iam_on_step_init () iam.output_map = {} iam.output_map["full_name"] = iam.input_map["givenname"] .. " " .. iam.input_map["surname"] iam.log:info("User with full name: " .. iam.output_map["full_name"]) return iam.output_map end
If multiple value map providers contain a key with the same name, the value from the last value map provider will overwrite previous values.
Optional input values
When configuring value provider maps with optional values, it is the script's responsibility to check whether a particular value is present. In case of a missing value, the iam.input_map[<key>]
will return the value nil
.
The following code example will check if the key givenname
is present or not:
if (iam.input_map["givenname"] ~= nil) then <logic if given name is present> else <logic if given name is absent> end
List all values provided to the script
The following code snippet will iterate over the table of input values provided to the script and output them to the IAM logfile:
for k, v in pairs(iam.input_map) do iam.log:info("key : " .. k .. ", value: " .. v) end
The following code snippet will achieve the same result, with less formatting:
iam.log:info("Complete input map of GET request step: " .. iam.cjson.encode(iam.input_map))
Input Secrets
Use this property to provide sensitive values to a Lua script. Sensitive values are transferred to the Lua script as environment variables. In the script, these values can be accessed through the IAM API function local secret = iam.secrets:get(<secretId>)
.
Once made available within the Lua script, secrets are retrieved as plaintext. The script developer is responsible for ensuring that secrets are not leaked (e.g., not logged).
The secretId
can only consist of alphanumeric and underscore characters.
Namespaces
Namespaces are optional. They are used to assign a name to the value map from the output of a script. This may be necessary if multiple scripts in the same flow can return an output value with the same key.
If no Namespace is configured, the default namespace is used. If several steps return the same key into the default namespace, the value of the scripting step executed last will overwrite the previous value.
Lua API functions
The Lua scripting language provides several built-in functions and types.
The print()
function has been modified for Airlock IAM. It now writes messages to the appropriate Airlock IAM logfile with severity DEBUG
.
All other built-in functions and types remain as implemented and documented by Lua.
Care should be taken when using the os
object or functions like load()
, loadfile()
, or dofile()
. These functions may have security-relevant side effects as they are run with the IAM user's permissions and can access processes and file system objects.
IAM API functions
Airlock IAM provides additional and IAM-specific functions for scripting with Lua:
Function | Description |
---|---|
| This table contains all the key-value pairs provided to the script by configuring the Input Value Providers. Use the key to access the value within the table. If the value is not present, “nil” is returned. Date-time values include the precise time of day and are represented as a Unix timestamp with millisecond precision. Date values exclude the time, and are specified as strings in the format |
| Use these functions to write messages to the Airlock IAM Log4J log files. The severity of the log message is determined by the function used in the script. All log message output of a Lua script will be prefixed with The Logging uses the standard error output stream. If the script or a library used in the script directly writes to standard error, this will be interpreted as an error message with severity ERROR. Data written to standard output will be ignored. |
| This function retrieves a value from secret storage and returns it as plaintext to the script. The key and value of secrets are defined in the IAM configuration. If the value is not present, “nil” is returned. |
| This is an alias for the bundled It is used implicitly by other IAM API functions. See Lua CJSON 2.1.0 Manual for more details. |
Error handling
The Config Editor does not verify the correctness of the Lua script syntax or semantics during configuration activation.
The following behavior is to be expected:
Syntax error | Syntax errors will be reported before the scriptable step is executed. The step will fail, and an error will be reported in the IAM log. |
Runtime error | Runtime errors will be reported if the error occurs during the execution of the scriptable step. The step will fail, and an error will be reported the IAM log. |
We recommended testing custom scripts before they are deployed with Airlock IAM.
The scriptable step supports the following error codes:
Error code | Description |
---|---|
20 | A syntax error is present in the script source. |
21 | A runtime error occurred. This type of error is printed together with a Lua stack trace, showing the cause and location of the error. |
22 | The value returned by the
|
24 | The value returned by the This error occurs when data (e.g., a function reference) inside the expected output cannot be converted to a string. |
27 | An error occurred when using the IAM API functions (e.g. trying to access a secret using an identifier that isn't a string). |
126 | This error occurs if the operating system cannot execute the |
- | If a script does not terminate within 30 seconds, the script is aborted, and the following message is written with severity ERROR to the logfile:
|
Lua library bundles
Lua can be extended with libraries by placing the necessary files in the correct folder of the instance directory. The following table explains the types of libraries and the expected directory locations:
Library type | File extension | Directory |
---|---|---|
Libraries written in Lua itself and provided as source code. |
|
or
|
Libraries written in C/C++ and provided as shared object libraries. |
|
or
|
Once a library is placed in the directory structure outlined above, it can be used in scripts with the require
function of Lua.
When adding additional libraries, you must ensure that the libraries are compatible with the installed version of Lua. See the Lua compatibility matrix here: Scriptable step overview - an incubating feature.
Building libraries with Luarocks
The package manager for Lua is Luarocks. The package manager should be installed on a system running the same operating system as the target architecture of Airlock IAM. This is necessary to ensure that shared object libraries will work correctly on the IAM target operating system.
When installed and configured, additional packages can be built and installed locally using the following command:
./luarocks install --tree <install_path> <lib_name> <lib_version>
Parameter | Description | Example |
---|---|---|
| The directory where Luarocks should place the library files. Luarocks knows the different library bundles types and will automatically add the Luarocks will also add directory levels to manage different Lua versions in parallel. |
|
| The name of the library. |
|
| The version of the library. |
|
Further information and links
External links:
- See The Programming Language Lua for more information about programming in Lua.
- See The Luarocks package manager for more information about using libraries with Lua.