AI Agent Engine

Hello, we’re just soft-launching a new extension (ext-ai-agent-engine) as part of the LimaCharlie Labs effort.

I wanted to share a bit more about it.

This extension provides an engine so anyone on the platform can quickly and easily codify an AI Agent through prompts directly on LimaCharlie. These agents optionally have access to all parts of the LC capabilities.

The documentation is here: AI Agent Engine
This new capability is a bit outside of our typical new features, so please do give us feedback, ask questions if things aren’t clear.

To get ideas flowing, here’s a quick Proof of Concept I threw together that leverages both Playbooks and AI Agents:

Create Agent

Make sure you have the ai_agent.* permissions.
Head over to Automation → AI Agents.
Create a new ai-summarizer agent:

{
  "additional_instructions": "",
  "credentials": "",
  "initial_message": {
    "msg": ""
  },
  "instructions": "You are a cybersecurity expert system who's job it is to summarize detections/alerts for SOC analysts. Output as markdown. Include detailed technical context about the alert and if MITRE techniques are mentioned, summarize them. Also include what next steps of the investigation should be. The audience of the report is a cyber security team at a medium sized enterprise.",
  "max_iterations": 10,
  "mode": "one_shot_answer",
  "model": "gemini-2.0-flash",
  "trace": true
}

Create Playbook

Make sure you have the playbook.* permissions.
Head over to Automation → Playbook.
Create a new notify-customer playbook:

import markdown
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
from weasyprint import HTML, CSS
from jinja2 import Template
from datetime import datetime
import os
import limacharlie
import json
import traceback
def generate_and_send_report(alert_markdown, smtp_server, smtp_port, sender_email, sender_password, recipient_email):
    # Convert markdown to HTML
    html_content = markdown.markdown(alert_markdown)
    
    # Create a professional template with CSS styling
    template_str = """
    <!DOCTYPE html>
    <html>
    <head>
        <style>
            body {
                font-family: Arial, sans-serif;
                line-height: 1.6;
                margin: 40px;
            }
            .header {
                text-align: center;
                margin-bottom: 30px;
            }
            .logo {
                font-size: 24px;
                font-weight: bold;
                color: #2c3e50;
                margin-bottom: 10px;
            }
            .report-title {
                font-size: 20px;
                color: #34495e;
                margin-bottom: 20px;
            }
            .timestamp {
                color: #7f8c8d;
                margin-bottom: 30px;
            }
            .content {
                background-color: #f9f9f9;
                padding: 20px;
                border-radius: 5px;
            }
            .footer {
                margin-top: 30px;
                text-align: center;
                color: #7f8c8d;
                font-size: 12px;
            }
        </style>
    </head>
    <body>
        <div class="header">
            <div class="logo">My MSSP</div>
            <div class="report-title">Security Alert Report</div>
            <div class="timestamp">Generated on: {{ timestamp }}</div>
        </div>
        <div class="content">
            {{ content }}
        </div>
        <div class="footer">
            Confidential Security Report - My MSSP © {{ year }}
        </div>
    </body>
    </html>
    """

    # Prepare the template data
    template = Template(template_str)
    current_time = datetime.now()
    html_report = template.render(
        content=html_content,
        timestamp=current_time.strftime("%Y-%m-%d %H:%M:%S"),
        year=current_time.year
    )

    # Generate PDF
    output_file = "security_report.pdf"
    HTML(string=html_report).write_pdf(
        output_file,
        stylesheets=[CSS(string='@page { size: letter; margin: 1cm }')]
    )

    # Create email message
    msg = MIMEMultipart()
    msg['From'] = sender_email
    msg['To'] = recipient_email
    msg['Subject'] = f"Security Alert Report - {current_time.strftime('%Y-%m-%d')}"

    # Add email body
    email_body = "Please find attached the security alert report."
    msg.attach(MIMEText(email_body, 'plain'))

    # Attach PDF
    with open(output_file, 'rb') as f:
        pdf_attachment = MIMEApplication(f.read(), _subtype='pdf')
        pdf_attachment.add_header(
            'Content-Disposition', 'attachment', filename=output_file
        )
        msg.attach(pdf_attachment)

    # Send email
    try:
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.starttls()
        server.login(sender_email, sender_password)
        server.send_message(msg)
        server.quit()
        print("Report generated and sent successfully!")
        
        # Clean up the PDF file
        os.remove(output_file)
        
    except Exception as e:
        print(f"Error sending email: {str(e)}")

def playbook(sdk, data):
    # Get the SMTP server and port from secrets
    hive = limacharlie.Hive(sdk, "secret")
    smtp_info = hive.get("smtp_server")
    smtp_info = json.loads(smtp_info.data["secret"])
    smtp_server = smtp_info["server"]
    smtp_port = smtp_info["port"]
    sender_email = smtp_info["sender_email"]
    sender_password = smtp_info["sender_password"]

    # Get the recipient email from the hive
    recipient_email = hive.get("customer_soc_email")
    recipient_email = recipient_email.data["secret"]
    
    # Generate a summary using the ai-summarizer AI agent from
    # the ext-ai-agent-engine extension
    summary = sdk.extensionRequest("ext-ai-agent-engine", "start_session", {
        "agent_definition": "ai-summarizer",
        "initial_message": {
            "msg": "Summarize the following alert:",
            "data": {
                "alert": data
            }
        }
    })
    try:
        for interaction in summary["data"]["interactions"]:
            if 'ai_interaction' in interaction:
                summary = interaction["ai_interaction"]["msg"]
                break
    except Exception as e:
        return {"error": f"Error getting summary: {traceback.format_exc()} : {summary}"}
    
    # Send the summary to the customer
    generate_and_send_report(summary, smtp_server, smtp_port, sender_email, sender_password, recipient_email)

If you wonder how I got to this playbook, I used ChatGPT and asked for Python code that takes a Markdown report on a security alert, generates a branded PDF and emails it to the customer.

Create Secrets

The above playbook requires a few Secrets. I could have hard coded them, but making them Secrets makes it easy to modify using infrastructure-as-code to scale this to 100s of customers (for a service provider).
So head to Organization Settings → Secrets Manager and create:

smtp_server:

{
  "server": "smtp.gmail.com",
  "port": 587,
  "sender_email": "my-email-sender@gmail.com",
  "sender_password": "aaaa aaaa aaaa aaaa"
}

customer_soc_email:

my-customer@acme.com

notify-customer-creds

Create an API key for the org with the permissions:

  • secret.get // So we can get our secrets.
  • ext.request // So we can query the AI.
    Take the resulting API key and copy it into a notify-customer-creds secret.

Test

Make sure you have subscribed to the ext-ai-agent-engine and ext-playbook extension.
Head over to your Detections section, pick a Detection you’d like to test with.
Then go over to Extensions → Playbook.

Under name enter notify-customer.
Under credentials select Secrets Manager toggle, then select notify-customer-creds.
Under data: paste the detection you chose (in JSON format).

Click Run Playbook.

Summary

This combo Playbook+AI will:

  1. The playbook receives a Detection to summarize.
  2. It queries the AI to summarize it.
  3. It takes the Markdown summary and converts it into a PDF.
  4. It emails the PDF to the customer.

To fully automate, you could create an extension request like:

- action: extension request
  extension name: ext-playbook
  extension action: run_playbook
  extension request:
    name: '{{ "notify-customer" }}'
    credentials: '{{ "hive://secret/notify-customer-creds" }}'
    data: detect

as a D&R rule Response from a detection.

Pricing for this is currently $1.00 per 1,000,000 tokens.

1 Like