OpsIdentity Operational Hygiene Skill
Improve OpsIdentity code to detect administrative disorder, architectural debt, and configuration drift in Active Directory environments.
"Not looking for Russian hackers. Looking for administrative chaos, poor architecture, and suboptimal configurations."
When to Use This Skill
Mission
This skill focuses on operational hygiene, not penetration testing:
| Focus Area |
What We Detect |
Impact |
| Architecture |
40+ trusts without justification |
Unnecessary complexity |
| Permissions |
100 accounts with Global Admin |
Audit difficulty |
| GPO |
Monolithic GPO with 200+ settings |
Slow logon, impossible debugging |
| Infrastructure |
8-hour replication latency |
Data inconsistency |
| Configuration |
AD Recycle Bin disabled |
No object recovery |
| Topology |
15 subnets not assigned to sites |
Clients authenticate to remote DC |
Stack Overview
- Frontend: React + TypeScript + Vite + TailwindCSS + shadcn/ui
- Backend: Node.js + Express + PostgreSQL
- Collection: PowerShell embedded in
client/src/pages/NewAssessment.tsx
- AI: Anthropic Claude (Opus 4.5 for complex, Sonnet 4.5 for standard)
- Anti-Hallucination: Smart Filtering + Grounding Validation + Deterministic Rules
Key Files
| File |
Purpose |
client/src/pages/NewAssessment.tsx |
PowerShell script (35+ Get-* functions) |
server/server.js |
AI prompts, Smart Filtering, Validation |
server/analyzers/userRules.js |
Deterministic rules (Users category) |
Workflow
Phase 1: Identify Coverage Gap
Check current coverage (37% of 87 metrics). Reference 📊 Coverage Matrix for:
- Missing metrics by category
- Priority level (Critical/High/Medium)
- Implementation complexity
Phase 2: Implement PowerShell Function
Add collection function in NewAssessment.tsx. All functions must follow anti-null pattern:
function Get-NewMetric {
$results = @() # Always initialize as empty array
try {
$items = @(Get-ADObject -Filter * -ErrorAction Stop) # Force array
foreach ($item in $items) {
try {
$obj = @{
Name = $item.Name
IsProblematic = $false
# Add detection logic
}
$results += $obj
} catch {
Write-Host "[!] Error processing $($item.Name): $_" -ForegroundColor Yellow
}
}
return @($results) # Always return array
} catch {
Write-Host "[!] CRITICAL: $_" -ForegroundColor Red
return @() # Never return null
}
}
Phase 3: Add Smart Filtering
Update filterCategoryData() in server.js to pre-filter problematic objects:
case 'NewCategory':
return data.filter(item =>
item.IsProblematic === true ||
item.RiskLevel === 'HIGH' ||
item.SpecificCondition > threshold
);
Phase 4: Create AI Prompt
Add category instructions in server.js. See 📝 Prompt Templates.
Phase 5: Add Validation Rules
Update ATTRIBUTE_VALIDATION_RULES to prevent hallucinations:
'NEW_FINDING_TYPE': {
category: 'NewCategory',
identifierField: 'Name',
validate: (obj) => obj.Condition === expectedValue
}
Phase 6: Increment Version
Update version in App.tsx after changes.
Critical Patterns
Anti-Null Guarantees
# ✅ CORRECT
$list = @() # Initialize empty
$items = @(Get-ADObject -Filter *) # Force array context
return @($list) # Always return array
# ❌ WRONG
$list = $null # Never initialize as null
return $items # May return null if empty
Finding Output Format
{
type_id: 'UPPERCASE_WITH_UNDERSCORES',
title: '[Count] + specific problem',
description: 'Current state + operational impact + compliance',
recommendation: 'Copy-paste ready commands',
affected_objects: ['REAL objects from JSON data']
}
What NOT to Do
- ❌ Focus on offensive security (Golden Ticket, lateral movement)
- ❌ Code without robust error handling
- ❌ Prompts that generate findings without real data
- ❌ Ignore anti-hallucination system
- ❌ Functions returning null instead of
@()
- ❌ Unnecessary complexity
Valid Improvements
- ✅ Detect GPOs with 50+ settings (monolithic)
- ✅ Identify subnets not associated to any AD site
- ✅ Calculate replication latency between all DCs
- ✅ Find empty groups or groups without defined manager
- ✅ Detect users with estimated token size > 12KB
- ✅ Identify trusts with password > 90 days without rotation
Reference Files
Load these as needed during development:
Quick Reference: 87 Industry Metrics
| Category |
Total |
Key Checks |
| Users |
12 |
PwdNeverExpires, Kerberoastable, Delegation, AdminSDHolder |
| Computers |
10 |
Obsolete OS, LAPS, Delegation, Password Age |
| Groups |
10 |
Tier0 size, Nesting depth, Empty, Token bloat |
| GPOs |
12 |
Unlinked, Monolithic, Version mismatch, cpassword |
| DCs |
14 |
FSMO, KRBTGT age, SMBv1, LDAP signing, Spooler |
| Replication |
8 |
Latency, Lingering objects, USN rollback |
| DNS |
8 |
Scavenging, Stale records, Zone security |
| DHCP |
6 |
Rogue servers, Exhaustion, Options 6/15 |
| Sites |
7 |
Orphaned subnets, Missing links, UGMC |
Current coverage: 37% → Target: 80%+
1---2name: ops-identity-hygiene3description: Active Directory operational hygiene analyzer for OpsIdentity project. Detects administrative disorder, architectural debt, and suboptimal configurations—not offensive security. Use when (1) improving OpsIdentity PowerShell collection functions, (2) adding AI analysis prompts to server.js, (3) analyzing coverage gaps against 87 industry metrics, (4) implementing smart filtering or anti-hallucination rules. Triggers on AD health, GPO analysis, replication, trusts, token size, FSMO, site topology, DNS/DHCP hygiene, or requests to analyze existing OpsIdentity code.4---5
6# OpsIdentity Operational Hygiene Skill
7
8Improve OpsIdentity code to detect **administrative disorder, architectural debt, and configuration drift** in Active Directory environments.
9
10> "Not looking for Russian hackers. Looking for administrative chaos, poor architecture, and suboptimal configurations."
11
12## When to Use This Skill
13
14| Trigger | Action |
15|---------|--------|
16| "Analyze OpsIdentity code coverage" | Load [🔍 Analyzer Prompt](./references/analyzer-prompt.md) |
17| "Add new AD metric" | Check [📊 Coverage Matrix](./references/coverage-matrix.md) first |
18| "Create PowerShell function" | Follow patterns in [⚙️ PowerShell Functions](./references/powershell-functions.md) |
19| "Add AI analysis prompt" | Use templates from [📝 Prompt Templates](./references/prompt-templates.md) |
20
21## Mission
22
23This skill focuses on **operational hygiene**, not penetration testing:
24
25| Focus Area | What We Detect | Impact |
26|------------|----------------|--------|
27| Architecture | 40+ trusts without justification | Unnecessary complexity |
28| Permissions | 100 accounts with Global Admin | Audit difficulty |
29| GPO | Monolithic GPO with 200+ settings | Slow logon, impossible debugging |
30| Infrastructure | 8-hour replication latency | Data inconsistency |
31| Configuration | AD Recycle Bin disabled | No object recovery |
32| Topology | 15 subnets not assigned to sites | Clients authenticate to remote DC |
33
34## Stack Overview
35
36- **Frontend**: React + TypeScript + Vite + TailwindCSS + shadcn/ui
37- **Backend**: Node.js + Express + PostgreSQL
38- **Collection**: PowerShell embedded in `client/src/pages/NewAssessment.tsx`
39- **AI**: Anthropic Claude (Opus 4.5 for complex, Sonnet 4.5 for standard)
40- **Anti-Hallucination**: Smart Filtering + Grounding Validation + Deterministic Rules
41
42## Key Files
43
44| File | Purpose |
45|------|---------|
46| `client/src/pages/NewAssessment.tsx` | PowerShell script (35+ Get-* functions) |
47| `server/server.js` | AI prompts, Smart Filtering, Validation |
48| `server/analyzers/userRules.js` | Deterministic rules (Users category) |
49
50---
51
52## Workflow
53
54### Phase 1: Identify Coverage Gap
55
56Check current coverage (37% of 87 metrics). Reference [📊 Coverage Matrix](./references/coverage-matrix.md) for:
57- Missing metrics by category
58- Priority level (Critical/High/Medium)
59- Implementation complexity
60
61### Phase 2: Implement PowerShell Function
62
63Add collection function in `NewAssessment.tsx`. **All functions must follow anti-null pattern:**
64
65```powershell
66function Get-NewMetric {
67 $results = @() # Always initialize as empty array
68
69 try {
70 $items = @(Get-ADObject -Filter * -ErrorAction Stop) # Force array
71
72 foreach ($item in $items) {
73 try {
74 $obj = @{
75 Name = $item.Name
76 IsProblematic = $false
77 # Add detection logic
78 }
79 $results += $obj
80 } catch {
81 Write-Host "[!] Error processing $($item.Name): $_" -ForegroundColor Yellow
82 }
83 }
84
85 return @($results) # Always return array
86 } catch {
87 Write-Host "[!] CRITICAL: $_" -ForegroundColor Red
88 return @() # Never return null
89 }
90}
91```
92
93### Phase 3: Add Smart Filtering
94
95Update `filterCategoryData()` in `server.js` to pre-filter problematic objects:
96
97```javascript
98case 'NewCategory':
99 return data.filter(item =>
100 item.IsProblematic === true ||
101 item.RiskLevel === 'HIGH' ||
102 item.SpecificCondition > threshold
103 );
104```
105
106### Phase 4: Create AI Prompt
107
108Add category instructions in `server.js`. See [📝 Prompt Templates](./references/prompt-templates.md).
109
110### Phase 5: Add Validation Rules
111
112Update `ATTRIBUTE_VALIDATION_RULES` to prevent hallucinations:
113
114```javascript
115'NEW_FINDING_TYPE': {
116 category: 'NewCategory',
117 identifierField: 'Name',
118 validate: (obj) => obj.Condition === expectedValue
119}
120```
121
122### Phase 6: Increment Version
123
124Update version in `App.tsx` after changes.
125
126---
127
128## Critical Patterns
129
130### Anti-Null Guarantees
131
132```powershell
133# ✅ CORRECT
134$list = @() # Initialize empty
135$items = @(Get-ADObject -Filter *) # Force array context
136return @($list) # Always return array
137
138# ❌ WRONG
139$list = $null # Never initialize as null
140return $items # May return null if empty
141```
142
143### Finding Output Format
144
145```javascript
146{
147 type_id: 'UPPERCASE_WITH_UNDERSCORES',
148 title: '[Count] + specific problem',
149 description: 'Current state + operational impact + compliance',
150 recommendation: 'Copy-paste ready commands',
151 affected_objects: ['REAL objects from JSON data']
152}
153```
154
155---
156
157## What NOT to Do
158
159- ❌ Focus on offensive security (Golden Ticket, lateral movement)
160- ❌ Code without robust error handling
161- ❌ Prompts that generate findings without real data
162- ❌ Ignore anti-hallucination system
163- ❌ Functions returning null instead of `@()`
164- ❌ Unnecessary complexity
165
166## Valid Improvements
167
168- ✅ Detect GPOs with 50+ settings (monolithic)
169- ✅ Identify subnets not associated to any AD site
170- ✅ Calculate replication latency between all DCs
171- ✅ Find empty groups or groups without defined manager
172- ✅ Detect users with estimated token size > 12KB
173- ✅ Identify trusts with password > 90 days without rotation
174
175---
176
177## Reference Files
178
179Load these as needed during development:
180
181- [🔍 Analyzer Prompt](./references/analyzer-prompt.md) - Full analysis prompt with 87 metrics baseline, output format, web search rules
182- [📊 Coverage Matrix](./references/coverage-matrix.md) - Current coverage status, gaps by category, sprint priorities
183- [📝 Prompt Templates](./references/prompt-templates.md) - AI prompt structure for new categories with examples
184- [⚙️ PowerShell Functions](./references/powershell-functions.md) - Ready-to-use function implementations
185
186---
187
188## Quick Reference: 87 Industry Metrics
189
190| Category | Total | Key Checks |
191|----------|-------|------------|
192| Users | 12 | PwdNeverExpires, Kerberoastable, Delegation, AdminSDHolder |
193| Computers | 10 | Obsolete OS, LAPS, Delegation, Password Age |
194| Groups | 10 | Tier0 size, Nesting depth, Empty, Token bloat |
195| GPOs | 12 | Unlinked, Monolithic, Version mismatch, cpassword |
196| DCs | 14 | FSMO, KRBTGT age, SMBv1, LDAP signing, Spooler |
197| Replication | 8 | Latency, Lingering objects, USN rollback |
198| DNS | 8 | Scavenging, Stale records, Zone security |
199| DHCP | 6 | Rogue servers, Exhaustion, Options 6/15 |
200| Sites | 7 | Orphaned subnets, Missing links, UGMC |
201
202**Current coverage: 37% → Target: 80%+**