Encode your response playbooks once and let the platform run them on every matching event, in seconds, with no code, no external scheduler, and a complete audit record of what ran.
A runbook is a named automation rule built from one or more trigger rules and an ordered list of actions. When any trigger rule matches an incoming platform event, the action list runs in sequence. A finding is created, a scan finishes, an SLA is breached, or a cron timer fires, and within seconds the runbook acts.
When a single authenticated scan can return tens of thousands of findings, no team can hand-route each critical to an owner, open a ticket, set an SLA, and alert the right channel fast enough, and the work erodes when an analyst is off shift. The ad hoc scripts that paper over the gap tend to run with no audit trail, no failure handling, and no tenant isolation.

The hard part at enterprise scale is not running an action. It is running thousands of them safely, so a misconfigured webhook never hammers a downstream system forever and a noisy rule never stampedes.
At a glance
- Backend domain: internal/runbook (Go modular monolith, base path /api/v1/runbooks)
- Trigger events: 16 event types, including the synthetic schedule (cron) trigger
- Action catalog: 22 types across notification, finding, ITSM, scan, report, asset, and flow control
- Execution engines: inline (default), workflow (durable go-workflows), shadow (side by side)
- Resilience: Circuit breaker at 10 consecutive failures; throttle and concurrency gate
- Event backbone: internal/events 34-type catalog, 14 producers, 4 consumers, in-process pub/sub
- Multi-tenancy: company_id nil is global (platform admin only); authz.InScope on every path
How it works
Encode the response once as a runbook, then let the platform execute it on every matching event, in seconds, with a complete and auditable record of what ran and what it did.
A runbook is authored through a four-step wizard and inspected on a visual canvas, so a security engineer builds automation without writing code. A runbook fires when any of its trigger rules matches, and within a rule the event type must match and an optional condition tree must evaluate true.
Most runbooks run inline, with actions executing synchronously in the same goroutine as the event or HTTP handler. Some playbooks need to wait for a multi-day approval or a delay that must survive a worker restart, so PMAP integrates an optional durable workflow engine, selected by PMAP_RUNBOOK_ENGINE.
Key capabilities
- A 22-action catalog. Actions span seven concerns: notification (webhook, email, Slack, Teams, HTTP), finding mutation (status, severity, tags, SLA, assign, comment), ITSM ticketing, follow-up scans, report generation, asset and integration sync, and flow control such as sleep, await_signal, when, and resolve_owner.
- Templating and branching. Every config supports placeholders of the form {{ field }}, resolved against the enriched payload before the action runs. A when expression skips an action rather than failing it, the when action type selects a then or else sub-list, and resolve_owner writes owner fields back for a later assign or ticket.
- Cron scheduling, built in. A runbook whose trigger is schedule carries a cron expression and fires on a timer. A background Scheduler owns a robfig/cron instance and reloads active schedule triggers every 60 seconds, so a new or edited cron runbook can take up to 60 seconds to become active.
- Fresh-install safety. An action whose dependency is unconfigured, such as SMTP or a placeholder URL, is recorded as a structured skip rather than a failure. A fresh install therefore neither spams the audit log nor trips the breaker, because a pre-flight skip is not a health signal.
Use cases
- Auto-ticket a critical finding. A CISO mandates that every critical finding gets an owner and a ticket within minutes. A runbook on finding_created with finding.severity eq critical resolves the asset owner team, assigns the finding, and creates a Jira ticket routed to that team, with the reference linked back onto the finding.
- Alert on SLA breach. A SOC lead wants real-time pressure on aging risk. A runbook on sla_breached posts a Slack message to the owning team channel and adds an escalation comment. Template variables name the specific finding and severity, and the runbook is throttled so a wave of breaches does not flood the channel.
- Govern a multi-day approval gate. A vulnerability manager runs a playbook that pauses on await_signal for up to 72 hours awaiting a human decision on a high-impact change. With PMAP_RUNBOOK_ENGINE set to workflow, that wait is a PostgreSQL-persisted signal channel, so the workflow resumes from the same state after a restart.
Encode the response once, run it on every event, with a complete audit record.


