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 anotify-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:
- The playbook receives a Detection to summarize.
- It queries the AI to summarize it.
- It takes the Markdown summary and converts it into a PDF.
- 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.