Plugin System

pySigma implements a plugin architecture that decouples the development of the following entities from the core pySigma library:

The plugin system resides in the sigma.plugins module and takes care of providing information about available plugins as well as their installation with the SigmaPluginDirectory class. The InstalledSigmaPlugins discovers classes provided by plugins and allows the usage via defined identifiers if the plugin modules follow certain conventions.

Implementing Plugins

Python Module

Each module that wants to be recognized as pySigma plugin must provide a mapping between identifiers and their respecitve definitions in their module. Plugins are generally implemented as namespace packages with following conventions:

  • Backends reside as module in the namespace package sigma.backends and provide a dict backends with the mapping between identifiers and backend classes.

  • Processing pipelines reside as module in the namespace package sigma.pipelines and provide a dict pipelines with the mapping between identifiers and a function that returns a sigma.processing.pipeline.ProcessingPipeline object.

  • Rule validators reside in the namespace package sigma.validators and provide a dict validators with the mapping between identifiers and rule validator classes.

The most straightforward way is to import all classes that should be available as plugin class in the __init__.py of the module and add them to the mappings mentioned above.

Plugin Directory

The pySigma plugin directory is the central list of public available plugins for installation. It’s format is described in the README file of the project. The directory itself is consumed by the Sigma CLI for discovery. Therefore, each plugin that should be available for usage with the CLI must be added to the directory.

Discover Available Plugins

The SigmaPluginDirectory class is an interface to the Sigma plugin directory. The following code instantiates an object of this class with the current content of the plugin directory:

plugins = SigmaPluginDirectory.default_plugin_directory()

This class also allows to use alternative plugin directories with the sigma.plugins.SigmaPluginDirectory.from_url() method.

A list of available plugins is then returned by this code:

plugins.get_plugins(
    plugin_types={ SigmaPluginType.BACKEND },
    plugin_state={ SigmaPluginState.STABLE },
    compatible_only=True,
)

This code returns all stable backends that are compatible with the used pySigma version as list of SigmaPlugin objects. Instances of these classes can be used to install a plugin as follows:

plugin.install()

Discover Installed Plugins

The class InstalledSigmaPlugins main purpose is the discovery of classes provided by plugins. It is usually instantiated with the following code:

plugins = InstalledSigmaPlugins.autodiscover()

This initates the object with all classes found by the autodiscovery process that utilizes the mapping described above. The plugin classes can then be referenced as follows:

plugins.backends["backend-indetifier"]
plugins.pipelines["pipeline-indetifier"]
plugins.validators["validator-indetifier"]

Further, a pipeline resolver can be instantiated with:

plugins.get_pipeline_resolver()