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()
class sigma.plugins.SigmaPluginDirectory(plugins: ~typing.Dict[~uuid.UUID, ~sigma.plugins.SigmaPlugin] = <factory>, note: str | None = None)

A directory of pySigma plugins that can be loaded from the pySigma-plugin-directory repository or an arbitrary location.

classmethod default_plugin_directory(*args, **kwargs) SigmaPluginDirectory

Loads the plugin directory from the pySigma-plugin-directory repository. All further arguments are passed to requests.get().

classmethod from_url(url: str, *args, **kwargs) SigmaPluginDirectory

Loads the plugin directory from an arbitrary location. All further arguments are passed to requests.get().

get_plugins(plugin_types: Set[SigmaPluginType] = {SigmaPluginType.BACKEND, SigmaPluginType.PIPELINE, SigmaPluginType.VALIDATOR}, plugin_states: Set[SigmaPluginState] = {SigmaPluginState.BROKEN, SigmaPluginState.DEVEL, SigmaPluginState.ORPHANED, SigmaPluginState.STABLE, SigmaPluginState.TESTING}, compatible_only: bool = False) List[SigmaPlugin]

Return a list of plugins with the specified type and state. Returns all plugins if not specified.

class sigma.plugins.SigmaPlugin(uuid: ~uuid.UUID, type: ~sigma.plugins.SigmaPluginType, id: str, description: str, package: str, project_url: str, report_issue_url: str, state: ~sigma.plugins.SigmaPluginState, pysigma_version: ~packaging.specifiers.Specifier, capabilities: ~typing.Set[~sigma.plugins.SigmaPluginCapability] = <factory>)

Sigma plugin description corresponding to https://github.com/SigmaHQ/pySigma-plugin-directory#format

classmethod from_dict(d: Dict) SigmaPlugin

Construct a SigmaPlugin object from a dict that results in parsing a plugin description from the JSON format linked above.

has_capability(capability: SigmaPluginCapability) bool

Checks if the plugin has the specified capability.

install()

Install plugin with pip.

is_compatible() bool | None

Checks if the pySigma version specifier of the plugin matches the used pySigma version. Returns None if current version can’t be determined, e.g. if pySigma was not installed as package.

uninstall()

Uninstall plugin with pip.

upgrade()

Upgrade plugin with pip.

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()
class sigma.plugins.InstalledSigmaPlugins(backends: ~typing.Dict[str, ~sigma.conversion.base.Backend] = <factory>, pipelines: ~typing.Dict[str, ~typing.Callable[[], ~sigma.processing.pipeline.ProcessingPipeline]] = <factory>, validators: ~typing.Dict[str, ~sigma.validators.base.SigmaRuleValidator] = <factory>)

Discovery and registration of installed backends, pipelines and validator checks as plugins.

This class represents a set of the objects mentioned above that are available. Further it implements autodiscovery of them in the sigma.backends, sigma.pipelines and sigma.validators module namespaces.

classmethod autodiscover(include_backends: bool = True, include_pipelines: bool = True, include_validators: bool = True)

Automatically discovers backends, pipelines and validators in their corresponding module namespaces and return a InstalledSigmaPlugins class containing all identified classes and generators.

get_pipeline_resolver() ProcessingPipelineResolver

Returns a ProcessingPipelineResolver object with all discovered pipelines.