Plugin Components

The following sections document the major plugin components at a high-level. For more details, read Plugin Spec next.

Connection

Each plugin may contain a connection, which is the piece of code that handles authentication. The connection code is run before other componenets and thus can be used to initialize libraries. It can also set up shared variables and code that can be used in the subsequent components: actions and triggers.

Here are some facts about connections:

  • Connections are optional for plugin development
    • A plugin that does not connect over a network to a service typically doesn’t need a connection
  • Connections are reusable in the products
    • Users can have multiple connections, each attached to separate workflows e.g. the IMAP plugin can have a connection for each user mailbox to monitor
  • Connection inputs using the credential types are encrypted
  • Connection schema is defined in the plugin spec e.g. plugin.spec.yaml
  • Connection code lives in icon_$PLUGIN_NAME/connection/connection.py

Individual plugin authors are responsible for writing the schema and connection code.

Actions

Each plugin may contain one or more actions, which are short running processes that execute and then exit. Workflows typically contain many actions chained together. Plugin code is executed in a Docker container. As the action initializes, the connection object is created and then the action code runs.

Example uses:

  • If you need to make an API request and return the results.
    • E.g. Deprovision a user
    • E.g. Create a JIRA ticket
    • E.g. Make an LDAP query
  • If you need to run a command/utility and return the results.
    • E.g. Run an Nmap scan
    • E.g. Run a base64 decode function

Here are some facts about actions:

  • Actions, if present, are executed after a workflow trigger
  • Actions are optional for plugin development, and there can be more than one
  • Actions are short running processes
  • Action failure may stop the workflow
    • Depends if Continue workflow on step failure is set for the plugin in the workflow builder
    • Stopping the workflow may be desirable if the rest of the workflow depends on the success of the action
    • Continuing the workflow may be desirable if the rest of the workflow can handle the failure of the action
  • Action schema is defined in the plugin spec e.g. plugin.spec.yaml
  • Action code lives in icon_$PLUGIN_NAME/actions/$ACTION_NAME/action.py

Individual plugin authors are responsible for writing the schema and action code.

Triggers

Each plugin may contain one or more triggers which are long running processes that poll for / emit a new event and then send the event to the engine to kick off a workflow. Because of how workflows get fed data, all workflows must start with a trigger. When a workflow is activated, the plugin with the trigger is executed in a Docker container. As the trigger initializes, the connection object gets created and then the trigger enters a loop where it waits for a message or polls for new data.

Example uses:

  • If you need to poll an API, web site, etc, for changes, a trigger is a good candidate mechanism for doing so.
    • E.g. Monitoring JIRA for newly created tickets on a board, and trigger when found
    • E.g. Monitoring a Twitter account for new messages, and trigger when found
  • If you need to open a socket, to listen for messages, a trigger is a good candidate mechanism for doing so.
    • E.g. Open a Kafka listener, and trigger on any new messages
    • E.g. Create a custom HTTP server to listen for messages from ElastAlert, and trigger on them

Here are some facts about triggers:

  • All workflows must start with a trigger
  • Triggers are optional for plugin development, and there can be more than one
  • Triggers are long running processes
  • Trigger failure will stop a workflow from functioning
    • Triggers need to be made resilient
  • Trigger schema is defined in the plugin spec e.g. plugin.spec.yaml
  • Trigger code lives in icon_$PLUGIN_NAME/triggers/$TRIGGER_NAME/trigger.py

Individual plugin authors are responsible for generating the schema and writing the trigger code.