Files
claudetools/clients/cascades-tucson/docs/migration/entra-connect-risk-register-2026-04-22.md
Howard Enos 5c6f7dca5e sync: auto-sync from HOWARD-HOME at 2026-04-22 21:40:31
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-04-22 21:40:31
2026-04-22 21:40:33 -07:00

379 lines
19 KiB
Markdown

# Entra Connect Install — Risk Register
**Built from:** G1 AD audit 2026-04-22 (`reports/2026-04-22-g1-ad-audit.md`) + post-reboot readiness check (`reports/2026-04-22-cs-server-entra-readiness-post-reboot.md`) + HIPAA review (`docs/security/hipaa-review-2026-04-22.md`)
**Purpose:** Know every possible failure mode before Gate G1 executes. Each risk has: probability, impact, what the audit proved, mitigation, detection, rollback.
## Executive summary
The audit turned up **several encouraging confirmations** and a **manageable set of genuine risks**. None are install-blockers. The biggest real concern is password hygiene (Gate G5), which our plan already handles via directory-sync-only initial posture.
### Already GOOD (no remediation needed)
- Forest 2016 / Domain 2016 / Schema 88 — supports modern Connect
- `cascadestucson.com` UPN suffix already configured forest-wide
- AD Recycle Bin enabled (can undo bad renames)
- No MSOL_* accounts — clean install target
- `dcdiag` silent (all tests pass)
- Time sync stratum 2 / time.nist.gov (confirmed post-reboot)
- All 3 critical Microsoft sync endpoints resolve
- Department OU structure exists (`OU=Departments\OU=Administrative`, etc.)
- `OU=ServiceAccounts` exists
- `OU=Workstations\OU=Staff PCs` + `OU=Shared PCs` already structured
- **UPN prefixes match the M365 format for 95% of users** — the pre-audit-assumed mismatches have already been cleaned up:
- `Tamra.Matthews` in AD matches `tamra.matthews@` in M365 (rename already done)
- `Shelby.Trozzi` in AD matches `Shelby.Trozzi@` in M365 (rename already done)
- `Alyssa.Brooks` in AD matches `alyssa.brooks@` in M365
- `Christopher.Holick` in AD matches `christopher.holick@` in M365 (typo fix already done)
---
## Risk register
### CRITICAL — must fix before Gate G3 (staging-mode install)
---
#### R1. Sync-scope drift: `CN=Users` + role accounts would be synced by default
**Probability:** Certain | **Impact:** High
**What the audit showed:**
- **8 accounts in `CN=Users`** (default container, not an OU):
`Administrator`, `directoryshare`, `Guest`, `krbtgt`, `localadmin`, `QBDataServiceUser34`, `Receptionist`, `sysadmin`
- **4 role-based accounts** in departmental OUs with `@cascades.local` UPN suffix:
`Culinary` (in `OU=Culinary`), `Receptionist` (in `CN=Users`), `saleshare` (in `OU=Marketing`), `directoryshare` (in `CN=Users`)
**Why it matters:** Default Entra Connect scope is "all users". Without filter rules, these synthetic / service / shared-credential accounts sync to Entra and either (a) consume licenses, (b) get blocked by the verified-domain check since `@cascades.local` isn't a tenant domain, or (c) muddy the HIPAA-compliance story with shared-login objects now in the cloud identity plane.
**Mitigation:**
- Configure Entra Connect **OU-scoped filtering**: include only `OU=Departments` (real staff) + optionally `OU=ServiceAccounts`. Exclude `CN=Users` entirely.
- **Before install**, create `OU=Excluded-From-Sync,DC=cascades,DC=local` and move the 4 role-based accounts there so they're scoped out cleanly.
- Alternative: attribute-based filter on `extensionAttribute1` set to "NoSync" — more flexible long-term.
**Detection:** Staging-mode preview will list exactly which accounts would sync. Review before exit-staging.
**Rollback if missed:** Remove from sync scope, re-run sync, Entra deletes the synced objects.
---
#### R2. 13 enabled users have **null `PasswordLastSet`** — sign-in would fail after PHS turns on
**Probability:** Certain for these users | **Impact:** High (key staff locked out)
**What the audit showed:**
| SAM | whenCreated | Role |
|---|---|---|
| Meredith.Kuhn | 2024-08-28 | Executive Director |
| John.Trozzi | 2024-08-28 | Facilities Director |
| Megan.Hiatt | 2024-08-28 | Sales Director |
| Tamra.Matthews | 2024-08-28 | Move-In Coordinator |
| Christine.Nyanzunda | 2024-08-28 | MC Admin / MedTech |
| Ashley.Jensen | 2024-08-28 | Assistant Executive Director |
| Veronica.Feller | 2024-08-28 | AL Aide |
| Sebastian.Leon | 2024-08-28 | Courtesy Patrol |
| JD.Martin | 2024-08-28 | Culinary Director |
| Matt.Brooks | 2024-08-28 | MC Receptionist / Maintenance |
| Ramon.Castaneda | 2024-08-28 | Kitchen Manager |
| Michelle.Shestko | 2024-08-28 | MC Receptionist |
| britney.thompson | 2025-06-12 | *(departed 2026-04-22)* |
All have `PasswordLastSet = NULL` — AD account created but never had a password set. Last-logon is also `never` for all of them. They've never signed into Windows; they only use M365 with cloud-managed passwords.
**Why it matters:** If we enable **Password Hash Sync (Gate G5)**, Entra Connect typically pushes the AD hash to overwrite the cloud password. For null-hash users, Microsoft's behavior:
- Password Hash Sync **does not** overwrite cloud password with "empty" — the cloud password persists.
- BUT: these users have no AD password, so Windows sign-in never worked for them anyway — not a change.
- The real risk: if we *ever* enable "hybrid" features (password writeback, etc.) and later set a placeholder AD password, we'd silently break their cloud sign-in.
**Mitigation (staged):**
1. **Gate G4 (directory sync only, no PHS)** — safe for these users. They keep signing into M365 with their current cloud password.
2. **Before Gate G5 (PHS enablement)** — decision point per user:
- (a) Set real AD password, tell user "from now on your M365 password is [X]" — but MOST won't want to change their M365 password. Disruptive.
- (b) Leave null, don't enable PHS for them — requires excluding them from PHS scope (per-user filter).
- (c) **Preferred: don't enable PHS at all; stay on directory-sync-only permanently.** Users keep their cloud passwords; their AD accounts are just there for group membership + OU governance. This trades the "single password" benefit for zero risk to currently-working sign-in.
**Detection:** Track sign-in failures per user in Entra sign-in logs after any PHS change.
**Rollback:** Disable PHS in Entra Connect — cloud passwords stop being overwritten on next sync.
---
#### R3. Matt.Brooks UPN mismatch — AD `Matt.Brooks` vs M365 `matthew.brooks@`
**Probability:** Certain | **Impact:** Medium (one duplicate user)
**What the audit showed:**
- AD: `SAM=Matt.Brooks`, `UPN=Matt.Brooks@cascadestucson.com`
- M365 (per `docs/cloud/m365.md` line 59): `matthew.brooks@cascadestucson.com`
**Why it matters:** Soft-match uses UPN + proxyAddresses. AD UPN `Matt.Brooks@` doesn't match M365 UPN `matthew.brooks@`. With no `proxyAddresses` on the AD user (see R4), the engine has no fallback. Will likely **create a duplicate Entra user** for Matt.
**Mitigation (pick one, before staging):**
- (a) Change AD UPN from `Matt.Brooks@``matthew.brooks@` (preferred — keeps M365 mailbox stable)
- (b) Change M365 UPN from `matthew.brooks@``matt.brooks@` (disrupts Matt's cached Outlook / Teams sessions, one-time prompt)
**Detection:** Staging-mode preview report will flag this as "would create new user" instead of "would match existing".
**Rollback:** If we miss it and dupe gets created, use Entra portal to soft-delete the duplicate + hard-match manually.
---
#### R4. No users have `mail` or `proxyAddresses` populated in AD
**Probability:** Certain (all 42 enabled users affected) | **Impact:** Medium (single point of failure for soft-match)
**What the audit showed:** **Every single AD user** has empty `mail` and empty `proxyAddresses`. Soft-match relies on:
1. `proxyAddresses` (SMTP: prefix) — primary
2. UPN — fallback
With no proxyAddresses, we rely on UPN matching, which is case-insensitive but format-exact. Anything off by even a character creates a duplicate.
**Why it matters:** Combined with R3 (Matt's UPN mismatch), we're one typo away from duplicates. Also, when M365 mailboxes have aliases (e.g., `cara.lespron@` on Howard's mailbox, `tamra.johnson@` alias on Tamra's, `ashley.jenson@` typo alias on Ashley's), those ONLY match via proxyAddresses — not UPN. The aliases would orphan.
**Mitigation:**
- **Before staging install**, script a bulk update to populate each AD user's `proxyAddresses` from their M365 SMTP addresses. Takes ~30 min to write + run. See G1 remediation script (draft pending).
- `mail` attribute can be set to the primary SMTP — feeds Outlook profile defaults.
**Detection:** Staging preview shows match source per user (UPN vs SMTP). Review before exit.
**Rollback:** AD attribute changes are reversible via another script.
---
### HIGH — should fix before Gate G3, or early during G3 review
---
#### R5. Missing security groups (all 16 `SG-*` groups our CA design assumes)
**Probability:** Certain | **Impact:** High (CA policies can't target non-existent groups)
**What the audit showed:** Zero of the 16 planned `SG-*` groups exist in AD:
`SG-External-Signin-Allowed`, `SG-Caregivers`, `SG-FrontDesk`, `SG-CourtesyPatrol`, `SG-Drivers`, `SG-Management-RW`, `SG-Sales-RW`, `SG-Culinary-RW`, `SG-IT-RW`, `SG-Receptionist-RW`, `SG-Directory-RW`, `SG-Server-RW`, `SG-Chat-RW`, `SG-Office-PHI-External`, `SG-Office-PHI-Internal`, `SG-CA-BreakGlass`.
**Why it matters:** Gate G6 (CA Report-Only) needs these groups to exist and be populated before policies can target them. Can't target empty groups.
**Mitigation:** Script creation of all 16 groups under `OU=Groups,DC=cascades,DC=local` (already exists — audit shows 1 group in it) BEFORE Gate G6. Populate membership from the rollout plan's persona tables.
**Detection:** CA policy assignment wizard in Entra portal will show "group not found" if we target before creating.
**Rollback:** `Remove-ADGroup` — safe.
---
#### R6. M365-side orphan accounts need cleanup before sync
**Probability:** Certain | **Impact:** Medium (post-sync confusion)
**Accounts to resolve (per `docs/cloud/m365.md`):**
| M365 UPN | Status | Action before sync |
|---|---|---|
| `kristiana.dowse@cascadestucson.com` | HR confirmed not current employee | Delete from M365 |
| `howaed@azcomputerguru.com` | Typo duplicate of `howard@` | Delete from M365 |
| `nick.pavloff@cascadestucson.com` | Created 2026-03-07, no AD account | **Decide: create AD account or delete M365 account.** If kept cloud-only, exclude from sync-expected list. |
| `anna.pitzlin@cascadestucson.com` | Former employee, forwarded to Meredith | Already blocked — delete if HR confirms |
| `nela.durut-azizi@cascadestucson.com` | Former employee | Already blocked — delete if HR confirms |
| `jeff.bristol@cascadestucson.com` | Former employee | Already blocked — decision to delete vs keep for mail history |
| `stephanie.devin@cascadestucson.com` | Former? | Verify with Meredith |
| `admin@NETORGFT4257522.onmicrosoft.com` | Sandra Fish (blocked 2026-04-14) | Delete |
**Why it matters:** Post-sync, mismatched AD-vs-M365 state creates orphan objects that muddy audit logs and risk accidental reactivation.
**Mitigation:** Clean up M365 side in Gate G2 (role-account-to-shared-mailbox conversion phase). Delete / block / convert each per the table above.
**Detection:** M365 admin portal user list before/after. Entra staging preview will flag M365 users with no AD counterpart.
---
#### R7. Role-based account UPNs use unverified domain `@cascades.local`
**Probability:** Certain | **Impact:** Low (these shouldn't sync anyway)
**What the audit showed:**
- `Culinary@cascades.local`
- `Receptionist@cascades.local`
- `directoryshare@cascades.local`
**Why it matters:** If these sync, Entra tries to create users with UPNs in a domain that isn't verified on the tenant. Sync will fail for these objects specifically with a clear error. Not a tenant-wide failure.
**Mitigation:** These accounts are explicitly excluded by R1's OU scoping. Confirmed via dual filter.
**Detection:** Staging preview shows sync-blocked objects.
**Rollback:** N/A — sync failure is self-protecting.
---
#### R8. No Entra Connect service account exists yet
**Probability:** N/A — create at install | **Impact:** High (blocks install)
**What the audit showed:** Nothing in `OU=ServiceAccounts` matches "MSOL_*", "AADSync*", or similar patterns. The only service account there is `svc-audit-upload` (Syncro-specific).
**Why it matters:** Entra Connect install creates an MSOL_* AD account automatically during install. But best practice: pre-provision a dedicated service account in `OU=ServiceAccounts` with explicit delegated permissions (AD replication rights + BUILTIN\Users read).
**Mitigation:** Installer will create `MSOL_<hex>` automatically on install — acceptable. Alternative: pre-create `svc-entra-connect` with delegated rights using Microsoft's `Set-ADSyncPermissions` cmdlet.
**Detection:** Post-install, verify the service account appears in AD and has correct delegated rights.
**Rollback:** Uninstall Connect removes the auto-created service account.
---
#### R9. `krbtgt` password is 602 days old
**Probability:** Not a Connect issue | **Impact:** Low (for Connect), High (for AD security)
**What the audit showed:** `krbtgt` password last set 2024-08-28, age 602 days.
**Why it matters:** Not an Entra Connect concern. But this is a pre-existing HIPAA / AD security finding (audit gap #20 in hipaa.md). Standard best practice is 180-day rotation.
**Mitigation:** Run `Reset-KrbTgt-Password.ps1` script (MS-published) — two iterations ~24 hours apart. Do this OUTSIDE the Entra Connect window to avoid changing two things at once.
**Detection:** Event Log shows TGT-related errors if done wrong.
**Rollback:** Can't rollback a krbtgt reset, but two rotations clear any old TGTs cleanly.
---
### MEDIUM — can fix during or after G4 (directory sync active)
---
#### R10. DisplayName inconsistencies (will propagate to Entra)
**What the audit showed:**
- `Crystal.Rodriguez` display name = `'Crystal Rodriguez'` (two spaces)
- `howard` display name = `'howard'` (should be `Howard Dax` per GivenName+Surname)
- `Cathy.Kingston` display name = `'Cathy.Kingston'` (SAM-like, should be `Cathy Kingston`)
**Why it matters:** These propagate to Entra / M365 directory, address book, Teams people cards. Cosmetic but visible.
**Mitigation:** Fix during Gate G4 or post-sync — reversible. Set correct DisplayName on each.
**Detection:** M365 People / address book reflects the bad names.
---
#### R11. 10 enabled accounts with `PasswordNeverExpires=True`
**What the audit showed:**
| SAM | Risk | Action |
|---|---|---|
| Administrator | Normal for built-in | Leave |
| localadmin | Normal for emergency local | Leave |
| sysadmin | Normal for MSP service | Leave |
| QBDataServiceUser34 | Service account | Leave (won't sync) |
| howard | Should rotate | Address separately |
| Culinary | Should be Phase 5 cleaned up | Leave, out of scope |
| Receptionist | Same | Leave, out of scope |
| directoryshare | Same | Leave, out of scope |
| Lois.Lane | Exception on purpose? | **Investigate** |
| Shelby.Trozzi | Exception on purpose? | **Investigate** |
| svc-audit-upload | Service account | Correct |
**Why it matters:** Not a Connect blocker, but HIPAA password-policy audit finding. Lois + Shelby flagged to rotate.
**Mitigation:** Post-install, enforce AD password policy + flip their `PasswordNeverExpires` off.
---
#### R12. 28 staff users show `lastLogon = never`
**What the audit showed:** 28 enabled accounts have no recorded logon history — they've never signed into Windows. Consistent with the null-PasswordLastSet finding — these are cloud-primary users who've never touched a domain-joined PC.
**Why it matters:** Entra Connect doesn't care. Just confirming this is consistent with our mental model: Cascades has long operated as "AD for mail + group membership" but users actually authenticate to M365 cloud-only. Not broken, just noteworthy.
**Mitigation:** None needed. Our Gate G4 directory-sync-only posture accepts this reality.
---
#### R13. 8 domain computers — known set, no surprises
**What the audit showed:**
| Computer | OS | Last Logon |
|---|---|---|
| CS-SERVER | Server 2019 | 2026-04-22 |
| ACCT2-PC | Win 11 Pro WS | 2026-04-22 |
| CRYSTAL-PC | Win 11 Pro | 2026-04-16 |
| DESKTOP-DLTAGOI | Win 11 Pro WS | 2026-04-13 (Sharon Edwards, our FR pilot) |
| DESKTOP-H6QHRR7 | Win 11 Pro WS | 2026-04-13 |
| DESKTOP-ROK7VNM | Win 11 Pro WS | 2026-04-13 (Susan Hicks) |
| CS-QB | Win 10 Pro | 2026-04-16 (VoIP VM on CS-SERVER) |
| DESKTOP-1ISF081 | Win 10 Pro | 2025-03-22 (stale — 13 months no logon) |
**Why it matters:** Sync default includes computer accounts. For hybrid join, that's desired. For our scope (just user identity), exclude computers from sync.
**Mitigation:** Set Entra Connect sync-scope filter to `Users` + `Groups` only initially. Add computers later when hybrid join is a real goal.
**Action item:** Investigate `DESKTOP-1ISF081` — 13 months no logon, likely retired. Disable if confirmed.
---
### LOW — track but not blocking
---
#### R14. 9 deleted objects in AD Recycle Bin from prior cleanup
All former employees. Recycle Bin keeps them 180 days for recovery. Not a Connect concern.
---
#### R15. Disabled accounts that still exist
Only 2 per audit: `Guest` (built-in) and `krbtgt` (disabled/system). Both excluded from sync automatically.
---
#### R16. Missing mail infrastructure attributes
**What the audit showed:** No users have `msExchMailboxGuid`, `msExchRecipientDisplayType`, or other Exchange schema attributes populated in AD.
**Why it matters:** Would matter for Exchange Hybrid (on-prem Exchange coexistence). Not relevant for cloud-only Exchange Online.
**Mitigation:** None needed for our scope.
---
## Install-day go/no-go checklist
All must be satisfied before exiting Gate G3 (staging mode):
- [ ] `OU=Excluded-From-Sync` created; role accounts moved there (R1)
- [ ] `proxyAddresses` populated for all real staff from M365 SMTP (R4)
- [ ] Matt.Brooks UPN unified between AD and M365 (R3)
- [ ] M365 orphans resolved: Kristiana, howaed, Sandra Fish admin, nick.pavloff (R6)
- [ ] Role-based M365 accounts converted to shared mailboxes (accounting@, frontdesk@, etc.) (Gate G2)
- [ ] Sync-scope filter set to `OU=Departments` only, user+group objects only (R1, R13)
- [ ] 16 `SG-*` security groups pre-created and populated (R5)
- [ ] Break-glass admin account created + vaulted (independent of Connect, but gate G7 needs it)
- [ ] Microsoft BAA signed (Wave 0 — independent of Connect but HIPAA-critical)
## Items that can wait until after G4
- Fix DisplayName inconsistencies (R10)
- Rotate krbtgt (R9) — schedule OUTSIDE the Connect window
- Clean up PasswordNeverExpires exceptions on Lois + Shelby (R11)
- Disable DESKTOP-1ISF081 stale computer account (R13)
## Rollback summary per gate
| Gate | Rollback |
|---|---|
| G1 | AD changes (renames, attribute populates) reversible via recorded before-state |
| G2 | Shared-mailbox conversion reversible (undo from Exchange Admin) |
| G3 | Uninstall Connect; tenant stays unchanged (staging mode never wrote) |
| G4 | Uninstall Connect; run `Set-MsolDirSyncEnabled -EnableDirSync $false` to stop tenant-side sync (takes ~72h to fully disable) |
| G5 | Disable PHS via Entra Connect config; cloud passwords stop being overwritten |
| G6 | Delete CA policies; no sign-ins were being blocked anyway |
| G7 | Flip each CA policy back to Report-only |
| G8 | Remove ALIS Enterprise App registration; ALIS users revert to local credentials |
---
*Full G1 audit source data: `reports/2026-04-22-g1-ad-audit.md`*