Files
claudetools/clients/cascades-tucson/session-logs/2026-04-28-howard-ca-reconciliation-blocked-on-sp-role.md
Howard Enos 00fa539e4f cascades save: AD-side pilot prep done; CA reconciliation blocked on SP role gap (2026-04-28)
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>
2026-04-28 07:19:11 -07:00

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 id b1be1c3e-b65d-4f19-8427-f6fa0d97feb9) to the Tenant Admin SP via Graph. Token has RoleManagement.ReadWrite.Directory — should work app-only without elevation. After it lands, also patch .claude/skills/remediation-tool/scripts/onboard-tenant.sh so future tenants get this assignment automatically (parallels the Exchange Admin → Exchange Operator fix Mike committed in 16f95e8).
  • 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

  1. CA reconciliation read-side — pull existing Cascades Named Location object (currently 72.211.21.217/32 only, per 4/25 portal review) and the existing Require multifactor authentication for all users policy state (Report-only / On / Off).
  2. CA reconciliation write-side — PATCH the Cascades Named Location to add 184.191.143.62/32. Decide whether to add a single caregiver-specific compliant-device policy targeting howard.enos@cascadestucson.com UPN (Report-only) or rely on existing all-users MFA policy.
  3. 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.
  4. Gate A5 — exit Entra Connect staging. Howard runs on CS-SERVER:
    Set-ADSyncScheduler -SyncCycleEnabled $true   # if needed
    # Remove staging mode via the Entra Connect wizard (Configure → Configure staging mode → uncheck)
    Start-ADSyncSyncCycle -PolicyType Initial
    
    Then verify howard.enos lands in M365 as hybrid user, assign Entra ID P2 license (unassigned seat available from Sandra Fish cleanup).
  5. Gate A6 — phone enrollment. QR from CSC - Android Shared Phones profile → 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.
  6. 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.enos AD 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.com to match the G1 convention. Confirmed via Get-ADUser -Properties proxyAddresses,memberOf.

Problems Encountered

  • CA endpoints all return AccessDenied despite token carrying Policy.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.sh similar to the one Mike fixed for Exchange Operator on 16f95e8. 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/namedLocations
  • GET /v1.0/identity/conditionalAccess/policies
  • GET /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.enos password 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.enos gained proxyAddresses=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/32 to existing Cascades Named Location
  • Verify state of existing Require multifactor authentication for all users CA policy (Report-only / On / Off)
  • Decide on caregiver-specific compliant-device CA targeting howard.enos UPN (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 Phones profile (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.sh to assign Conditional Access Administrator role to Tenant Admin SP at onboard time (mirror of 16f95e8 Exchange 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.