feat: an MDE exclusion reviewer and a PowerShell author - #1
Merged
Conversation
Two agents, on the existing pattern: fragments composed at build time, branding in the profile, knowledge fetched and committed. mde-exclusion-reviewer reviews Defender for Endpoint and Defender Antivirus exclusion requests and audits lists that already exist. It is a reviewer, not an operator, and the manifest says so: a named human owns every exclusion decision. Nine safety nets, applied to every request. The never-exclude folder, extension and process lists are uploaded as knowledge rather than left to web search, because a reviewer that cannot see the authoritative list is a reviewer with an opinion, and a match is a rejection with the entry quoted. It states the blast radius every time, in particular that a process exclusion also stops network protection and ASR rules inspecting that process, which is the least understood consequence in the feature. Then narrowest form wins, fully qualified paths, LocalSystem variable resolution, redundancy against automatic server-role exclusions, one list per workload, evidence rather than anticipation, and an owner and review date even on an approval. One verdict per answer: APPROVE, NARROW, REJECT or INSUFFICIENT EVIDENCE. powershell-author answers house style and enterprise PowerShell 7: approved verbs and the noun prefix, strict mode, typed and validated parameters, comment-based help, objects rather than host writes, structured logging with the canonical level vocabulary, terminating versus non-terminating errors, secrets, and the analyzer and Pester gates. Two new profile tokens carry the PowerShell conventions so they rebrand with everything else: cmdlet_prefix and ps_module_name. Neither is a new question, because new-profile derives both from the organisation name. Proven end to end: rendered under a throwaway ACME profile the agent emits Invoke-AcmeTerraformPlan, Write-AcmeLog, AcmeHelpers and ACME_LOG_LEVEL with no Ldo or LibreDevOps leakage, and lint is clean. Six knowledge packs added, the Defender ones from the public MicrosoftDocs/defender-docs mirror. Budgets: exclusion reviewer 7593/8000, PowerShell author 7264/8000, both under the 95 percent warning line. Also de-hardcoded the agent count in three docs that said "both" or "three".
The language is shared between the two products and the schemas are not, which is the failure this agent exists to prevent: a hunt written against the wrong table set does not error helpfully, it returns nothing, and an empty result looks identical to a clean environment. So the agent names the target before it writes and asks when the request does not say. It also separates two artefacts people conflate. A hunt explores and may be noisy on purpose; a detection runs unattended and pages someone. It says which it is writing and refuses to hand over an untuned hunt as a rule, listing what still has to happen: tuning, entity mapping, severity, ATT&CK. The correctness section carries the traps that pass review and then mislead an investigation. First among them, verified against the Kusto reference: join defaults to kind=innerunique, which deduplicates the LEFT side, so rows disappear silently. The join operator page is a knowledge pack of its own for that reason. Then case sensitivity, has versus contains as terms versus substrings, per-table timestamp columns, and arg_max for the latest record. Performance is stated in the order the engine cares about rather than as a list of tips: datetime predicate first because Kusto indexes it and eliminates whole shards unread, then term-level string predicates most selective first, then the cheaper operator of each pair, never search *, smaller table on the left of a join, project early, materialize a reused let, limit anything exploratory. Seven knowledge packs, the Kusto ones from the public MicrosoftDocs/dataexplorer-docs mirror and the hunting ones from MicrosoftDocs/defender-docs. Budget 7520/8000, under the warning line.
The sibling to the hunt author, and the reason it carries the whole platform rather than just the rule form: most rule problems are really problems with the link either side of it. A rule that fires constantly is usually grouping or threshold, not the query. A rule nobody can investigate is usually a missing entity mapping. A rule that misses events is usually a schedule that does not match the source's ingestion delay. So the purpose fragment carries the pipeline: connectors ingest into tables, rules run KQL and raise alerts, alerts become incidents, entities correlate them and are what an analyst pivots on, automation rules fire on incident or alert events and call playbooks, watchlists hold reference data, UEBA adds baselines. Two platform facts that change answers are stated up front: Sentinel is Defender-portal only after 31 March 2027, and on a Defender-onboarded workspace Defender XDR creates and names incidents, the Microsoft Security rule type is auto-disabled and reopening closed incidents is unavailable. Prefer an ASIM parser over a native table so a rule survives a change of data source. Every limit is quoted rather than approximated, each verified against the reference: query 1 to 10,000 characters with search * and union * rejected outright, schedule 5 minutes to 14 days with interval no longer than lookback, the 5 minute scheduled delay against NRT's 2 minutes on ingestion time, 10 entity mappings of 3 identifiers with at least one required, 500 entities per alert divided equally across mappings and a 64 KB field cap, 150 alert caps on both event grouping and alert grouping, suppression up to 24 hours. A rule with no entity mapping is treated as a defect rather than a preference, because it produces an incident nobody can pivot from. Nine Sentinel knowledge packs plus the Kusto best practices, since a rule query runs on a schedule and its cost is recurring. Sentinel docs now live in the defender-docs mirror rather than azure-docs, which is its own signal. Budget 7596/8000.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two new agents on the existing pattern, plus the token work that makes the PowerShell one rebrand cleanly.
mde-exclusion-reviewerReviews Defender for Endpoint and Defender Antivirus exclusion requests, and audits exclusion lists that already exist. It is a reviewer, not an operator: it never applies anything, and the manifest disclaimer says a named human owns the decision.
One verdict per answer, as the first line: APPROVE, NARROW, REJECT, or INSUFFICIENT EVIDENCE.
The nine safety nets:
%TEMP%isC:\Windows\TEMPSafety net 2 is the one worth the agent existing for. The requester almost never knows that excluding a process silently disables ASR enforcement for it.
The never-exclude lists are uploaded knowledge, not left to web search, because scoped search only reads what Bing indexes and a reviewer that cannot see the authoritative list is a reviewer with an opinion.
powershell-authorHouse style plus enterprise PowerShell 7. Approved verbs and the noun prefix,
Set-StrictMode -Version Latest, typed and validated parameters,SupportsShouldProcessactually gated onShouldProcess, comment-based help, objects rather thanWrite-Host, structured logging with the canonicalTRACEtoFATALvocabulary and OTel severity numbers, terminating versus non-terminating errors, secrets, and the PSScriptAnalyzer and Pester gates.Rebranding, which was the explicit ask
The PowerShell conventions would have been hardcoded branding, so they are tokens:
cmdlet_prefixandps_module_name. Neither adds a prompt, becausenew-profilederives both from the organisation name (ACME→Acme,Acme→AcmeHelpers).Proven end to end against a throwaway profile:
Budgets and gates
mde-exclusion-reviewerpowershell-authorBoth under the 7600 warning line, so the next edit does not fail the build.
just validateclean: render drift gate plus lint, 5 agents, 0 warnings.Six knowledge packs added. The Defender ones come from the public
MicrosoftDocs/defender-docsmirror, so they are refreshable withjust update-knowledgelike everything else.Also de-hardcoded the agent count in three docs that still said "both agents" or "three agents".