Message Groups & Cases¶
Generally available
Email Security is generally available. Subscribe to the Email Security extension in your organization to purchase and enable it. Paid usage costs \(1 per protected mailbox per month**, billed daily at **\)1/30 per mailbox-day. Free-tier organizations receive a limited 14-day trial. See security product billing for pricing, trial limits and upgrading.
CLI examples require LimaCharlie CLI 5.7.0 or later, which includes the
mailsec commands. Install or upgrade, then check:
Credential-file examples also require jq.
A message group represents one email delivered to several recipients, including per-recipient personalization. Open Email Security → Messages and choose Groups in the Messages | Groups switch to triage the copies together. Groups is the default when no view has been chosen for the organization. A campaign relates similar messages and may contain several groups. Group membership is stricter than campaign similarity.
Identity and the queue¶
The organization-scoped group_id combines the normalized Message-ID, sender
SMTP address, normalized subject, From/sender display names, the sets of
registrable Reply-To and link domains, and the SHA-256 digests of attachments.
For links to IP addresses or hosts with no registrable parent, the normalized
host value participates instead. Relative paths without a host contribute no
link domain. Different IP destinations stay separate; equivalent IPv6 spellings
and host capitalization do not split copies.
Inline raster images displayed in the body are excluded; inline PDFs, SVGs and
other files remain attachments for identity purposes.
Copies can share a group despite personalized greetings or footers, tracking and unsubscribe URL paths, queries or fragments, Reply-To local-part tokens, different HTML presentation and recipient-specific delivery headers. A copy reusing the same Message-ID, sender and subject with a different link-domain or attachment set stays separate. Group membership does not establish that every copy has the same body, engine verdict or disposition; inspect instances and the remediation preview before acting.
Missing or invalid Message-ID or sender, or incomplete identity inputs, produce an individual message identity. Unrelated parser warnings do not split copies when all identity inputs are complete. The current identity version applies only to newly ingested messages. Existing stored group IDs remain unchanged, so older and newer groups can coexist for the same send; no historical regrouping occurs.
The default queue shows groups needing triage: malicious or suspicious copies, medium-or-higher rule severity, or user-reported mail. An analyst benign revision removes that copy's severity-only triage contribution while preserving its historical severity. Dispositions benign, graymail and simulation dismiss that copy's triage contribution; malicious and spam flag it. The historical user-report indicator stays visible. Other undismissed copies keep the group in the queue. Include unflagged groups includes the remaining groups.
Groups contain retained recipient copies from the past 35 days, consistent with the group drawer and remediation preview.
The shared Messages filters apply in both views, including mailbox, sender, free text, placement, direction, lane, score and IOC pivots. Switching views keeps the filters and their badges. Unsupported combinations show an error instead of silently removing a filter. When a filtered page comes back empty while more results remain, the queue shows Still searching and keeps loading, and after twenty empty pages in a row offers Keep searching rather than claiming that nothing matched.
Each row describes the whole group: subject and sender, representative message, worst verdict and severity, recipient and copy counts, disposition summary, and first and last seen. When the response includes a matching-copy count, the row also shows N of M copies match. Its absence does not mean that every copy matched.
Both views apply the same filters on the server: literal text search,
mailbox, sender address or root domain, campaign, link domain, attachment SHA-256,
placement state, direction, minimum score, lane, verdict, severity, disposition
(including none), user-reported state and time. Omitted user-reported state leaves
that dimension unrestricted. Alternatives within one filter use OR; different
filters use AND on one recipient copy. For example, mailbox A plus malicious
returns a group only if A's copy is malicious, even when another copy is malicious.
The default flagged-group gate remains separate: Include unflagged groups removes it.
exclude_state is the one exception to the one-copy rule. On its own (for example
exclude_state=spam to hide mail the provider filed as junk) it hides a group only
when every copy is in an excluded state, judged from the group summary, and a group
with a copy elsewhere stays with its whole-group counts. The summary refreshes within
seconds to minutes of a change, so a copy that has just moved out of the excluded
state can keep its group hidden until then. Combined with any other copy filter,
exclude_state becomes one more condition on the matching copy.
Filtered ordering uses the newest matching copy's time. Summary badges and counts still describe the whole group, so a matching copy's verdict or disposition can differ from the aggregate. The group drawer and remediation preview include all copies, including recipients outside the list filters.
The list uses bounded index reads and opaque cursors. A filtered cursor pins a
snapshot for 50 minutes; restart pagination after it expires or after changing
filters. Short or empty pages can still carry a next_cursor: continue until it
is empty. If a canonical matching-copy lookup exceeds its bound, the explicit
group_filter_too_broad error asks for narrower filters. Search and lane have the
same supported combinations as message lists; unsupported combinations are
refused, never ignored. Exact matched_copies counts are omitted because counting
large fan-outs per row would exceed the predictable page cost.
The drawer shows first and last seen, message and recipient counts, maximum
verdict and severity, placement and disposition counts, a representative message
and campaign association when unambiguous. Queue summaries show their as_of
time; the drawer reads a consistent current snapshot. A missing severity remains
unknown. Instances are paged: continue until there is no next cursor rather than
assuming the first page contains every recipient.
Preview, confirm and track¶
Select groups in the queue to prepare remediation or disposition previews. The console accepts up to 50 groups per batch; each group has its own durable job and can contain more than 20,000 copies. Review the prepared jobs before confirming the batch. Preparation failures can be retried without recreating the successful previews. A failed or uncertain confirmation requires reviewing the job status; the console does not confirm automatically.
Group actions cover all copies
A mailbox, sender or other queue filter narrows which groups appear. Group remediation and disposition still cover every copy of each selected group at the preview snapshot, including copies that did not match the filter. Inspect the preview before confirming.
Group remediation prepares a durable snapshot of every member, including all-hands messages with more than 20,000 recipients. Preparation may need several passes. The preview shows its snapshot time, selected count, action and frozen parameters. No confirmation is available until preparation finishes. Newly arriving copies after the snapshot require a separate preview.
Confirm the complete preview to start execution. Confirmation is bound to the organization, authenticated actor, group, action, parameters and manifest. A ready preview expires 45 minutes after its snapshot; prepare a new preview rather than confirming stale information. Confirming again after execution starts resumes the same job and does not create another intent.
Execution processes bounded chunks and survives worker restarts. Track the job until it reaches a terminal phase, and inspect succeeded, skipped, withheld and failed counts. Withheld is not successful remediation. The normal enforcement, exclusion and mailbox protection rules still apply; an explicit force request requires the same deliberate consent as individual remediation. Retention can remove a selected copy before execution, and provider failures can leave a partial outcome. Review those outcomes before retrying.
Microsoft may accept quarantine or restore before completing it. The group job stays running while that provider result is pending; acceptance does not increase its succeeded or failed counts. Continue polling the same job instead of creating another intent. Each recipient has up to 90 minutes from its first recorded pending result to reach a terminal provider outcome. An unconfirmed result after that window counts as failed, even if Microsoft later completes the action. Inspect the provider state before retrying such a member.
The console can resume a job from its URL. Paused browser polling does not cancel the durable server job; refresh its status. See Bulk Remediation for individual and campaign scopes.
Group disposition uses the same preview and confirmation flow, requiring both
mailsec.act and mailsec.set. Choose malicious, spam, graymail, benign or
simulation, or clear the existing disposition, with an optional note of at most
1,024 characters. Confirmation uses the frozen value and note and checks current
permission. It records the decision through the ordinary disposition path,
including history and disposition events, without changing engine verdicts or
running remediation automations. Newly delivered copies keep their own disposition.
From the command line¶
limacharlie mailsec group list --severity high --severity critical --disposition none
limacharlie mailsec group list --all --since 2026-09-01T00:00:00Z
limacharlie mailsec group get <GROUP_ID>
limacharlie mailsec message list --group-id <GROUP_ID>
limacharlie mailsec group preview <GROUP_ID> --action quarantine_message --reason "Incident review"
limacharlie mailsec group preview <GROUP_ID> --action set_disposition --disposition benign --note "Reviewed"
limacharlie mailsec group status <JOB_ID>
limacharlie mailsec group confirm <JOB_ID> --confirmation <TOKEN>
Preview and confirm wait for the job by default; --no-wait returns it at once.
Reuse the printed --preview-id when retrying the same preview. A failed or
withheld recipient outcome exits non-zero. See Command Line Interface.
Routes¶
All routes are under /v1/mailsec/{oid}. See API Reference
for the shared conventions.
| Route | Does |
|---|---|
GET /groups |
The flagged triage queue, ordered by the newest matching copy. Accepts the same filters as Messages: q, mailbox, sender_email, sender_root_domain, campaign_id, group_id, link_domain, attachment_sha256, state, exclude_state, direction, min_score, lane, verdict, severity, disposition (including none), user_reported, since/until (matching-copy time, RFC 3339 or Unix seconds), plus all=true, cursor, limit. Repeated values OR within a filter; every active filter must match one copy. The cursor is bound to the filters and tenant. Follow short or empty pages while a cursor remains. Requires mailsec.get |
GET /groups/{group_id} |
One consistent aggregate of every indexed copy: first/last seen, counts, maximum verdict and severity, placement and disposition summaries, representative message and campaign. Requires mailsec.get |
GET /messages?group_id={group_id} |
The group's recipient copies, paged like any message list |
POST /groups/{group_id}/actions/preview |
Prepare a durable snapshot of every copy. Body: preview_id (caller UUID, reused on retry), action (a remediation action or set_disposition), optional reason, text, force; for set_disposition, disposition or clear: true, and optional note. Requires mailsec.act, plus mailsec.set for set_disposition |
GET /group-actions/{job_id} |
Preparation or execution progress: phase, snapshot time, counts of succeeded, skipped, withheld and failed. The confirmation token appears only once the manifest is complete. Requires mailsec.get |
POST /group-actions/{job_id}/confirm |
Execute the complete preview with {"confirmation": ...}, from the same authenticated actor that prepared it. Repeating it resumes the same job. Requires mailsec.act |
Opt-in Cases detection pack¶
In Email Security → Protection setup, install the Cases pack after enabling
Cases. The pack creates ordinary dr-general rules with your credentials. It
only reports detections; it does not change verdicts, dispositions or placement.
Installation needs permission to call the extension and read/write detection
rules. Removal also needs detection-rule delete permission.
The pack reports:
EMAIL_ANALYSIS_COMPLETEwhen the final verdict is malicious or suspicious, severity is at least medium, or the message was user-reported.EMAIL_USER_REPORTfrom a human reporter. Automated senders are excluded.
Copies classified benign, graymail or simulation are excluded from both triggers. Closing a Case alone does not dismiss its messages. Set the group disposition when dismissing a retained Case; future unclassified copies can still report and reopen it.
| Severity | Detection priority |
|---|---|
| informational | 1 |
| low | 1 |
| medium | 3 |
| high | 6 |
| critical | 9 |
| unknown or missing | 1, with unknown severity retained |
Global suppression limits duplicates for the same group and severity across mailbox sensors and both triggers for 30 days. A higher severity can report again and raise the priority of the same retained case. Explicit case identity keeps late detections together independently of ordinary time-based grouping and reopens a closed case when necessary. A manually merged case follows its retained merge target.
Deduplication lasts while that identity's case remains retained. Deliberate case deletion, retention expiry, or a missing, cyclic or excessively long merge mapping allows a fresh case; retired mappings carry an audit reason. A missing group uses the immutable message identity rather than an empty organization-wide key.
Installation and repair show an outcome for each record. Repair adds missing records without overwriting existing rules. Updates preserve disabled state, customer tags and comments, and use conditional writes. A customer-owned record at a reserved pack key is refused. Unavailable metadata stays unknown instead of being treated as an absent rule. Removal targets only pack-owned records in the pack's namespace.