@query-ai/digital-workers 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: hunt-quality-checker
3
+ description: Use at Phase 2 exit to verify hunt process compliance — catches skipped data sources, missing artifacts, untracked confidence, and process shortcuts before they degrade hunt quality
4
+ ---
5
+
6
+ # Hunt Quality Checker
7
+
8
+ ## Iron Law
9
+
10
+ **CHECK THE PROCESS BEFORE ADVANCING THE HUNT.**
11
+
12
+ Process shortcuts compound. A missing data-map in Phase 1 becomes blind queries in Phase 2 and false confidence in the report. A skipped specialist means domain-specific logic was never applied. These checks exist to catch shortcuts before they degrade hunt quality.
13
+
14
+ ## When to Invoke
15
+
16
+ - **Phase 2 exit**: Invoked by `threat-hunt` after investigation queries complete, before transitioning to Phase 3 (Pattern & Attack Discovery)
17
+
18
+ ## Reasoning Principles
19
+
20
+ Three principles anchor all checks.
21
+
22
+ ### 1. Artifacts are gates, not paperwork
23
+
24
+ `hypothesis.md` and `data-map.md` are not documentation — they are planning artifacts that shape what gets queried and how gaps are measured. Writing them after the queries defeats their purpose.
25
+
26
+ ### 2. Coverage is measurable
27
+
28
+ The data availability map defines what "complete" means. Without it, confidence is a guess. With it, every unqueried connector and untested TTP is visible.
29
+
30
+ ### 3. Specialists exist for a reason
31
+
32
+ The orchestrator coordinates. Specialists apply domain-specific logic, query patterns, and quality checks. When the orchestrator does specialist work itself, those quality checks are skipped.
33
+
34
+ ---
35
+
36
+ ## Phase 2 Exit Checkpoint — Hunt Process Compliance
37
+
38
+ Run at Phase 2 exit, before transitioning to Phase 3. Nine binary checks, designed for <90 seconds.
39
+
40
+ Review the hunt's hypothesis, data map, queries, and findings, then evaluate each check:
41
+
42
+ | # | Check | If No |
43
+ |---|-------|-------|
44
+ | 1 | Does `hypothesis.md` exist in the hunt directory AND was it written before any investigation queries? | FAIL — write it now; if queries already ran, document that hypothesis was retroactive |
45
+ | 2 | Does `data-map.md` exist in the hunt directory AND was it written before investigation queries? | FAIL — write it now; document any data sources that were queried without being in the map |
46
+ | 3 | For every TTP in `hypothesis.md`: was at least one query executed that specifically tests it? | FAIL — identify untested TTPs and execute queries before proceeding |
47
+ | 4 | For every connector in `data-map.md` marked as relevant: was it queried, or was a gap documented explaining why not? | FAIL — query the missing connector or document why it was skipped |
48
+ | 5 | Were confidence dimensions tracked during Phase 2 (Data Coverage %, TTP Coverage %, Enrichment Depth %)? | FAIL — calculate and report current confidence now |
49
+ | 6 | Is every executed query logged in `queries.md` with query text, result count, and summary? | FAIL — backfill missing entries before proceeding |
50
+ | 7 | If any finding was classified as Active Threat: was the hunt stopped and escalation initiated? | FAIL — stop now and escalate; do NOT proceed to Phase 3 |
51
+ | 8 | For dynamic schema connectors that returned empty results: is an assumptions caveat documented (data absent vs. mapping gap vs. filter issue)? | FAIL — add caveats before proceeding |
52
+ | 9 | Were specialist skills invoked when their trigger conditions were met? (identity findings → identity-investigator, network findings → network-investigator, IOCs → threat-intel-enricher) | FAIL — invoke the relevant specialist now before proceeding; the orchestrator must not replicate specialist work |
53
+
54
+ ---
55
+
56
+ ## Output Format
57
+
58
+ After running the checkpoint, output:
59
+
60
+ ```
61
+ HUNT QUALITY CHECK — Phase 2 Exit
62
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63
+
64
+ [1] hypothesis.md exists and pre-dates investigation: PASS | FAIL
65
+ [If FAIL: what was found and what action to take]
66
+
67
+ [2] data-map.md exists and pre-dates investigation: PASS | FAIL
68
+ [If FAIL: what was found and what action to take]
69
+
70
+ [3] All TTPs tested with at least one query: PASS | FAIL
71
+ [If FAIL: list untested TTPs]
72
+
73
+ [4] All relevant connectors queried or gap-documented: PASS | FAIL
74
+ [If FAIL: list unqueried connectors]
75
+
76
+ [5] Confidence dimensions tracked: PASS | FAIL
77
+ [If FAIL: current confidence = Data X% | TTP X% | Enrichment X%]
78
+
79
+ [6] All queries logged in queries.md: PASS | FAIL
80
+ [If FAIL: number of unlogged queries]
81
+
82
+ [7] Active threats escalated (or none found): PASS | FAIL
83
+ [If FAIL: STOP — escalate now]
84
+
85
+ [8] Dynamic connector empty results have assumptions caveats: PASS | FAIL
86
+ [If FAIL: list connectors missing caveats]
87
+
88
+ [9] Specialist skills invoked when triggered: PASS | FAIL
89
+ [If FAIL: list which specialists should have been invoked and why]
90
+
91
+ Result: ALL PASS | [N] FAILURES — fix before proceeding
92
+ ```
93
+
94
+ If any check FAILs, fix the issue before proceeding to Phase 3. Do not defer fixes to the report.
95
+
96
+ **After the check completes — whether all checks pass or after failures are fixed — immediately continue to Phase 3 without pausing.** This is an inline quality gate, not a stopping point. Do not wait for user input. Print the results and keep going.
97
+
98
+ ## Red Flags
99
+
100
+ | Red Flag | Correct Action |
101
+ |----------|---------------|
102
+ | "All checks passed" in under 10 seconds | STOP. You didn't actually check. Review each item against the hunt artifacts. |
103
+ | "This check doesn't apply to this hunt" | It might not. But state WHY it doesn't apply — don't just skip. |
104
+ | "I'll fix this in the report" | STOP. Fix it now. The point is to catch shortcuts before Phase 3, not annotate them after. |
105
+ | "The orchestrator already did this work" | STOP. That's the problem. Specialist skills apply domain-specific checks. Invoke them. |
@@ -0,0 +1,303 @@
1
+ ---
2
+ name: hypothesis-builder
3
+ description: Use when raw intel, MITRE technique IDs, or analyst hunches need to be transformed into structured, testable hypotheses scoped to available data
4
+ ---
5
+
6
+ # Hypothesis Builder
7
+
8
+ ## Iron Law
9
+
10
+ **A HYPOTHESIS MUST BE FALSIFIABLE. IF THE DATA CANNOT DISPROVE IT, REFRAME IT.**
11
+
12
+ ## When to Invoke
13
+
14
+ Called by `threat-hunt` orchestrator when a hunt needs a structured hypothesis:
15
+ - Raw threat intel (articles, advisories, PDFs)
16
+ - MITRE ATT&CK technique or tactic IDs
17
+ - Analyst observations or gut feelings
18
+ - Threat actor or campaign names
19
+ - Specific IOCs or described anomalies
20
+ - "What should I hunt next?" requests (suggest mode)
21
+
22
+ ## Process
23
+
24
+ ### Step 0: Qualification Gate
25
+
26
+ Before building a hypothesis, verify the input is specific enough. If too vague (e.g., "hunt for bad stuff"), present structured options:
27
+
28
+ ```
29
+ I need a bit more to build a testable hypothesis. Which fits your intent?
30
+
31
+ 1. "I have a specific threat or technique in mind"
32
+ -> Tell me the TTP, technique ID, or behavior you're looking for
33
+
34
+ 2. "I saw something suspicious and want to dig deeper"
35
+ -> Describe what you observed -- alert, anomaly, user report, gut feeling
36
+
37
+ 3. "I read an article about a threat and want to check our environment"
38
+ -> Share the link, paste the text, or upload the PDF
39
+
40
+ 4. "I want to test our visibility against a threat actor's playbook"
41
+ -> Name the actor, campaign, or advisory (e.g., APT28, Volt Typhoon, CISA AA24-xxx)
42
+ ```
43
+
44
+ Qualification criteria -- input must contain at least ONE of:
45
+ - A named MITRE ATT&CK technique or tactic
46
+ - A specific observable behavior
47
+ - A threat actor, campaign name, or advisory reference
48
+ - A specific IOC or set of IOCs
49
+ - A described anomaly with enough detail to query
50
+
51
+ ### Step 1: Intel Intake -- Multi-Modal Input Handling
52
+
53
+ Handle multiple input formats with graceful degradation:
54
+
55
+ | Input Type | How to Handle | Available In |
56
+ |------------|--------------|-------------|
57
+ | URL to article/advisory | Fetch via WebFetch, extract TTPs, IOCs, actor info | Claude Desktop, Claude Code |
58
+ | Pasted text | Parse directly | All environments |
59
+ | Uploaded PDF | Read via PDF tool | Claude Desktop, Claude Code |
60
+ | MITRE technique ID | Look up technique details, data sources | All environments |
61
+ | Threat actor / campaign name | Use knowledge + TI connectors | All environments |
62
+ | Described anomaly | Structure into testable hypothesis | All environments |
63
+
64
+ When URL fetch fails:
65
+
66
+ ```
67
+ I couldn't access that URL. To build the hypothesis, I need a few key details:
68
+
69
+ 1. What threat actor or campaign is described?
70
+ 2. What TTPs or attack techniques are mentioned?
71
+ 3. What IOCs are listed? (IPs, hashes, domains)
72
+ 4. What targets or industries are affected?
73
+ 5. What's the attack timeline or recency?
74
+
75
+ Even partial answers help -- I can fill gaps from threat intel connectors and MITRE data.
76
+ ```
77
+
78
+ If analyst can't provide details either (e.g., "I just saw a headline about Volt Typhoon"):
79
+ - Use the actor/campaign name to build hypothesis from known MITRE ATT&CK mappings
80
+ - Query any available TI connectors (discovered via `FSQL_Connectors`)
81
+ - Note: "Built from public ATT&CK profile, not from the specific article"
82
+
83
+ ### Step 2: Extract TTPs from Input
84
+
85
+ Parse the qualified input to identify all referenced TTPs. Map each to its MITRE ATT&CK technique ID, tactic, and associated data sources.
86
+
87
+ ### Step 3: Map TTPs to Data Sources
88
+
89
+ Use `FSQL_Connectors` + `Search_FSQL_SCHEMA` + the environment profile to determine:
90
+ - Which data sources are available for each TTP
91
+ - Which field paths exist in those connectors (verify -- do not assume standard OCSF paths for dynamic connectors)
92
+ - Where coverage gaps exist (TTPs with no available data source)
93
+
94
+ ### Step 4: Formulate the Hypothesis
95
+
96
+ Structure as: "We believe [threat/behavior] is occurring in [scope] because [reasoning]. We test by querying [data sources] for [observable patterns]."
97
+
98
+ Define hunt parameters:
99
+ - Query patterns for each data source
100
+ - Time range for the hunt
101
+ - Baseline vs. suspicious thresholds
102
+ - Success criteria (what proves the hypothesis)
103
+ - Null criteria (what disproves the hypothesis)
104
+
105
+ ### Step 5: Determine Hunt Tier
106
+
107
+ Derived from the hypothesis structure, not guessed from the prompt:
108
+
109
+ | Signal | Tier | Rationale |
110
+ |--------|------|-----------|
111
+ | 1-2 TTPs AND 1-3 relevant connectors AND scoped to specific hosts/users/segment | Focused | Narrow hypothesis, limited data surface -- 25 min circuit breaker |
112
+ | 3+ TTPs OR 4+ relevant connectors OR environment-wide scope | Broad | Complex hypothesis, large data surface -- 45 min circuit breaker |
113
+
114
+ Examples (illustrative -- actual connector names discovered at runtime):
115
+ - "Hunt for RDP lateral movement (T1021.001) from service accounts on finance subnet via [auth connector]" -- 1 TTP, 1 connector -- **Focused**
116
+ - "Hunt for APT28 TTPs: spearphishing, credential dumping, lateral movement, exfil across all connectors" -- 4 TTPs, all connectors -- **Broad**
117
+ - "Hunt for PowerShell fileless execution (T1059.001) across all endpoints" -- 1 TTP, but environment-wide -- **Broad**
118
+
119
+ The analyst can always override: "Just do a focused pass first" downgrades. "Go broad" upgrades. Default comes from hypothesis structure, not vibes.
120
+
121
+ ### Step 6: Note HMM Level
122
+
123
+ Document which Hunt Maturity Model level this hunt represents.
124
+
125
+ ## Hunt History Detection — Three-Tier Model
126
+
127
+ Before generating recommendations, detect what hunt history is available. The maturity of hunt history storage varies by customer — degrade gracefully.
128
+
129
+ ### Detection Sequence
130
+
131
+ Run these checks in order. Use the FIRST tier that returns data:
132
+
133
+ **Tier 3: Integrated History (Linear, Notion, JIRA via MCP)**
134
+ Check for project management MCP connectors. Search for hunt-related projects/issues:
135
+ - Linear: Use `list_projects` / `list_issues` to find a "Threat Hunting" project
136
+ - Notion: Use `notion-search` to find hunt databases or pages
137
+ - If found: extract past hypotheses, TTPs tested, gaps identified, detection coverage
138
+
139
+ **Tier 2: Local History (`docs/hunts/`)**
140
+ Check if `docs/hunts/` directory exists with past hunt artifacts:
141
+ - Read `gaps.md` files from previous hunts for known coverage gaps
142
+ - Read `findings.md` files for previously tested TTPs and results
143
+ - Read `detections.md` for existing detection coverage
144
+
145
+ **Tier 1: Zero History (First Hunt)**
146
+ No hunt history available — this is the first hunt or history isn't stored.
147
+ - Rely entirely on: available connectors, MITRE ATT&CK coverage analysis, TI signals, environment profile
148
+ - Explicitly note: "No hunt history detected. Recommendations based on data availability and threat landscape."
149
+
150
+ ### Tier Detection Output
151
+
152
+ ```
153
+ HUNT HISTORY: Tier [1/2/3] — [Zero History / Local History / Integrated (Linear)]
154
+ Source: [what was found]
155
+ Past hunts: [count or "none"]
156
+ Known gaps: [count or "none"]
157
+ TTPs previously tested: [count or "none"]
158
+ ```
159
+
160
+ **This detection feeds directly into suggest mode and influences recommendation ranking.**
161
+
162
+ ---
163
+
164
+ ## Suggest Mode — Default Entry Point (HMM3 Capability)
165
+
166
+ Suggest mode is the **default** when the analyst does not provide a specific hypothesis, technique, or intel. This includes:
167
+ - "What should I hunt?"
168
+ - "Suggest hunts"
169
+ - "What's worth looking at?"
170
+ - "Let's go hunting" (no specific target)
171
+ - "Start a hunt" (no hypothesis attached)
172
+ - Any prompt that invokes `threat-hunt` without qualifying input
173
+
174
+ ### Recommendation Ranking Criteria
175
+
176
+ Score each candidate hunt on five weighted dimensions:
177
+
178
+ | Dimension | Weight | What It Measures |
179
+ |-----------|--------|------------------|
180
+ | **Data Availability** | 30% | Do we have connectors and verified field paths for this TTP? Hunts with data rank higher than hunts against gaps. |
181
+ | **TTP Risk Impact** | 25% | MITRE ATT&CK prevalence and impact. Techniques used by active threat actors in the current landscape rank higher. |
182
+ | **Never Tested** | 20% | Has this TTP or tactic EVER been hunted? (From hunt history tier). First-time coverage ranks higher than re-tests. |
183
+ | **TI Relevance** | 15% | Are threat intel connectors showing current activity related to this TTP? Recent signals rank higher. |
184
+ | **Environment Change** | 10% | Have new connectors, field mappings, or data sources appeared since the last hunt? New data = new visibility. |
185
+
186
+ ### Recommendation Generation Process
187
+
188
+ 1. **Detect hunt history tier** (see above)
189
+ 2. **Discover available connectors** via `FSQL_Connectors`
190
+ 3. **Map connector coverage to MITRE ATT&CK** — which tactics/techniques can we actually test?
191
+ 4. **Query TI connectors** for recent threat signals (if available)
192
+ 5. **Check environment profile** for changes since last hunt
193
+ 6. **Score and rank** candidate hunts using the 5-dimension model
194
+ 7. **Present Top 10** to the analyst
195
+
196
+ ### Suggest Mode Output Format
197
+
198
+ ```
199
+ HUNT HISTORY: Tier [1/2/3] — [status]
200
+
201
+ RECOMMENDED HUNTS — Top 10 (ranked by composite score)
202
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
203
+
204
+ 1. [HIGH — 92] Hunt for scheduled task persistence (T1053.005)
205
+ Why: Zero previous coverage of Persistence tactic. 2 connectors with verified paths.
206
+ Score: Data 30/30 | Risk 22/25 | Untested 20/20 | TI 10/15 | Env 10/10
207
+ Source: ATT&CK coverage gap + environment change (new EDR connector)
208
+ Tier: Focused — 1 TTP, 2 connectors
209
+
210
+ 2. [HIGH — 87] Hunt for CVE-2026-XXXXX exploitation (T1190)
211
+ Why: Actively exploited vulnerability affecting [product] in environment.
212
+ Score: Data 25/30 | Risk 25/25 | Untested 15/20 | TI 15/15 | Env 7/10
213
+ Source: Threat intel connector signal (last 72h)
214
+ Tier: Focused — 1 TTP, 1 connector
215
+
216
+ 3. [HIGH — 81] Hunt for PowerShell fileless execution (T1059.001)
217
+ Why: High-impact execution technique, strong data coverage, never tested.
218
+ Score: Data 30/30 | Risk 20/25 | Untested 20/20 | TI 5/15 | Env 6/10
219
+ Source: ATT&CK coverage gap analysis
220
+ Tier: Broad — 1 TTP, environment-wide
221
+
222
+ ...
223
+
224
+ 10. [MEDIUM — 54] Baseline new [connector name] data
225
+ Why: New dynamic schema connector — field mappings untested.
226
+ Score: Data 10/30 | Risk 10/25 | Untested 20/20 | TI 4/15 | Env 10/10
227
+ Source: Environment profile change
228
+ Tier: Broad — discovery sweep
229
+
230
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
231
+ Select a number to begin, or describe a different hypothesis.
232
+ ```
233
+
234
+ **Tier 1 (zero history) messaging:**
235
+
236
+ ```
237
+ HUNT HISTORY: Tier 1 — Zero History
238
+ This appears to be your first structured hunt. Recommendations are based
239
+ entirely on your current data sources and the threat landscape.
240
+
241
+ After this hunt, findings and gaps will be stored locally (docs/hunts/)
242
+ to improve future recommendations. For persistent tracking, consider
243
+ creating a Threat Hunting project in Linear, Notion, or JIRA.
244
+
245
+ RECOMMENDED HUNTS — Top 10 (ranked by composite score)
246
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
247
+ [recommendations as above, but Never Tested dimension scores 20/20 for all]
248
+ ```
249
+
250
+ ## Output
251
+
252
+ ```
253
+ HYPOTHESIS:
254
+ Statement: "We believe [threat/behavior] is occurring in [scope] because
255
+ [reasoning]. We test by querying [data sources] for
256
+ [observable patterns]."
257
+
258
+ MITRE Mapping:
259
+ Technique: [ID] -- [Name]
260
+ Tactic: [Tactic name]
261
+ Data Sources: [list]
262
+
263
+ Data Source Map:
264
+ Available: [connectors with verified field paths]
265
+ Gaps: [TTPs with no available data source]
266
+ Coverage: [percentage of hypothesis TTPs with data]
267
+
268
+ Query Strategy:
269
+ Data Sources: [connector list]
270
+ Time Range: [start -- end]
271
+ Baseline: [what normal looks like]
272
+ Suspicious: [thresholds that indicate the hypothesis may be true]
273
+
274
+ Success Criteria: [what confirms the hypothesis]
275
+ Null Criteria: [what disproves the hypothesis]
276
+
277
+ Hunt Tier: [Focused / Broad] -- [rationale]
278
+ Circuit Breaker: [25 min / 45 min]
279
+ HMM Level: [level]
280
+
281
+ Confidence Dimensions:
282
+ Data Coverage: [what constitutes 100% for this hunt]
283
+ TTP Coverage: [what constitutes 100% for this hunt]
284
+
285
+ Source Note: [origin of hypothesis -- analyst input, article, suggest mode, etc.]
286
+ ```
287
+
288
+ **Return this structured hypothesis to the calling orchestrator and continue. Do not present to the user or wait for input unless running the qualification gate.**
289
+
290
+ ## Red Flags
291
+
292
+ | Red Flag | Correct Action |
293
+ |----------|---------------|
294
+ | "Let's just look for anything suspicious" | STOP. That's not a hypothesis. Run the qualification gate. |
295
+ | Accepting a vague hypothesis to avoid friction | STOP. Vague hypotheses produce meaningless results. Guide the analyst. |
296
+ | Hardcoding connector names in the hypothesis | STOP. Use `FSQL_Connectors` for runtime discovery. |
297
+ | Skipping data source mapping | STOP. A hypothesis without a data source map will waste Phase 2 on queries that can't return results. |
298
+ | Determining tier from vibes instead of structure | STOP. Count TTPs, connectors, and scope. The tier is a calculation, not a judgment call. |
299
+ | Assuming standard OCSF paths for dynamic connectors | STOP. Use `Search_FSQL_SCHEMA` to verify field paths. Dynamic connectors have customer-defined mappings. |
300
+ | URL fetch failed, abandoning the hunt | STOP. Degrade gracefully -- use actor name, MITRE mappings, TI connectors. Never let access failure kill the hunt. |
301
+ | Building hypothesis without checking what data actually exists | STOP. Map TTPs to available data BEFORE finalizing. A beautiful hypothesis against data you don't have is useless. |
302
+ | Recommending hunts without checking hunt history | STOP. Run the three-tier history detection. Recommending a TTP you already hunted last week is wasted effort. |
303
+ | Hardcoding hunt history location | STOP. Detect the tier at runtime. Not every customer has Linear or local hunt artifacts. Degrade gracefully. |
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: identity-investigator
3
+ description: Use when investigation involves user accounts, authentication events, privilege changes, or identity-based indicators — deep dive on user behavior and access patterns
4
+ ---
5
+
6
+ # Identity Investigator
7
+
8
+ ## Iron Law
9
+
10
+ **ESTABLISH BASELINE BEFORE JUDGING ANOMALOUS.**
11
+
12
+ A failed login is not suspicious without context. 50 failed logins from the same IP in 5 minutes is. Always gather enough data to distinguish normal from abnormal for this specific user/account.
13
+
14
+ ## When to Invoke
15
+
16
+ Called by `alert-investigation` when the `alert-classifier` identifies:
17
+ - Alert type: Identity/Access
18
+ - IOCs include: usernames, email addresses, service accounts
19
+ - MITRE techniques: T1078 (Valid Accounts), T1110 (Brute Force), T1136 (Create Account), T1098 (Account Manipulation)
20
+
21
+ ## Investigation Process
22
+
23
+ Use `digital-workers:fsql-expert` for ALL queries below.
24
+
25
+ ### Step 1: Identify the Account
26
+
27
+ From the alert IOCs, identify:
28
+ - Username(s) involved
29
+ - Account type: human user, service account, admin account, shared account
30
+ - Associated email address(es)
31
+
32
+ ### Step 2: Authentication Pattern Analysis
33
+
34
+ Query authentication events for this user with specific field selectors:
35
+
36
+ ```
37
+ QUERY authentication.message, authentication.time, authentication.status_id,
38
+ authentication.src_endpoint.ip, authentication.user.username,
39
+ authentication.http_request.user_agent
40
+ WITH authentication.user.username = '<username>' AFTER 7d
41
+ ```
42
+
43
+ Look for:
44
+ - **Volume**: How many auth events in the time window? Is this normal?
45
+ - **Failures**: Count and pattern of failures vs. successes
46
+ - **Source IPs**: Are logins coming from expected locations?
47
+ - **Timing**: Are logins happening at expected times?
48
+ - **MFA**: Was MFA used? Was it bypassed?
49
+ - **Methods**: Password, SSO, API key, certificate — is the method expected?
50
+
51
+ **SUMMARIZE for authentication pattern analysis:**
52
+
53
+ Use SUMMARIZE to quickly quantify authentication patterns before drilling into individual events:
54
+
55
+ ```
56
+ -- Failure volume and source distribution
57
+ SUMMARIZE COUNT DISTINCT authentication.src_endpoint.ip
58
+ GROUP BY authentication.actor.user.email_addr
59
+ WITH authentication.status_id = FAILURE AFTER 7d
60
+
61
+ -- Success from unusual locations (impossible travel signal)
62
+ SUMMARIZE COUNT DISTINCT authentication.device.ip
63
+ GROUP BY authentication.actor.user.email_addr
64
+ WITH authentication.status_id = SUCCESS AFTER 24h
65
+
66
+ -- Auth volume per source IP (which IPs are most active?)
67
+ SUMMARIZE COUNT authentication.user.uid
68
+ GROUP BY authentication.src_endpoint.ip
69
+ WITH authentication.actor.user.email_addr = '<user>' AFTER 7d
70
+ ```
71
+
72
+ Start with SUMMARIZE for the distribution picture, then QUERY for the individual events that look anomalous.
73
+
74
+ > **Constraints:** SUMMARIZE has known execution limits — `status_id` filtering fails on detection_finding (use GROUP BY instead), `FROM` not supported, high-cardinality GROUP BY can overflow. If SUMMARIZE returns empty, fall back to QUERY. See fsql-expert Layer 1c for workarounds and check `summarize_support` in the environment profile.
75
+
76
+ ### Step 3: Privilege and Account Changes
77
+
78
+ Query for account modifications:
79
+
80
+ ```
81
+ QUERY account_change.message, account_change.time, account_change.user.username,
82
+ account_change.type_name
83
+ WITH account_change.user.username = '<username>' AFTER 30d
84
+ ```
85
+
86
+ Look for:
87
+ - Role or group changes
88
+ - Password resets
89
+ - MFA enrollment/removal
90
+ - New API keys or tokens created
91
+ - Permission escalation
92
+
93
+ ### Step 4: Session Activity
94
+
95
+ If the user authenticated successfully, what did they do?
96
+
97
+ ```
98
+ -- Layer 1a: Discover which event types contain this user's activity
99
+ QUERY *.message, *.time WITH %username = '<username>' AFTER 24h
100
+
101
+ -- Layer 1b: Query specific event types found in Layer 1a with targeted fields
102
+ -- (adapt based on which __event types appear in Layer 1a results)
103
+ ```
104
+
105
+ This discovery scan reveals all event types across the mesh tied to this identity. Read the `__event` field to see where the user appears, then query those specific event types for detail:
106
+ - Applications accessed
107
+ - Data sources queried
108
+ - Files accessed or modified
109
+ - Cloud resources touched
110
+
111
+ ### Step 5: Cross-Reference Source IPs
112
+
113
+ For any suspicious source IPs found in auth events:
114
+
115
+ ```
116
+ -- Layer 1a: Discover where this IP appears across the mesh
117
+ QUERY *.message, *.time WITH %ip = '<suspicious_ip>' AFTER 7d
118
+
119
+ -- Layer 1b: Query specific event types found in Layer 1a
120
+ ```
121
+
122
+ Determine:
123
+ - Is this IP used by other users? (Shared VPN, office IP)
124
+ - Is this IP associated with other suspicious activity?
125
+ - Geo-location and reputation (pass to `threat-intel-enricher`)
126
+
127
+ ### Step 6: Assess and Report
128
+
129
+ Synthesize findings into:
130
+ - **Account compromise confidence**: Confirmed / Likely / Possible / Unlikely
131
+ - **Timeline**: When did suspicious activity start?
132
+ - **Scope**: What systems/data were accessed?
133
+ - **Lateral movement**: Did the compromised account access other systems?
134
+ - **Persistence**: Were new credentials or access methods created?
135
+
136
+ ## Output
137
+
138
+ ```
139
+ IDENTITY INVESTIGATION:
140
+ Account: [username] ([account type])
141
+ Compromise Assessment: [Confirmed/Likely/Possible/Unlikely]
142
+
143
+ Authentication Summary:
144
+ Total events (7d): [count]
145
+ Failures: [count] from [unique IPs] IPs
146
+ Successes: [count] from [unique IPs] IPs
147
+ Unusual: [description of anomalies]
148
+
149
+ Account Changes (30d): [list or "None detected"]
150
+
151
+ Post-Auth Activity:
152
+ Systems accessed: [list]
153
+ Data sources queried: [list]
154
+ Anomalous actions: [list or "None detected"]
155
+
156
+ Suspicious Source IPs: [list with reputation]
157
+
158
+ Timeline: [chronological summary]
159
+
160
+ IOCs Discovered: [new indicators found during investigation]
161
+ Recommended Follow-Up: [additional queries or skills to invoke]
162
+ ```
163
+
164
+ **Return this investigation output to the calling orchestrator and continue. Do not present to the user or wait for input — the orchestrator will incorporate findings into the evidence package.**
165
+
166
+ ## Red Flags
167
+
168
+ | Red Flag | Correct Action |
169
+ |----------|---------------|
170
+ | "Only one failed login, not suspicious" | Complete the investigation. One failed login with a successful login from a new IP seconds later IS suspicious. |
171
+ | "This is a service account, skip user analysis" | STOP. Service account compromise is often MORE severe. Investigate fully. |
172
+ | "I can see the auth logs, that's enough" | STOP. Check account changes and post-auth activity too. Auth is just the entry point. |