IBM Support

App File Structure

How To


Summary

An IBM® QRadar® app that you create is distributed within a compressed file.

The Hello World sample app that is created when you set up your development environment is a basic template that you can use for your application. However, the application file structure can be more complex.

Steps

The following list outlines the layout of files and sub directories that you can add to the root directory of your app. It also outlines the required nomenclature for app files and sub directories:

  • App Root Folder
    • app/ - Main directory for application files
    • app/__init__.py - Main entry point into the web app.
    • app/views.py - File that contains view functions which respond to requests to your application
    • app/templates - Optional subdirectory that contains any Python Flask or Jinja templates that are required by the app.
    • app/static - Optional subdirectory that contains CSS, JavaScript, globalization, and other resource files.
      • app/static/css - Cascading style sheets used by the app.
      • app/static/js - Javascript files used by the app.
      • app/static/resources - Resource bundle properties files used by the app. Text strings for globalization are stored as key/value pairs in Java format properties files. If you configured text strings for globalization, they appear in QRadar when the user sets their preferences for the relevant locale. Note: If no matching resource bundle properties file is found it will default to the english translation if present.
    • container/ - Optional directory that can be added with any of the following subdirectories
      • container/pip - This contains any extra Python libraries that the app requires. See Source dependencies for more details
      • container/rpm - This contains any RPM dependencies that the app requires. RPMs must be RHEL 8 x86_64 compatible. See Source dependencies for more details.
      • container/build - This contains any dependencies that the app requires that are not RPMs or Python libraries. See Build and Runtime dependencies for more details.
      • container/run - This contains any dependencies that the app requires that are not RPMs or Python libraries. See Build and Runtime dependencies for more details.
      • container/clean - This contains cleanup.sh script a shell script that is executed during container shut down. This shell script can be used to shutdown app processes gracefully e.g. database connections.
      • container/service - This contains scripts that start background processes used in the app container.
      • container/conf - This contains configuration files for any services and general use.
      • container/conf/supervisord.d - This contains supervisord include files. The contents of this directory will be copied to /etc/supervisord.d/ and will be included as a part of the supervisord configuration at container startup
    • manifest.json - The application manifest description file. See Application manifest structure for more details

Application manifest structure

The manifest is a JSON file that describes to IBM QRadar the capabilities that the app provides.

The following table describes the fields that you can include in the manifest.json file.

Table 1. Application manifest fields

Field Required Type Description
name Yes String The user-readable name of the app. If the app is globalized this field can optionally point at a resource bundle key.
description Yes String The user-readable description of the app. If the application is globalized, this field can optionally point at a resource bundle.
version Yes String A version string for the app. We recommend you use the following format x.x.x e.g. 1.0.0
uuid Yes String An RFC 4122-compliant universally unique identifier for the application.
The create command uses the Python UUID package to generate a random 128-bit number for the uuid value.
If you do not use the SDK to create the app manifest file, you must manually enter a unique value in the uuid field.
image No String The base image name to use when building your application. If none is specified the default base image is used
authentication No String Authorization for the app to access QRadar. The only mandatory entry is “requested_capabilities”: [""].
For example, admin is a commonly used user capability.Enter at least one supported QRadar user capability. The installation fails if any of the requested_capabilities are not defined in QRadar.
load_flask No Boolean Set to false when you don’t want to make Python Flask framework available to your app. Typically, you might disable Flask when you want your app to use a different web application framework.
If not specified, this field defaults to true.
areas No Array of Area Type Area objects describe new complete pages of the application. In QRadar, Area objects are represented as tabs.
rest_methods No Array of REST Method Type REST Method objects describe REST methods that the app exposes. REST Method objects are required parameters for Dashboard Items and Metadata Providers, and are optional for GUI Actions.
dashboard_items No Array of Dashboard Item Type Dashboard Item objects describe the contents of new items that you want to expose to the QRadar dashboard.
configuration_pages No Array of Configuration Page Type Configuration Page objects describe new complete pages of the app that represent configuration. In QRadar, configuration pages are opened from the Admin tab.
gui_actions No Array of GUI Action Type GUI Action objects describe new actions that can be performed on items in the user interface by page toolbars or by right-click menus.
page_scripts No Array of Page Script type Page Script objects describe new JavaScript files that you want included within an existing page in QRadar. By default, these scripts run in their own namespace.
metadata_providers No Array of Metadata Provider type Metadata Provider objects describe REST methods that can be called to fetch new metadata information for certain data types in QRadar e.g. IP. Metadata is shown in tooltips when a mouse is hovered-over an item.
resource_bundles No Array of Resource Bundle type Resource Bundle objects are used for language locales and locale properties file locations.
resources No Integer Resource objects are used to configure the amount of memory in megabytes that is available for the app to use.
fragments No Array of Fragments type Fragment objects are used to determine the injection point in the QRadar UI where content is added and the rest endpoint that is used to retrieve the content.
custom_columns No Array of Custom Columns type Custom column objects are used to identify the context (the page and table in the QRadar UI) where a custom column is added, a label for the column header, the type of data to be added, and the rest endpoint that is used to add the column content.
multitenancy_safe No Boolean If set to true, this key indicates that your application can work in a multi-tenant environment. If not set to true, it indicates thatonly one instance of your app can be created, and any user who is a member of a tenant is not able to see it.
If not specified the default is false.
single_instance_only No Boolean If set to true, only one instance of this app can be created. Typically, this indicates that this application can either provide multi-tenancy support itself, or that use of this application is meant only for administrators. If multitenancy_safe is also not set true, then users who are a member of a tenant cannot see this app. If multitenancy_safe is also set to true, then all users can see the app.
If not specified the default is false.
use_qradar_csrf No Boolean If set to true csrf support is handled by QRadar for the app. If not specified the default is false.
environment_variables No Array of Environment Variable type Environment variable objects are used to specify environment variables that will be available within the container during runtime
services No Array of Service type Service objects are used to define named services, service endpoints, and supervisord configuration parameters.

Source dependencies

If your app requires dependencies, such as RPMs or Python libraries

The container directory can contain these optional sub directories:

pip

Use the pip folder to install extra Python libraries. For example, if your application requires the observable-0.01.00 Python library, add the observable-0.01.00.tar.gz file to the pip folder.

Don't use .tar files for Python libraries that include extra C-based extensions. Instead, add libraries as Python wheel files (.whl), which have C-based extensions pre-compiled.

You must install Python wheel files on the same system architecture they were compiled upon. To work with IBM® QRadar® application framework v2, wheel files must be compiled on RHEL 8 x86_64. If it uses compatible architecture, you can use the Python bdist_wheel command to create wheel files from a library's source code on your own system. The command python setup.py sdist bdist_wheel creates the wheel file when you run it from within the root directory of the Python library's source folder.

A useful alternative to manually downloading Python packages for your app is the pip2pi Python package. It requires pip and you can install it on your development computer by using the pip install pip2pi command. After you install this package, you run the following command:

pip2tgz <target-directory> <Python package>

For example, the following command downloads the package's wheel, along with its dependencies, into the specified folder.

pip2tgz python_packages/pytest/ pytest==2.8.2

The == parameter is optional after pytest in the command above and is used to download a specific version of the package.

For Python libraries that have dependencies, you can include an optional ordering.txt file in the pip folder to specify the order in which Python libraries are installed. This text file must include the names of files that are in the pip folder. File names must be separated with a new line (UNIX line endings) in the order that you want them installed.

pytz-2020.1-py2.py3-none-any.whl
Babel-2.8.0-py2.py3-none-any.whl
speaklater-1.3.tar.gz
Flask-Babel-1.0.0.tar.gz

rpm

Use the rpm folder to install extra Red Hat Enterprise Linux (RHEL) RPMs. The RPMs must be RHEL 8 x86_64 compatible.

For RPMs that have dependencies, you can include an optional ordering.txt file in the rpms folder to specify the order in which RPMs are installed. This text file must include the names of files that are in the rpms folder. File names must be separated with a new line (UNIX line endings) in the order you want them installed.

nginx-1.17.8-1.el8.ngx.x86_64.rpm
nodejs-10.19.0-1.module+el8.1.0+5726+6ed65f8c.x86_64.rpm
npm-6.13.4-1.10.19.0.1.module+el8.1.0+5726+6ed65f8c.x86_64.rpm

Build and Runtime dependencies

If your app requires additional configuration dependencies at image build time or at container startup

The container directory can contain these optional sub directories:

Build

Use the build folder to perform additional configuration changes during the docker build process for the app. In order for your app to be available for use as quickly as possible after installation we recommend moving as many steps as possible to image build time. Similar to the source dependency folders an ordering.txt file needs to be created under this folder. This text file must include cli commands separated with a new line (UNIX line endings) in the order you want them executed.

For example:

Post configuration after installing nginx via an rpm install in a container, container/build - ordering.txt file contents:

/opt/app-root/container/build/deploy.sh

In the above ordering.txt file we are executing one shell script that will complete the configuration of nginx after the rpm installation

Example deploy.sh:

#!/bin/bash

rm /etc/nginx/conf.d/default.conf
cp ${APP_ROOT}/container/build/nginx.conf /etc/nginx/nginx.conf
cp ${APP_ROOT}/container/build/server.conf /etc/nginx/conf.d/server.conf

In the above example deploy.sh would be executed as part of the docker image build process. This is copying the app's version of nginx.conf and server.conf from the container build folder to the correct places inside the image for nginx.

  1. APP_ROOT is available as an environment variable inside the container and can be used to refer to the app root directory
  2. As the persistent store for the app i.e. /opt/app-root/store will only be available at container runtime you will not be able to alter anything in that directory using this method you would need to add commands to the run section outlined below

Runtime

Use the run folder to perform additional configuration changes during docker container startup. In order to specify which commands to run you need to create a file called ordering.txt under this folder. This text file must include cli commands separated with a new line (UNIX line endings) in the order you want them executed.

For example, loading certificates into the trusted ca certificate bundle previously uploaded via the app:

as_root ${APP_ROOT}/bin/update_ca_bundle.sh

In the above ordering.txt file we are executing a shell script that exists in the container by default for loading certificates stored under /opt/app-root/store/certs into the CA trust certificate bundle

  1. All commands now execute as appuser by default and the above command requires root permissions so you need to execute it with a special script called as_root which is available during container startup. The as_root command should be used only when necessary
  2. If as_root is not needed or potentially causes a security issue then the app may fail our validation

Document Location

Worldwide

[{"Line of Business":{"code":"LOB24","label":"Security Software"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SSBQAC","label":"IBM Security QRadar SIEM"},"ARM Category":[{"code":"a8m0z000000cwt3AAA","label":"QRadar Apps"}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Version(s)"}]

Document Information

Modified date:
30 March 2021

UID

ibm16437529