diff --git a/.planning/research/SUMMARY.md b/.planning/research/SUMMARY.md index f8043d6..c728532 100644 --- a/.planning/research/SUMMARY.md +++ b/.planning/research/SUMMARY.md @@ -508,7 +508,55 @@ Based on the combined research, the dependency graph from ARCHITECTURE.md and FE - ManageEngine SharePoint Manager Plus — https://www.manageengine.com/sharepoint-management-reporting/sharepoint-permission-auditing-tool.html - AdminDroid SharePoint Online auditing — https://admindroid.com/microsoft-365-sharepoint-online-auditing +--- + +## v2.3 Tenant Management & Report Enhancements + +**Researched:** 2026-04-09 +**Confidence:** HIGH + +### Stack Additions + +**None.** All five features are delivered using existing dependencies: +- `Microsoft.Graph` 5.74.0 — app registration, service principal, admin consent, group member resolution +- `PnP.Framework` 1.18.0 — `Tenant.SetSiteAdmin` for auto-ownership +- BCL .NET 10 — LINQ consolidation, HTML5 `
/` + +Do NOT add `Azure.Identity` — conflicts with existing MSAL PCA + MsalCacheHelper pattern. + +### Feature Table Stakes + +| Feature | Table Stakes | Differentiators | +|---------|-------------|-----------------| +| App Registration | Create app + SP + grant roles; guided fallback mandatory | Auto-detect admin permissions, single-click register | +| App Removal | Delete app + SP, revoke consent | Clear MSAL cache for removed app | +| Auto-Ownership | `Tenant.SetSiteAdmin` on access denied; global toggle OFF by default | Persistent cleanup list, startup warning for pending removals | +| Group Expansion | Resolve members at scan time; HTML5 details/summary | `transitiveMembers` for nested groups; pagination for large groups | +| Report Consolidation | Toggle per-export; merge same-user same-access rows | New `ConsolidatedUserAccessEntry` type (never modify existing) | + +### Critical Pitfalls + +1. **App registration requires `Application.ReadWrite.All` + `AppRoleAssignment.ReadWrite.All`** — MSP app likely doesn't have these consented. Guided fallback is first-class, not a degraded mode. +2. **`POST /applications` does NOT create service principal** — Must be 3-step atomic: create app → create SP → grant roles, with rollback on failure. +3. **Auto-ownership cleanup** — `try/finally` insufficient for hard termination. Need persistent JSON cleanup-pending list + startup warning. +4. **`$expand=members` caps at ~20 silently** — Must use `GET /groups/{id}/transitiveMembers?$top=999` with pagination. +5. **Consolidation is a schema change** — Must be off by default, opt-in per export. + +### Suggested Build Order (5 phases, starting at 15) + +1. **Phase 15** — Model extensions + PermissionConsolidator (zero API calls, data shapes) +2. **Phase 16** — Report consolidation toggle (first user-visible, pure LINQ) +3. **Phase 17** — Group expansion in HTML reports (Graph at export time, HTML5 details/summary) +4. **Phase 18** — Auto-take ownership (PnP Tenant.SetSiteAdmin, retry once, default OFF) +5. **Phase 19** — App registration + removal (highest blast radius, Entra changes, guided fallback default) + +### Research Flags + +- **Phase 19:** Admin consent grant appRole GUIDs need validation against real tenant +- **Phase 17:** Confirm `GroupMember.Read.All` scope availability on MSP app registration + --- *v1.0 research completed: 2026-04-02* *v2.2 research synthesized: 2026-04-08* +*v2.3 research synthesized: 2026-04-09* *Ready for roadmap: yes*