Playbook
  • 05 Feb 2025
  • 5 Minutes to read
  • Contributors
  • Dark
    Light

Playbook

  • Dark
    Light

Article summary

Private Beta

Playbooks are currently in private Beta. If you would like access, please reach out to us at support@limacharlie and include the use cases you intend to implement.

The Playbook Extension allows you to execute Python playbooks within the context of your Organization in order to automate tasks and customize more complex detections.

The playbooks themselves are managed in the playbook Hive Configurations and can be managed across tenants using the Infrastructure as Code extension.

The execution of a playbook can be triggered through the following means:

  1. Interactively in the web app by going to the Extensions section for the Playbook extension.

  2. By issuing an extension request action through a D&R rule.

  3. By issuing an extension request on the API directly: https://api.limacharlie.io/static/swagger/#/Extensions/createExtensionRequest

  4. By issuing an extension request through the Python CLI/SDK or Golang SDK.

This means playbooks can be issued in a fully automated fashion based on events, detections, audit messages or any other target of D&R rules. But it can also be used in an ad-hoc fashion triggered manually.

Usage

When invoking a playbook, all you need is the playbook name as defined in Hive. Optionally, a playbook can also receive a JSON dictionary object as parameters, this is useful when triggering a playbook from a D&R rule and you want to pass some context, or when passing context interactively.

D&R rule example

Here is an example D&R rule starting a new invocation of a playbook.

- action: extension request
  extension name: ext-playbook
  extension action: run_playbook
  extension request:
    name: my-playbook
    credentials: hive://secret/my-api-key
    data:
      some: data
      for_the: running of the playbook

Python example

# Import LC SDK
import limacharlie
# Instantiate the SDK with default creds.
lc = limacharlie.Manager()
# Instantiate the Extension manager object.
ext = limacharlie.Extension(lc)

# Issue a request to the "ext-playbook" extension.
response = ext.request("ext-playbook", "run_playbook", {
    "name": "my-playbook",
    "credentials": "hive://secret/my-playbook-api-key",
    "data": {
        "some": "data"
    }
})

# The returned data from the playbook.
print(response)

Playbook structure

A playbook is a normal python script. The only required component is a top level function called playbook which takes 2 arguments:

  • sdk: an instance of the LC Python SDK ( limacharlie.Manager() ) pre-authenticated to the relevant Organization based on the credentials provided, if any, None otherwise.

  • data: the optional JSON dictionary provided as context to your playbook.

The function must return a dictionary with the following optional keys:

  1. data: a dictionary of data to return to the caller

  2. error: an error message (string) to return to the caller

  3. detection: a dictionary to use as detection

  4. cat: a string to use as the category of the detection, if detection is specified.

This allows your playbook to return information about its execution, return data, errors or generate a detection. The python print() statement is not currently being returned to the caller or otherwise accessible, so you will want to use the data in order to return information about the execution of your playbook.

Example playbook

The following is a sample playbook that sends a webhook to an external product with a secret stored in LimaCharlie, and it returns the data as the response from the playbook.

import limacharlie
import json
import urllib.request

def playbook(sdk, data):
  # Get the secret we need from LimaCharlie.
  mySecret = limacharlie.Hive(sdk, "secret").get("my-secret-name")["secret"]

  # Send the Webhook.
  request = urllib.request.Request("https://example.com/webhook", data=json.dumps(data).encode('utf-8'), headers={
    "Content-Type": "application/json",
    "Authorization": f"Bearer {mySecret}"
  }, method="POST")

  try:
    with urllib.request.urlopen(request) as response:
      response_body = response.read().decode('utf-8')
      # Parse the JSON response
      parsed_response = json.loads(response_body)
  except Exception as e:
    # Some error occured, let the caller/LC know.
    return {
      "error": str(e),
    }

  # Return the data to the caller/LC.
  return {
    "data": parsed_response,
  }

Execution environment

Playbooks contents are cached for short periods of time ( on the order of 10 seconds ) in the cloud.

Playbooks are instanciated on demand and the instance is reused for an undefined amount of time.

Playbook code only executes during the main call to the playbook function, background on-going running is not supported.

The execution environment is provisioned on a per-Organization basis, meaning all your playbooks may execute within the same container, but NEVER on a container used by another Organization.

Although you have access to the local environment, this environment is ephemeral and can be wiped at any moment in between executions so you should take care that your playbook is self contained and doesn’t assume pre-existing conditions.

A single execution of a playbook is limited to 10 minutes.

The current execution environment is based on the default libraries provided by the python:slim Dockerhub official container.

Custom packages and execution environment tweaks are not available in self-serve mode, but they may be available on demand, get in touch with us at support@limacharlie.io.

Infrastructure as Code

Example:

hives:
    playbook:     
        my-playbook:
            data:
                python: |-
                    def playbook(sdk, data):
                        if not sdk:
                            return {"error": "LC API key required to list sensors"}
                        return {
                            "data": {
                                "sensors": [s.getInfo() for s in sdk.sensors()]
                            }
                        }
            usr_mtd:
                enabled: true
                expiry: 0
                tags: []
                comment: ""

Billing

Playbooks are billed per seconds of total execution time.


Was this article helpful?