
Security Investigator Automation
- 1 installs
- 10 repo stars
- Updated August 4, 2026
- aradotso/security-skills
security-investigator-automation is a skill that automates natural-language security investigations across Microsoft Sentinel, Defender XDR and Graph API using Copilot Agent Skills and MCP servers.
About
A framework that runs automated security investigations across the Microsoft security stack using GitHub Copilot Agent Skills, VS Code and MCP servers. It lets an analyst query Sentinel, Defender XDR and Graph API in natural language for user, incident, device and IoC investigations. A SOC analyst uses it to hunt threats and produce reports. It matters because it turns manual KQL hunting into guided agent workflows.
- Natural-language threat hunting across Microsoft Sentinel, Defender XDR and Graph API
- Ships 25 investigation workflows with KQL queries and IoC enrichment
- Generates automated HTML investigation reports
Security Investigator Automation by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,834 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
security-investigator-automation capabilities & compatibility
Requires Azure/Sentinel access plus IPInfo, AbuseIPDB, Shodan and VPNAPI keys.
- Capabilities
- threat hunting · incident investigation · ioc enrichment
- Works with
- azure · github
- Use cases
- security audit · research · documentation
- IDEs
- vscode
- Pricing
- Bring your own API key
What security-investigator-automation says it does
Includes 25 specialized investigation workflows with KQL queries, threat intelligence enrichment, and automated HTML report generation
**@sentinel-triage** - Defender XDR Advanced Hunting
npx skills add https://github.com/aradotso/security-skills --skill security-investigator-automationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 10 |
| Last updated | August 4, 2026 |
| Repository | aradotso/security-skills ↗ |
What it does
Run natural-language security investigations across Microsoft Sentinel and Defender XDR, enriching IoCs and generating HTML reports.
Who is it for?
SOC analysts hunting threats and investigating incidents across Microsoft Sentinel and Defender XDR.
Skip if: Teams not on the Microsoft security stack or without Sentinel/Defender access.
When should I use this skill?
You need to investigate a user, incident, device or IoC in Sentinel/Defender using natural language.
What you get
Guided natural-language investigations with IoC enrichment and automated HTML reports.
- HTML investigation reports
- IoC reputation assessments
- Incident MITRE ATT&CK mappings
By the numbers
- 25 specialized investigation workflows
- 7 preconfigured MCP servers
- 5-dimension device Drift Score
Files
security-investigator-automation
Skill by ara.so — Security Skills collection.
Automated security investigation framework combining GitHub Copilot Agent Skills, VS Code, and Model Context Protocol (MCP) servers to enable natural language security investigations across Microsoft Sentinel, Defender XDR, Graph API, and threat intelligence platforms. Includes 25 specialized investigation workflows with KQL queries, threat intelligence enrichment, and automated HTML report generation.
Installation
# Clone repository
git clone https://github.com/SCStelz/security-investigator.git
cd security-investigator
code .
# Set up Python virtual environment
python -m venv .venv
# Windows
.venv\Scripts\Activate.ps1
# macOS/Linux
source .venv/bin/activate
# Install dependencies (hash-verified recommended)
pip install --require-hashes -r requirements.lock
# OR without hash verification
pip install -r requirements.txtConfiguration
1. Sentinel and Azure Configuration
# Copy template
copy config.json.template config.jsonEdit config.json:
{
"workspace_id": "your-sentinel-workspace-id",
"tenant_id": "your-azure-tenant-id",
"subscription_id": "your-azure-subscription-id",
"resource_group": "your-resource-group",
"workspace_name": "your-sentinel-workspace-name"
}2. Threat Intelligence API Keys
# Copy template
copy .env.template .envEdit .env:
IPINFO_TOKEN=your_ipinfo_token
ABUSEIPDB_API_KEY=your_abuseipdb_key
VPNAPI_KEY=your_vpnapi_key
SHODAN_API_KEY=your_shodan_key3. MCP Server Configuration
# Copy template
copy .vscode\mcp.json.template .vscode\mcp.jsonThe template includes pre-configured MCP servers:
- @sentinel-datalake - Sentinel log analytics
- @sentinel-triage - Defender XDR Advanced Hunting
- @graph-api - Entra ID/Graph API queries
- @kql-search - Schema documentation
- @microsoft-learn - Documentation reference
- @azure-mcp-server - Azure Resource Manager + Monitor
- @sentinel-graph - Relationship mapping (private preview)
Custom local MCP apps (geomap, heatmap, incident-comment) are also pre-configured.
Core Workflow
1. Start Investigation with Copilot Chat
Open VS Code Copilot Chat (Ctrl+Shift+I) in Agent mode.
Recommended first command:
"Run a threat pulse scan"This executes the threat-pulse skill which scans 9 security domains and provides prioritized findings with drill-down recommendations.
2. Investigation Skills
The system auto-detects skills based on keywords:
Core Investigations
User Investigation:
"Investigate user@domain.com for the last 7 days"Generates comprehensive user analysis:
- Entra ID sign-in activity with anomaly detection
- MFA status and authentication methods
- Risky sign-ins and Identity Protection alerts
- Device registrations and compliance
- Audit log changes (role assignments, permissions)
- Associated incidents and alerts
- HTML report with IP enrichment
Incident Investigation:
"Analyze incident 12345"Deep-dive incident analysis:
- Criticality assessment (CRITICAL/HIGH/MEDIUM/LOW)
- Entity extraction (users, devices, IPs, processes)
- Recursive entity investigation
- MITRE ATT&CK mapping
- Evidence correlation across Sentinel and Defender XDR
IoC Investigation:
"Is this IP malicious? 203.0.113.42"Multi-source threat intelligence:
- Defender Threat Intelligence API
- Sentinel ThreatIntelligenceIndicator table
- AbuseIPDB reputation scores
- Shodan port/service/CVE data
- VPN detection (vpnapi.io)
- Geolocation with IPInfo
- Organizational exposure assessment
Device Investigation:
"Investigate computer WIN-CLIENT01"Endpoint security analysis:
- Defender alerts and vulnerabilities
- Device compliance status
- Logged-on users and sessions
- Process execution (DeviceProcessEvents)
- Network connections (DeviceNetworkEvents)
- File operations (DeviceFileEvents)
Authentication & Access
Authentication Tracing:
"Trace authentication for SessionId abc123"Forensic authentication chain analysis:
- SessionId correlation across sign-ins
- Token reuse vs interactive MFA events
- Geographic anomaly detection
- Authentication method changes
Conditional Access Policy Investigation:
"Investigate Conditional Access failures for user@domain.com"Policy forensics:
- CA policy state changes (enabled/disabled)
- Sign-in failure correlation
- Device compliance bypass detection
- Policy evaluation timeline
Behavioral Analysis
Scope Drift Detection (Device):
"Detect device drift for WIN-SERVER01"Baseline deviation analysis:
- Configurable baseline window (default 30 days)
- 5-dimension Drift Score: Volume, Processes, Accounts, Command Chains, Code Signing
- Heartbeat corroboration for uptime validation
- Fleet-wide or single-device analysis
Scope Drift Detection (SPN):
"Detect scope drift for service principal app-id-123"Service principal behavioral change:
- 90-day baseline vs 7-day comparison
- Correlated with AuditLogs, SecurityAlert, DeviceNetworkEvents
- New resource access patterns
- Permission elevation detection
Posture & Exposure
Threat Pulse (Quick Scan):
"Run a morning threat pulse"Broad-spectrum scan with color-coded verdicts:
- 🔴 Escalate - Critical findings requiring immediate action
- 🟠 Investigate - Medium-risk anomalies
- 🟡 Monitor - Low-risk observations
- ✅ Clear - No issues detected
Covers:
- Active incidents (Sentinel + Defender XDR)
- Identity risks (humans + non-human identities)
- Endpoint threats
- Exposure management (Defender EASM)
- Email threats (Defender for Office 365)
- UEBA anomalies
- Authentication spray attacks
- Privileged operations
- Recent CVEs in environment
Exposure Management:
"Run exposure management scan"Attack surface analysis:
- Defender EASM integration
- Internet-facing assets
- Shadow IT discovery
- SSL/TLS certificate inventory
- Domain and subdomain enumeration
Identity Posture:
"Analyze identity posture"Entra ID security assessment:
- Guest user risk
- Privileged role assignments
- MFA coverage gaps
- Legacy authentication usage
- Inactive high-privilege accounts
Python Utilities
Generate Investigation Report
from report_generator import generate_investigation_report
# Generate HTML report from investigation data
report_data = {
"user": "user@domain.com",
"investigation_period": "7 days",
"sign_ins": [...], # Sign-in data from Sentinel
"alerts": [...], # Security alerts
"devices": [...] # Device registrations
}
generate_investigation_report(
data=report_data,
output_file="investigation_report.html"
)IP Enrichment
from enrich_ips import enrich_ip_address
# Enrich IP with threat intelligence
enrichment = enrich_ip_address("203.0.113.42")
print(f"Country: {enrichment['country']}")
print(f"ISP: {enrichment['isp']}")
print(f"Is VPN: {enrichment['is_vpn']}")
print(f"Abuse Score: {enrichment['abuse_confidence_score']}")
print(f"Shodan Services: {enrichment['shodan_services']}")
print(f"Associated CVEs: {enrichment['shodan_vulns']}")Batch Report Generation from JSON
# Generate report from JSON investigation output
python generate_report_from_json.py investigation_output.json
# Creates HTML report with:
# - Executive summary
# - Timeline visualization
# - Risk scoring matrix
# - Enriched IP addresses with threat intel
# - MITRE ATT&CK mapping
# - Recommended actionsKQL Query Patterns
The framework includes a verified query library in queries/ directory:
User Activity Query
// queries/user_signins.kql
SigninLogs
| where TimeGenerated > ago(7d)
| where UserPrincipalName == "user@domain.com"
| extend GeoLocation = strcat(Location.city, ", ", Location.countryOrRegion)
| extend RiskState = case(
RiskLevelDuringSignIn == "high", "🔴 High Risk",
RiskLevelDuringSignIn == "medium", "🟠 Medium Risk",
RiskLevelDuringSignIn == "low", "🟡 Low Risk",
"✅ No Risk"
)
| project
TimeGenerated,
UserPrincipalName,
AppDisplayName,
IPAddress,
GeoLocation,
RiskState,
AuthenticationRequirement,
ConditionalAccessStatus,
DeviceDetail.displayName
| order by TimeGenerated descDevice Process Baseline
// queries/device_process_baseline.kql
let BaselineWindow = 30d;
let AnalysisWindow = 7d;
let DeviceName = "WIN-CLIENT01";
let Baseline = DeviceProcessEvents
| where TimeGenerated between (ago(BaselineWindow) .. ago(AnalysisWindow))
| where DeviceName == DeviceName
| summarize
BaselineProcesses = make_set(FileName),
BaselineAccounts = make_set(AccountName),
BaselineVolume = count()
by DeviceName;
let Recent = DeviceProcessEvents
| where TimeGenerated > ago(AnalysisWindow)
| where DeviceName == DeviceName
| summarize
RecentProcesses = make_set(FileName),
RecentAccounts = make_set(AccountName),
RecentVolume = count()
by DeviceName;
Baseline
| join kind=inner Recent on DeviceName
| extend
NewProcesses = set_difference(RecentProcesses, BaselineProcesses),
NewAccounts = set_difference(RecentAccounts, BaselineAccounts),
VolumeChange = (todouble(RecentVolume) - todouble(BaselineVolume)) / todouble(BaselineVolume) * 100
| extend DriftScore = case(
array_length(NewProcesses) > 10 or VolumeChange > 50, 90,
array_length(NewProcesses) > 5 or VolumeChange > 25, 70,
array_length(NewProcesses) > 0 or VolumeChange > 10, 40,
0
)
| project
DeviceName,
DriftScore,
NewProcessCount = array_length(NewProcesses),
NewProcesses,
VolumeChange = round(VolumeChange, 2),
Verdict = case(
DriftScore >= 80, "🔴 High Drift - Investigate",
DriftScore >= 50, "🟠 Medium Drift - Monitor",
DriftScore >= 20, "🟡 Low Drift - Baseline Update",
"✅ Normal Behavior"
)Incident Entity Extraction
// queries/incident_entities.kql
SecurityIncident
| where IncidentNumber == "12345"
| mv-expand AlertIds
| join kind=inner (
SecurityAlert
| mv-expand Entities
| extend EntityType = tostring(Entities.Type)
| extend EntityValue = case(
EntityType == "account", tostring(Entities.Name),
EntityType == "host", tostring(Entities.HostName),
EntityType == "ip", tostring(Entities.Address),
EntityType == "process", tostring(Entities.ProcessId),
EntityType == "file", tostring(Entities.Name),
tostring(Entities)
)
) on $left.AlertIds == $right.SystemAlertId
| summarize
EntityCount = count(),
Entities = make_set(EntityValue)
by IncidentNumber, EntityType
| order by EntityCount descMCP Server Interaction Patterns
Query Sentinel Data Lake
@sentinel-datalake execute the user sign-in query for user@domain.comThe agent will: 1. Load appropriate query from queries/ directory 2. Replace parameters (UPN, time range) 3. Execute via Sentinel Data Lake MCP server 4. Parse results and apply skill-specific analysis
Advanced Hunting (Defender XDR)
@sentinel-triage hunt for process execution on device WIN-CLIENT01Uses DeviceProcessEvents, DeviceNetworkEvents, DeviceFileEvents across Defender for Endpoint.
Graph API Queries
@graph-api get user details for user@domain.com including risk state and authentication methodsQueries Entra ID for:
- User profile and attributes
- Sign-in activity
- Risk detections (Identity Protection)
- Authentication methods
- Device registrations
- Group memberships
- Role assignments
Skill Development
Create custom investigation skills in .github/skills/:
---
name: custom-investigation
description: Custom security investigation workflow
triggers:
- "custom investigation"
- "run custom hunt"
---
# Custom Investigation Skill
## Objective
[Describe what this skill investigates]
## Detection Logic
[KQL queries and analysis patterns]
## Risk Assessment
- 🔴 CRITICAL: [conditions]
- 🟠 HIGH: [conditions]
- 🟡 MEDIUM: [conditions]
- ✅ LOW: [conditions]
## Workflow
1. **Data Collection**
- Query: `queries/custom_query.kql`
- Sources: [Sentinel tables]
2. **Analysis**
- [Analysis steps]
3. **Enrichment**
- [Threat intel sources]
4. **Reporting**
- [Output format]
## Example
User: "Run custom investigation for user@domain.com"
Agent: [Expected workflow execution]Reference the skill in .github/copilot-instructions.md:
## Skill: custom-investigation
**Triggers:** "custom investigation", "run custom hunt"
**Path:** .github/skills/custom-investigation/SKILL.mdTroubleshooting
MCP Server Connection Issues
# Verify MCP configuration
cat .vscode\mcp.json
# Check logs in VS Code
# View -> Output -> Select "MCP" from dropdown
# Test Sentinel connectivity
az login
az account showAuthentication Errors
# Refresh Azure credentials
az logout
az login --tenant your-tenant-id
# Verify Sentinel access
az monitor log-analytics workspace show \
--resource-group your-rg \
--workspace-name your-workspacePython Dependencies
# Reinstall with hash verification
pip install --force-reinstall --require-hashes -r requirements.lock
# Check installed packages
pip list
# Verify environment activation
python -c "import sys; print(sys.prefix)"Missing Threat Intel Data
- IPInfo: Free tier allows 50,000 requests/month - check env var
IPINFO_TOKEN - AbuseIPDB: Free tier allows 1,000 requests/day - check
ABUSEIPDB_API_KEY - Shodan: Requires paid API key - check
SHODAN_API_KEY - VPNapi: Free tier for basic checks - check
VPNAPI_KEY
Enrichment gracefully degrades if APIs are unavailable.
KQL Query Errors
# Test query syntax in Sentinel portal first
# Logs -> Run query manually
# Copy working query to queries/ directory
# Verify table schema with @kql-search
@kql-search show schema for SigninLogsReport Generation Failures
# Debug report generation
python generate_report_from_json.py investigation_output.json --debug
# Validate JSON structure
import json
with open('investigation_output.json') as f:
data = json.load(f)
print(json.dumps(data, indent=2))Copilot Skill Not Triggering
1. Check trigger keywords in .github/skills/[skill-name]/SKILL.md 2. Verify skill is referenced in .github/copilot-instructions.md 3. Reload VS Code window (Ctrl+Shift+P -> "Reload Window") 4. Use exact trigger phrases or ask: "What skills do you have access to?"
Advanced Patterns
Chained Investigations
1. "Run threat pulse scan"
→ Identifies 3 high-risk users
2. "Investigate user1@domain.com for last 7 days"
→ Detects suspicious sign-in from 203.0.113.42
3. "Is this IP malicious? 203.0.113.42"
→ Confirms C2 infrastructure
4. "Hunt for this IP across all devices"
→ @sentinel-datalake query DeviceNetworkEventsAutomated Weekly Reports
# weekly_hunt.py
from datetime import datetime, timedelta
from report_generator import generate_investigation_report
# Query last 7 days
end_date = datetime.utcnow()
start_date = end_date - timedelta(days=7)
# Generate report for all high-risk users
high_risk_users = [...] # From Identity Protection
for user in high_risk_users:
generate_investigation_report(
user=user,
start_date=start_date,
end_date=end_date,
output_file=f"reports/{user}_{end_date.strftime('%Y%m%d')}.html"
)Custom Threat Intelligence Integration
# custom_ti_enrichment.py
import requests
import os
def custom_ti_lookup(ioc, ioc_type):
"""Integrate custom threat intel source"""
api_key = os.getenv('CUSTOM_TI_API_KEY')
response = requests.get(
f"https://custom-ti-api.com/v1/{ioc_type}/{ioc}",
headers={"Authorization": f"Bearer {api_key}"}
)
return response.json()
# Use in enrich_ips.py
from custom_ti_enrichment import custom_ti_lookup
enrichment['custom_ti'] = custom_ti_lookup(ip_address, 'ip')Resources
- Video Walkthrough: YouTube Demo
- Repository: https://github.com/SCStelz/security-investigator
- Issues: https://github.com/SCStelz/security-investigator/issues
- Copilot Instructions:
.github/copilot-instructions.md - KQL Query Library:
queries/directory - Skill Catalog:
.github/skills/directory (25 specialized skills)
Related skills
FAQ
Which Microsoft services does it investigate?
Sentinel log analytics, Defender XDR Advanced Hunting, Entra ID/Graph API and Azure Resource Manager via preconfigured MCP servers.
What threat intelligence sources does it enrich with?
AbuseIPDB, Shodan, IPInfo and vpnapi.io, plus Defender and Sentinel threat-intelligence tables.