Events & Automation¶
Private beta
Email Security is in private beta. It is not generally available, and
access is enabled per organization — if the ext-email-security extension
is not in your catalog, this product is not turned on for you yet.
While it is in beta, expect the surface described here to move: commands, fields and event shapes may change between releases, and they may change in ways that are not backwards compatible. Pin a CLI version if you script against it, and re-read this page after upgrading.
Talk to us before relying on it in production.
Email Security is not a side-car product with its own event bus. Everything it sees becomes ordinary LimaCharlie telemetry, in the same lake as your endpoint, cloud and identity data — which is what makes "a phish was delivered, and then that user's endpoint ran a new binary" one rule instead of two products and a spreadsheet.
The sensor¶
Each mail connection appears as one cloud sensor on platform email. The
mailbox is a field on the event, not an identity: a ten-thousand-mailbox tenant
is one sensor, not ten thousand.
The events¶
| Event | Emitted when |
|---|---|
EMAIL_MESSAGE |
Once per message, at ingest. Carries the whole parsed model — headers, sender, recipients, body, links, attachments, authentication, hops — plus the enrichments and the verdict. It is the record that this mail arrived |
EMAIL_ACTION |
On every remediation outcome, including failures and skips. Who asked, what was attempted, what happened |
EMAIL_USER_REPORT |
When a message reaches the abuse mailbox and becomes a report |
EMAIL_INGEST_ERROR |
When a message could not be fetched or processed. Coverage honesty: failures are visible, never silent |
EMAIL_MESSAGE is emitted once and is immutable.
Everything the rule needs is in the event
The verdict, the top signals and the enrichments the pipeline resolved are
all in EMAIL_MESSAGE. A rule never has to call back for enrichment, and a
replay of the event sees exactly what the pipeline saw.
Events arrive on the default D&R target, so a rule matching them needs no
target: line.
Acting on mail from a D&R rule¶
# Detect
op: and
rules:
- op: is
path: routing/event_type
value: EMAIL_MESSAGE
- op: is
path: event/verdict/verdict
value: malicious
- op: is
path: event/direction
value: inbound
# Respond
- action: report
name: email-malicious-delivered
- action: extension request
extension name: ext-email-security
extension action: quarantine_message
extension request:
msg_uuid: '{{ .event.msg_uuid }}'
The typed actions available to extension request are the same six the console
and the CLI use: quarantine_message, trash_message, move_to_spam,
restore_message, banner_message, unbanner_message. They route to the same
executor, so the organization's alert_only / enforce mode, the audit row and
idempotency all apply unchanged — there is exactly one remediation path in this
product.
Actions dispatched this way are attributed with source: dr in the audit trail.
Which seat should this rule sit in?
A rule that should change the verdict belongs in dr-mail as a
pre_verdict signal — see Custom Rules. A rule that
should do something once the verdict exists can sit in either seat: in
dr-mail as post_verdict if it only needs mail actions, or here as an
ordinary D&R rule if it needs the platform's full response arsenal, Outputs,
Cases, or correlation with non-mail telemetry.
Reacting to a user report¶
From there the detection flows into Cases, Outputs and everything else that consumes detections. A report is the highest-signal thing your users will ever hand you, so treating it as a first-class detection is usually right.
Watching your own coverage¶
EMAIL_INGEST_ERROR is the event to alert on. A mail security product that
quietly stops seeing a mailbox is worse than one that is visibly down, so
failures are emitted rather than swallowed:
Pair it with the coverage call, which reports mailboxes in error, the
parse-degradation rate and the emission backlog. See
Getting Started.
Querying mail with LCQL¶
EMAIL_* events are queryable like any other telemetry in the Query Console and
through limacharlie search, over the platform's normal retention rather than
the 35-day product index. That makes it the right tool for questions that reach
further back than the queue does.
Use limacharlie ai generate-query to build the query and
limacharlie search validate before running it — LCQL is validated against
org-specific schemas and hand-written queries fail or mislead. See
Data & Queries.
For the everyday "who else got this" question, the message index pivots are faster and are purpose-built.
Outputs¶
Because the events are ordinary telemetry, every
Output works without any mail-specific
configuration: stream EMAIL_MESSAGE to a data lake, forward detections to a
SIEM, or push EMAIL_ACTION into an audit pipeline.
Configuration as code¶
Every piece of Email Security configuration is a Hive record, so a tenant's whole mail posture is a directory of YAML:
| Hive | Holds |
|---|---|
secret |
The provider credential |
mailsec_provider |
The connection |
mailsec_policy |
Automations, exclusions, VIPs, thresholds, banners, retention, reporter replies |
dr-mail |
Custom mail rules |
lookup |
VIP lists referenced by vips.list_refs |
dr-general |
The D&R rules on EMAIL_* events |
limacharlie hive set --hive-name mailsec_policy --key 50-finance-vips \
--input-file policy/50-finance-vips.yaml --enabled --oid $OID
limacharlie hive list --hive-name mailsec_policy --oid $OID --output yaml
limacharlie hive get --hive-name mailsec_policy --key 50-finance-vips --oid $OID
Two conventions make this pleasant to keep in git:
- Records compose in name order, so number your records (
00-baseline,50-team-x,99-override) when precedence matters. - Unknown fields are refused, so a typo fails the write rather than silently
disabling a control. Validate a rule with
limacharlie hive validateorlimacharlie mailsec rule validatebefore committing it.
Onboarding a new tenant is then: subscribe the extension, write the secret, write the provider record, apply the policy directory, run the connection test.