Thread 1 (AD-side prep on CS-SERVER) completed:
- howard.enos password reset to memorable value (PHS will sync to M365 once staging exits)
- proxyAddresses=SMTP:howard.enos@cascadestucson.com added (G1 convention)
Thread 2 (CA reconciliation) blocked: ComputerGuru - Tenant Admin SP
(appId 709e6eed-...) has zero directory role assignments in Cascades.
Graph CA endpoints 403 despite Policy.ReadWrite.ConditionalAccess on token.
Decision pending: Path A (Graph-side role assignment via existing
RoleManagement.ReadWrite.Directory) vs Path B (portal click as admin@).
Target role: Conditional Access Administrator
(b1be1c3e-b65d-4f19-8427-f6fa0d97feb9) on SP objectId
a5fa89a9-b735-4e10-b664-f042e265d137.
Follow-up: extend onboard-tenant.sh to assign this role at onboard time
(parallels 16f95e8 Exchange Admin fix for Exchange Operator SP).
Pilot target slipped 2026-04-27 to 2026-04-28. ALIS App Store still
inaccessible — install-side of ALIS SSO still deferred regardless.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
12 KiB
2026-04-28 — Cascades CA reconciliation blocked on SP directory role; AD-side pilot prep done
User
- User: Howard Enos (howard)
- Machine: Howard-Home
- Role: tech
- Session span: 2026-04-28 morning (short save-point session, picking up from 2026-04-25 pause)
Resume point (READ THIS FIRST when picking back up)
We are mid-Track-A-Gate-2 / CA reconciliation. Thread 1 (AD-side prep) is done. Thread 2 (CA portal/Graph reconciliation) is blocked on a directory-role gap on the Tenant Admin SP in Cascades — Howard needs to choose Path A or Path B before we proceed.
Original pilot target was Monday 2026-04-27 — slipped one day, now in flight on 2026-04-28.
Decision pending from Howard
The ComputerGuru - Tenant Admin SP (appId 709e6eed-0711-4875-9c44-2d3518c47063) has zero directory role assignments in the Cascades tenant. Its Graph token carries Policy.ReadWrite.ConditionalAccess, but Microsoft Graph also requires the SP itself to hold a directory role (Conditional Access Admin / Security Admin / Global Reader) for CA endpoints. All /identity/conditionalAccess/* and /policies/conditionalAccessPolicies calls return AccessDenied.
Two paths offered to Howard:
- Path A (recommended): Assign
Conditional Access Administrator(role template idb1be1c3e-b65d-4f19-8427-f6fa0d97feb9) to the Tenant Admin SP via Graph. Token hasRoleManagement.ReadWrite.Directory— should work app-only without elevation. After it lands, also patch.claude/skills/remediation-tool/scripts/onboard-tenant.shso future tenants get this assignment automatically (parallels the Exchange Admin → Exchange Operator fix Mike committed in16f95e8). - Path B: Howard adds the role manually in the Cascades Entra portal as
admin@cascadestucson.com: Roles & administrators → Conditional Access Administrator → Add assignments → "ComputerGuru - Tenant Admin". Faster, no programmatic role-management on our side.
Sequence after the role assignment lands
- CA reconciliation read-side — pull existing
CascadesNamed Location object (currently72.211.21.217/32only, per 4/25 portal review) and the existingRequire multifactor authentication for all userspolicy state (Report-only / On / Off). - CA reconciliation write-side — PATCH the
CascadesNamed Location to add184.191.143.62/32. Decide whether to add a single caregiver-specific compliant-device policy targetinghoward.enos@cascadestucson.comUPN (Report-only) or rely on existing all-users MFA policy. - Gate A3 partial — Entra App Registration for ALIS SSO. Howard creates in Entra portal (or via Graph), captures Directory ID + App ID + Client Secret. Vault them. ALIS-side install of the SSO app is still blocked on ALIS App Store update.
- Gate A5 — exit Entra Connect staging. Howard runs on CS-SERVER:
Then verify howard.enos lands in M365 as hybrid user, assign Entra ID P2 license (unassigned seat available from Sandra Fish cleanup).
Set-ADSyncScheduler -SyncCycleEnabled $true # if needed # Remove staging mode via the Entra Connect wizard (Configure → Configure staging mode → uncheck) Start-ADSyncSyncCycle -PolicyType Initial - Gate A6 — phone enrollment. QR from
CSC - Android Shared Phonesprofile → sign in as howard.enos → verify no MFA prompt on Cascades Wi-Fi → Authenticator/Teams sign-in flow. ALIS sign-in flow can't be tested until ALIS App Store comes back and the SSO app is installed there. - Gate A7 — flip CA from Report-only to On.
Session Summary
Picked up from the 4/25 save point. Howard ran Thread 1 (AD-side prep on CS-SERVER) successfully — howard.enos now has the proxyAddresses SMTP entry set and the password was reset to a memorable value while still in staging mode (so PHS will sync the real password to M365 instead of the random temp once we exit staging). I attempted Thread 2 (CA reconciliation read-side) via the Tenant Admin SP and discovered the SP has no directory roles assigned in the Cascades tenant, blocking all Conditional Access endpoints. Two unblock paths surfaced; awaiting Howard's pick. ALIS App Store still inaccessible.
Key Decisions
- Pre-stage password reset before exiting staging. Howard reset
howard.enosAD password to a memorable value while Entra Connect is still in staging mode. Rationale: PHS will overwrite any cloud password once staging exits, so setting the AD password first ensures the real password is what lands in M365 — not the random temp generated at account creation. - proxyAddresses convention applied. Added
SMTP:howard.enos@cascadestucson.comto match the G1 convention. Confirmed viaGet-ADUser -Properties proxyAddresses,memberOf.
Problems Encountered
-
CA endpoints all return
AccessDenieddespite token carryingPolicy.ReadWrite.ConditionalAccess. Confirmed by decoding the JWT — the role IS in the token. Root cause:roleAssignments?$filter=principalId eq <sp-id>returns empty for the Tenant Admin SP in Cascades. Microsoft Graph evaluates CA endpoints against directory-role membership of the calling SP in addition to the OAuth scope; without an applicable role assignment (CA Admin / Security Admin / Global Reader), the call is denied.This appears to be a gap in
onboard-tenant.shsimilar to the one Mike fixed for Exchange Operator on16f95e8. Recommend follow-up: extend the script to assign Conditional Access Administrator to Tenant Admin SP at onboard time.
Commands & Outputs
Thread 1 (Howard, on CS-SERVER PowerShell)
Set-ADAccountPassword -Identity howard.enos -Reset -NewPassword (Read-Host -AsSecureString "New password")
Set-ADUser howard.enos -Add @{proxyAddresses="SMTP:howard.enos@cascadestucson.com"}
Get-ADUser howard.enos -Properties proxyAddresses,memberOf | Select Name,UserPrincipalName,proxyAddresses,memberOf
Output:
Name UserPrincipalName proxyAddresses memberOf
---- ----------------- -------------- --------
Howard Enos howard.enos@cascadestucson.com {SMTP:howard.enos@cascadestucson.com} {CN=SG-Caregivers,OU=Groups,DC=casc...
(New password is what will sync to M365 via PHS once staging exits. Not vaulted — Howard knows the value.)
Thread 2 (me, via Tenant Admin SP)
Token acquisition succeeded for Cascades tenant 207fa277-e9d8-4eb7-ada1-1064d2221498. Decoded JWT shows roles:
['Policy.ReadWrite.ConditionalAccess', 'User.ReadWrite.All', 'SecurityEvents.Read.All',
'Application.ReadWrite.All', 'Directory.ReadWrite.All', 'AppRoleAssignment.ReadWrite.All',
'RoleManagement.ReadWrite.Directory']
All CA endpoints returned 403 AccessDenied:
GET /v1.0/identity/conditionalAccess/namedLocationsGET /v1.0/identity/conditionalAccess/policiesGET /v1.0/policies/conditionalAccessPolicies
SP lookup in Cascades:
ObjectId: a5fa89a9-b735-4e10-b664-f042e265d137
DisplayName: ComputerGuru - Tenant Admin
Role assignments: [] (empty — confirmed root cause).
Configuration Changes
Active Directory (cascades.local)
howard.enospassword reset to memorable value (Howard knows; not vaulted by request — temp pilot account, will be reset post-pilot or replaced when production CA rollout swaps to group targeting)howard.enosgainedproxyAddresses=SMTP:howard.enos@cascadestucson.com
Cascades M365 tenant
- No changes this session (CA reconciliation blocked).
Repo
- This session log only.
Pending / Incomplete Tasks
Immediate (this morning's blocker)
- Howard picks Path A or Path B to grant Conditional Access Administrator role to Tenant Admin SP
Track A blockers (after the role assignment)
- Add
184.191.143.62/32to existingCascadesNamed Location - Verify state of existing
Require multifactor authentication for all usersCA policy (Report-only / On / Off) - Decide on caregiver-specific compliant-device CA targeting
howard.enosUPN (Report-only) — or skip - Gate A3 partial: create Entra App Registration for ALIS SSO, vault Directory ID + App ID + Client Secret
- Gate A5: exit Entra Connect staging mode → sync → verify howard.enos in M365 → assign Entra ID P2 license
- Gate A6: phone enrollment via QR from
CSC - Android Shared Phonesprofile (ALIS sign-in test deferred until ALIS App Store back) - Gate A7: flip CA from Report-only to On
ALIS-side (still blocked on ALIS App Store update)
- Howard installs "Entra SSO" app in ALIS App Store
- Pastes Directory ID + App ID + Secret Value into ALIS Outbound Connections
- Howard updates his ALIS staff profile email to match Entra UPN
- Tests SSO link triggering for his own account only
Follow-up onboard hardening
- Patch
.claude/skills/remediation-tool/scripts/onboard-tenant.shto assign Conditional Access Administrator role to Tenant Admin SP at onboard time (mirror of16f95e8Exchange Admin → Exchange Operator fix). Should also re-run against any tenant where Tenant Admin SP currently lacks the role.
Side-track from 4/25 (still in limbo)
- 7-mailbox shared conversion + Jodi Ramstack license removal — blocked on Exchange RBAC propagation lag. Three fallback paths in
reports/2026-04-24-jeff-restore-ashley-access.md. Not on the phone-pilot critical path.
Reference Information
Cascades tenant
- Tenant ID:
207fa277-e9d8-4eb7-ada1-1064d2221498 - Tenant Admin SP appId:
709e6eed-0711-4875-9c44-2d3518c47063 - Tenant Admin SP objectId in Cascades:
a5fa89a9-b735-4e10-b664-f042e265d137 - Vault:
msp-tools/computerguru-tenant-admin.sops.yaml
Microsoft directory role template IDs (for the role assignment)
- Conditional Access Administrator:
b1be1c3e-b65d-4f19-8427-f6fa0d97feb9 - Security Administrator:
194ae4cb-b126-40b2-bd5b-6091b380977d - Global Reader:
f2ef992c-3afb-46b9-b7cf-a126ee74c451
Path A — Graph role assignment payload (for when Howard greenlights)
# Activate the role first if it's not yet activated in this tenant (idempotent)
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"https://graph.microsoft.com/v1.0/directoryRoles" \
-d '{"roleTemplateId":"b1be1c3e-b65d-4f19-8427-f6fa0d97feb9"}'
# Assign Conditional Access Administrator to Tenant Admin SP
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments" \
-d '{
"principalId": "a5fa89a9-b735-4e10-b664-f042e265d137",
"roleDefinitionId": "b1be1c3e-b65d-4f19-8427-f6fa0d97feb9",
"directoryScopeId": "/"
}'
Path B — portal click path
Entra admin center (signed in as admin@cascadestucson.com or sysadmin@cascadestucson.com) →
Roles & administrators → search "Conditional Access Administrator" → open → Add assignments → search "ComputerGuru - Tenant Admin" → Add.
Note for Mike
Short save-point session this morning. Howard ran the AD-side prep (password + proxyAddresses for howard.enos) cleanly. Hit a directory-role gap on the Tenant Admin SP — it has zero role assignments in the Cascades tenant, so all CA Graph endpoints 403 even with Policy.ReadWrite.ConditionalAccess on the token. Same flavor of gap you fixed for Exchange Operator on 16f95e8. Recommend extending onboard-tenant.sh to assign Conditional Access Administrator to Tenant Admin SP at onboard time. Howard is choosing between Graph-side fix (Path A) and portal-click (Path B) when he resumes; either way we should backfill the script after.