---
name: identity-compromise-check
description: >
  Investigate whether a specific user account or identity may be compromised, using Polarity's
  identity, breach, and EDR integrations. Use this skill whenever a user gives a username, email
  address, or employee name and asks "is this account compromised", "check this user", "did
  this account get breached", "investigate this login", or pastes anomalous sign-in activity
  (impossible travel, new device, MFA fatigue) tied to a specific person. Also trigger when a
  user pastes a suspicious authentication log line referencing a specific account. Do not use for
  bulk/organization-wide identity audits with no specific account named — for those, treat as a
  broader investigation and ask which accounts to focus on.
---

# Identity Compromise Check Skill

Builds a single-account "is this person compromised" picture by fanning a username or email out
across identity providers, breach data, and endpoint/network context.

---

## Workflow Overview

```
1. Normalize identity  →  2. Check breach/reputation exposure  →  3. Check directory & sign-in state
   →  4. Check endpoint/network corroboration  →  5. Correlate  →  6. Render verdict
```

---

## Step 1 — Normalize Identity

Extract the email address and/or username with `polarity:parse_entities`. If only a name is given,
ask the user for the corresponding email/username — Polarity integrations key off entities, not
free-text names.

---

## Step 2 — Check Breach & Reputation Exposure

| Source | ID | What it adds |
|---|---|---|
| Have I Been Pwned | `haveibeenpwnd_3_2_0_node_18_e72f988cf7_1721826241` | Which breaches this email appeared in, and when |
| EmailRep | `emailrep` | Reputation, suspicious/malicious flags, credential-leak signals |
| OORT | `oort_3_0_1_node_18_4db23a23e2_1714631399` | Identity risk correlation by email/IP |

---

## Step 3 — Check Directory & Sign-In State

| Source | ID | What it adds |
|---|---|---|
| Okta | `okta_3_0_11_node_18_815368fef1_1743269873` | Account status, group membership, recent activity |
| Microsoft Entra ID | `microsoft_entra_id_3_0_0_node_18_9f3c7c025d_1779802234180` | Sign-in logs, risky sign-in flags, licenses, MFA state |
| LDAP | `ldap_3_5_6_node_18_3a46180e18_1698417167` | Directory record, group membership (on-prem AD) |

Flag directly: impossible travel (two sign-ins from geographically incompatible locations in a
short window), a new/unrecognized device, or a sign-in immediately following an MFA-fatigue burst.

---

## Step 4 — Check Endpoint & Network Corroboration

| Source | ID | What it adds |
|---|---|---|
| CrowdStrike EDR | `crowdstrike` or `crowdstrike_3_7_4_node_18_33726b1dc9_1751971059359` | Detections on the user's assigned device around the same time window |
| IP2User (DHCP) | `polarity_chameleon_3_0_0_node_18_1727117038` | Which IP the user's device actually held at the time |
| IP2User (Splunk) | `splunk_3_6_4_node_18_27043de191_1727064799` | Splunk-based cross-check of the same |
| ipinfo / GreyNoise / AbuseIPDB | `ipinfo`, `greynoise`, `abuseipdb` | Whether the sign-in source IP itself is known-malicious infrastructure |

---

## Step 5 — Correlate

- Does the sign-in source IP match the user's known/expected location and device history?
- Is there a breach hit that pre-dates the suspicious activity by a plausible credential-reuse window?
- Does Entra ID / Okta already flag this sign-in as risky, or is this the first signal?
- Is there an EDR detection on the assigned device that corroborates account takeover vs. a false
  alarm (e.g., VPN change, travel, new phone)?

---

## Step 6 — Render Verdict

Score 0–100 using the same factors as general triage, weighted for identity:

| Factor | Points |
|---|---|
| Entra ID/Okta already flags sign-in as risky | +25 |
| Impossible travel or new-device + no known travel | +20 |
| Email found in a recent (< 12 months) breach | +15 |
| EDR detection on assigned device in the same window | +20 |
| Source IP flagged malicious (AbuseIPDB/GreyNoise) | +10 |
| MFA fatigue pattern (repeated push prompts before success) | +10 |

Deductions: known travel on file (-15), source IP matches user's normal ASN/location (-15),
breach hit is old (>2 years) with a confirmed password rotation since (-10).

Render via `visualize:show_widget`:
1. **Header** — user identity, verdict badge, score
2. **Identity timeline** — sign-ins, breach hits, EDR detections plotted chronologically
3. **Risk factor table** — factor | evidence | points
4. **Recommended actions** — force password reset, revoke sessions, isolate device — with time
   horizon badges. Note: Claude does not execute account lockout or session revocation itself;
   these are recommendations for the analyst or SOAR playbook to action.
5. **Footer** — sources queried, data freshness

### Visual Design Rules (all reports)

Follow the claude.ai design system exactly:

- **No hardcoded hex colors.** Use only CSS variables: `--color-background-primary/secondary/tertiary`,
  `--color-text-primary/secondary/tertiary`, `--color-border-tertiary/secondary`,
  `--color-background-danger/warning/info/success`, `--color-text-danger/warning/info/success`.
- **Dark mode mandatory** — every element must be readable on a near-black background.
- Font sizes: section labels 11–12px uppercase tracking, body 13–14px, metric numbers 20–24px.
  Font weights: 400 body, 500 headings/labels only. Never 600 or 700.
- Cards: `background: var(--color-background-primary); border: 0.5px solid var(--color-border-tertiary);
  border-radius: 12px; padding: 1rem 1.25rem`.
- Badges: `display: inline-block; padding: 4px 12px; border-radius: 6px; font-size: 12px; font-weight: 500`
  using semantic CSS vars for bg + text.
- Section separators: `border-top: 0.5px solid var(--color-border-tertiary)`.
- Tabler outline icons only (`<i class="ti ti-NAME" aria-hidden="true">`). Never filled variants.
- Sentence case everywhere. No ALL CAPS section titles.
- No gradients, drop shadows, blur, or glow effects.
- Score/meter bars: plain `<div>` with width `${value}%`, no canvas or chart libraries.
- Always render via `visualize:show_widget` (HTML mode). Call `visualize:read_me` with
  `modules: ["mockup"]` first if not already done this session. One line of prose before the
  widget call, nothing after except an offer to drill into any section.

---

## Handling Edge Cases

**Service account, not a person**: Skip breach/HIBP checks (not meaningful for non-human
identities); focus on Okta/Entra sign-in anomalies and EDR/network corroboration only.

**No EDR/network data available**: Say so explicitly — a verdict based on identity-provider
signals alone is lower confidence and should be stated as such in the report.

**User confirms it was them (e.g., "I was traveling")**: Don't retroactively force a low score —
note the explanation, but still flag if the source IP independently resolves to known-malicious
infrastructure, since a legitimate explanation for travel doesn't rule out a compromised device.

**Only a username without domain context**: Ask which identity provider (Okta/Entra/LDAP) the
account lives in before querying — usernames aren't unique across providers.
