Skip to content

feat: anti-triggers and governance docs for email security vendor plugins - #165

Merged
asachs01 merged 2 commits into
mainfrom
feat/quality-email-security-vendors
Aug 4, 2026
Merged

feat: anti-triggers and governance docs for email security vendor plugins#165
asachs01 merged 2 commits into
mainfrom
feat/quality-email-security-vendors

Conversation

@asachs01

@asachs01 asachs01 commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Applies the repo-wide connector-quality standard to the four near-substitute email security vendor plugins. Branched from feat/skill-anti-triggers-governance, which carries the standard.

Scope note: the separate email-security plugin directory (knowbe4 / proofpoint / checkpoint-avanan) is owned by a parallel agent and is not touched here. This PR only references its skills by name.

What each of these four uniquely owns

The whole value of this batch is cross-vendor disambiguation. These plugins are near-substitutes — "quarantine", "phishing", "release message", "threat", and "policy" match all of them equally, plus the email-security bundle and the cipp / m365 tenant plugins. So each anti-trigger section leads with the boundary:

Plugin Uniquely owns
abnormal Post-delivery behavioural detection via the M365 API — the only one that reaches into an inbox that already received the mail, and the only one modelling how a sender normally behaves (BEC, supply-chain, ATO).
ironscales The user-report loop — its own Outlook/Gmail add-in turning employee reports into incidents, with a classify-then-remediate lifecycle and federated learning across tenants.
mimecast The delivery pipeline — the only one that can answer "where is this email right now": hold queue, deferred/retrying states, SMTP errors, delivery route, and TTP click-time verdicts.
spamtitan Pre-delivery gateway filtering — the spam-score quarantine in front of the tenant, and the sender allow/blocklists that override the scoring engine.

Task A — ## Anti-triggers

11 added / 4 skipped.

Plugin Added Skipped
abnormal 5 — threats, cases, messages, account-takeover, vendors 1 — api-patterns
ironscales 1 — incidents 1 — api-patterns
mimecast 3 — message-tracking, queue-management, threat-intelligence 1 — api-patterns
spamtitan 2 — quarantine, lists 1 — api-patterns

Why the four api-patterns skills were skipped: any bullet there would only negate when_to_use ("don't use for non-Mimecast questions"), which the checklist calls filler. This also matches the exemplar — Huntress has 7 skills and only 3 carry the section; api-patterns, billing, escalations, and organizations were all deliberately left alone.

Every bullet names the skill to load instead, using each skill's frontmatter name (the Huntress convention).

Judgement calls

  • Anti-triggers go on the skill that gets wrongly loaded, not symmetrically. abnormal-messages gets one pointing at Mimecast Message Tracking because "trace this email / check these headers" pulls it wrongly; Mimecast doesn't get the mirror bullet, because nobody reaches for a delivery-pipeline skill when they want Abnormal.
  • The caseId collision is real and gets bullets on both sides. Abnormal Security Cases and Abnormal Security Account Takeover both call their identifier caseId and both are reached by the word "case". That is a genuine two-way mistake, so both carry it.
  • M365-tenant overlap is routed out explicitly. Abnormal's ATO skill documents FORCE_PASSWORD_RESET / REVOKE_SESSIONS / REMOVE_RULES as remediation actions, but no tool in the shipped MCP server performs them — those are cipp-users and Microsoft 365 Mailboxes. Same for Ironscales: remediation removes mail and blocks senders, it cannot reset a harvested credential.
  • abnormal-vendors got a section for a vocabulary reason, not a sibling one. In MSP-land "vendor risk" overwhelmingly means a distributor. VendorBase means the opposite — an external party that emails your customer. That bullet routes to Pax8 Products, mirroring the exemplar's "agent means a sensor, not a Claude subagent".
  • Cross-gateway quarantine gets a bullet in three places (spamtitan-quarantine, mimecast-message-tracking, abnormal-threats) because it is the single highest-traffic routing error in this batch, and the message IDs do not federate between vendors.

Task B — GOVERNANCE.md

One per plugin, from _templates/governance-template.md, with Conduit-gateway framing kept intact (centralised auth, no local secrets, per-operator audit identity).

Tool names were derived from each plugin's own skills/*/SKILL.md and then cross-checked against the shipped MCP servers (abnormal-mcp, ironscales-mcp, mimecast-mcp, spamtitan-mcp). No tool name is invented.

Tiers by blast radius, not HTTP verb

Plugin Read Write Destructive
abnormal 9 empty abnormal_remediation_manage
ironscales 7 empty ironscales_remediation_act, ironscales_allowlist_manage
mimecast 8 mimecast_hold_message mimecast_release_message
spamtitan 5 empty spamtitan_release_message, spamtitan_delete_message, spamtitan_manage_allowlist, spamtitan_manage_blocklist

Three of the four have an empty Write tier, and that is stated plainly rather than padded. These are mail-flow products: there is no reversible bookkeeping middle ground between reading a queue and moving a customer's mail.

The sharp edges the brief called out are all reflected: release delivers possible malware and cannot be recalled (mimecast_release_message, spamtitan_release_message); purge destroys the only copy of the evidence (spamtitan_delete_message); a filter-policy change silently drops legitimate mail with no bounce and no alert (spamtitan_manage_blocklist). Each carries a written justification in the style of the exemplar's incidents_bulk_approve note.

Disputable destructive-tier calls

Flagged in the docs themselves so a reviewer can argue them:

  1. spamtitan_manage_allowlist → destructive. The server does not annotate it destructiveHint (unlike its blocklist sibling). But allowlisting bypasses spam scoring entirely, and spoofed mail claiming to be the allowlisted sender inherits the exemption. It is a durable hole in the customer's filtering with no visible symptom until it is used. Most likely to be argued down to Write.
  2. ironscales_allowlist_manage → destructive, same reasoning: a permanent, company-wide, silent exemption from phishing detection.
  3. abnormal_remediation_manage → destructive as a whole tool. Its action enum straddles read (status), destructive-removal (remediate), and destructive-delivery (unremediate). The gateway tiers by tool name, not by argument, so the tool takes the highest tier its arguments can reach. Same pattern noted for SpamTitan's manage_* tools, whose list action is read-only but lives inside a destructive-tier tool.
  4. mimecast_hold_message → Write, not destructive. Deliberate asymmetry with release: hold is undone by release, reaches one message, and its cost is a delayed email. Release is one-way.

Data handling

Every tool returning message bodies, headers, or recipient PII is flagged. Two are worth a reviewer's attention:

  • mimecast_get_ttp_logs returns every URL a named user clicked. That is a browsing-history-shaped dataset about identified employees and may attract employee-monitoring obligations independent of its security purpose.
  • ironscales_email_classify is the inverse flow — the operator supplies raw headers, bodies, and URLs outbound to Ironscales. It changes no state so it is tiered Read, but it exports customer email content.

For abnormal and spamtitan the honest summary is recorded as-is: there is no PII-free read tier.

Drift found along the way (documented, not fixed)

Cross-checking against the shipped servers surfaced skill-vs-server tool-name drift. Fixing it is out of scope for an additive PR, so each GOVERNANCE.md records the real names under Known sharp edges — an operator tiering tools at the gateway needs names that exist:

  • abnormal — skills reference abnormal_ato_*, abnormal_vendors_*, abnormal_threats_remediate, abnormal_cases_action, abnormal_messages_headers. The server exposes 10 tools; none of those are among them.
  • ironscales — skills say ironscales_list_incidents / ironscales_classify_email; server exposes ironscales_incidents_list / ironscales_email_classify.
  • mimecast — skills say mimecast_get_queue; server exposes mimecast_get_queue_status.
  • spamtitan — skills say spamtitan_list_allowlist / spamtitan_list_blocklist / spamtitan_get_domain_stats; the server covers those via the list action and a domain argument instead.
  • spamtitan multi-tenancyspamtitan_get_queue has no domain parameter in the shipped server, though the skill documents one. In a multi-tenant appliance the quarantine listing is not scoped by customer, and the release/delete that follows is scoped only by the API key. Called out prominently; probably worth its own issue.

Constraints observed

Verification

  • node scripts/check-marketplace-drift.mjs✔ marketplace drift check passed (76 entries)
  • claude plugin validate✔ Validation passed for all four plugins

@asachs01

asachs01 commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

Base-branch note: this branch was cut from feat/skill-anti-triggers-governance (which carries the standard), so the diff against main also shows that branch's 7 files — _standards/, _templates/, and the Huntress exemplar. None of those were touched here.

This PR's own commit is 52b324c, +614 / −0 across 15 files, all inside msp-claude-plugins/{abnormal,ironscales,mimecast,spamtitan}/. Review that commit alone, or merge the parent branch first and the diff resolves itself.

Applies the repo-wide connector-quality standard to the four
near-substitute email security vendor plugins: abnormal, ironscales,
mimecast, spamtitan.

Anti-triggers (11 of 15 skills; all four api-patterns skills skipped
as boilerplate-only per the checklist). These four vendors share almost
all their vocabulary — "quarantine", "phishing", "release", "threat",
"policy" match every one of them equally, plus the email-security
bundle and the cipp/m365 tenant plugins. Each section states what the
vendor uniquely owns and routes the neighbouring case elsewhere.

GOVERNANCE.md per plugin, from _templates/governance-template.md. Tool
names derived from each plugin's skills and cross-checked against the
shipped MCP servers in /Users/asachs/mcp/<vendor>-mcp/src. Tiers follow
blast radius, not HTTP verb: releasing a held message delivers possible
malware to an inbox, purging mail destroys evidence, and a filter-list
change silently drops a customer's legitimate mail — all destructive
tier regardless of the verb.

Additive only. No triggers: frontmatter (#158). No generated files.
@asachs01
asachs01 force-pushed the feat/quality-email-security-vendors branch from 52b324c to 5d87cbb Compare August 4, 2026 18:47
@asachs01
asachs01 marked this pull request as ready for review August 4, 2026 18:47
The marketplace bump gate requires any plugin whose files changed to
bump its own plugin.json version.
@asachs01
asachs01 merged commit e135c70 into main Aug 4, 2026
1 check passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in MSP Claude Plugins Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant