Files
claudetools/clients/cascades-tucson/session-logs/2026-04-29-howard-cascades-bypass-pilot-phase-b-buildout.md
Howard Enos a2f38c1038 cascades: CA unblock + Phase B buildout + onboard-tenant.sh CA Admin backfill
Day-long session unblocking the Cascades CA reconciliation that was paused on
the Tenant Admin SP directory-role gap. Discovered Microsoft also tightened
the OAuth scope for /identity/conditionalAccess/* reads (Policy.Read.All now
required, Policy.ReadWrite.ConditionalAccess no longer accepted for reads).
Patched Tenant Admin manifest accordingly and re-consented in Cascades.

Phase B Intune state turned out to be far more built than the 4/20 log
suggested -- compliance policy, Wi-Fi, device restrictions, both SDM app
configs (Authenticator + Teams), and 7 of 8 apps were already deployed and
assigned. PATCHed device restrictions to block camera/Bluetooth/roaming
and enabled Managed Home Screen multi-app kiosk (ALIS + Teams visible,
10-min auto-signout). PATCHed Cascades named location to add primary WAN
(184.191.143.62/32). Howard added Outlook from Managed Play; SMB encryption
enabled on \CS-SERVER\homes.

CA bypass design corrected -- original §5 plan in user-account-rollout-plan.md
called for "block off-site + MFA on-site" which doesn't match the actual goal
of bypass when network + device assurance present. Reshaped to three policies
that produce on-site-compliant = password only, anything else = MFA or block.

onboard-tenant.sh patched to:
  1. Backfill Policy.Read.All on Tenant Admin SP if missing (idempotent --
     for tenants consented before the 2026-04-29 manifest update).
  2. Assign Conditional Access Administrator directory role to Tenant Admin
     SP at onboard time. Mirrors the Exchange Operator fix Mike landed in
     16f95e8.

Validated with --dry-run against Cascades. Customer-facing tenants already
onboarded should be re-run with this script to backfill both items.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 07:32:23 -07:00

27 KiB

2026-04-29 — Cascades CA unblock + Phase B Intune buildout + bypass pilot prep

User

  • User: Howard Enos (howard)
  • Machine: HOWARD-HOME
  • Role: tech
  • Session span: 2026-04-28 evening into 2026-04-29 early morning (continuous, ~7 hours)

Resume point (READ THIS FIRST when picking back up)

We are on the Cascades caregiver shared-phone bypass pilot, Path B (cloud-only test user). Phase B Intune is fully built. Cascades named location has both WANs trusted. Phase A "Track" plan reshaped — original §5 design did not match Howard's actual goal of MFA bypass on trusted-network + compliant-device.

Where we paused: awaiting Howard's next decision after Phase B is fully populated and one phone successfully completes a real user sign-in flow to flip compliant. Outlook is being added by Howard via Managed Play.

What's still to do, in order

  1. Howard finishes Outlook add (Managed Play), then sync and tell me. I'll assign it + add to MHS visible apps (currently ALIS + Teams; will become ALIS + Teams + Outlook).
  2. Howard adds LinkRx + Helpany web apps in Intune portal when he has the URLs.
  3. Pilot user + cloud group (Path B):
    • Create cloud-only Entra group SG-Caregivers-Pilot
    • Create cloud-only test user (or use an existing cloud user; Howard's howard.enos cloud account doesn't exist yet because Entra Connect is in staging)
    • License test user with Business Premium (one of 34 spare seats)
    • Add user to SG-Caregivers-Pilot
  4. Break-glass admin — design + create. Need: cloud-only Global Admin, FIDO2 (Howard has 1 YubiKey), excluded from all CA, vaulted password, sign-in alerts. Pre-flight before CA changes.
  5. New CA bypass policies (corrected design — see §"CA design correction" below):
    • DELETE Require multifactor authentication for all users (existing)
    • CREATE CSC - Require MFA off Cascades network (all users, location not Cascades → require MFA)
    • CREATE CSC - Require MFA on non-compliant device (all users, device.isCompliant -eq False → require MFA)
    • CREATE CSC - Block off-network unless allow-listed (all except SG-External-Signin-Allowed and break-glass, location not Cascades → block)
    • CREATE CSC - Sign-in frequency 8h session control on SG-Caregivers-Pilot (and later SG-Caregivers)
  6. Stage all new CA in Report-only for 24-48h, review logs, fix gaps, then flip to On.
  7. Phone enrollment dry-run with the pilot user → expect no MFA on Cascades Wi-Fi + compliant device, expect block off-network.

Decisions still pending

  • Pilot user identity (create new pilot.test@ vs use existing cloud user)
  • Audit retention: deferred — Azure pay-as-you-go subscription still needs Howard or Mike billing call
  • Whether to backfill onboard-tenant.sh against other already-onboarded tenants for the new CA Admin + Policy.Read.All (script now handles this idempotently when re-run; just needs a re-run per tenant)

Session Summary

Picked up from the 2026-04-28 morning save where the Tenant Admin SP had no directory role in Cascades and every /identity/conditionalAccess/* call returned 403. Howard granted the Conditional Access Administrator role via PIM (Active assignment, permanent, Path B from yesterday's options). After that landed, CA endpoints still returned 403 with the same scope-missing error. Investigation showed Microsoft tightened LIST /identity/conditionalAccess/namedLocations to require Policy.Read.All as the application permission — Policy.ReadWrite.ConditionalAccess (which the SP carried) is no longer accepted for reads on this endpoint. Patched the Tenant Admin app manifest in ACG home to add Policy.Read.All, granted the appRoleAssignment in ACG home, Howard re-consented in Cascades. CA reads then worked.

Reading the CA state revealed the existing Require multifactor authentication for all users policy is in enabled state (not Report-only), which makes the original Track A "Gate A7 — flip from Report-only to On" obsolete. Howard re-stated the pilot goal in plain language: caregivers signing into shared phones on Cascades Wi-Fi with a compliant Intune-managed device should bypass MFA entirely; off-site they should be blocked (no personal device for MFA fallback exists). Eventually this rolls out to all users at Cascades. The existing user-account-rollout-plan.md §5 design said "Block sign-in unless from Cascades + MFA" — meaning even on-site users get MFA prompted — which doesn't match the goal. Reshaped the CA design to three policies that together produce on-site-compliant = password only, anything else = MFA or block.

In parallel, discovered the ComputerGuru - Intune Manager app was still single-tenant, so it couldn't be consented in Cascades. PATCHed signInAudience to AzureADMultipleOrgs in ACG home, Howard re-consented in Cascades, then queried Intune state. Phase B is far more built than the 4/20 session log indicated — at some point between 4/20 and 4/21 someone (likely Howard) finished it. The compliance policy (CSC - Android Compliance, type androidDeviceOwnerCompliancePolicy), Wi-Fi config (CSC - CSCNet Wi-Fi), device restrictions (CSC - Android Shared Phones Restrictions), and both Shared Device Mode app config policies (Authenticator + Teams, both with shared_device_mode_enabled=true) all exist and are assigned to the Cascades - Shared Phones dynamic group. 7 of 8 apps are deployed and assigned (Microsoft Launcher is the only unassigned one).

PATCHed the Cascades named location to add 184.191.143.62/32 (primary WAN). Both WANs now isTrusted=true. PATCHed device restrictions to block camera, Bluetooth, and data roaming (per Howard's spec). Enabled Managed Home Screen multi-app kiosk mode with ALIS + Microsoft Teams as visible apps, 10-min idle auto-signout with 1-min warning, no MHS-level PIN (relies on the device PIN already required by compliance). Howard added Microsoft Outlook from Managed Play in the Intune portal. Walked through Wave 0 HIPAA pre-flight: HIPAA BAA is automatic via Microsoft Online Services Terms (no separate signature needed); SMB encryption on \\CS-SERVER\homes was False, Howard ran Set-SmbShare -Name homes -EncryptData $true -Force to flip it; Diagnostic Settings deferred (will set up Azure pay-as-you-go later for Log Analytics workspace). After the session, ran /sync which surfaced Mike's note from earlier in the day approving Path A for the CA fix — superseded by Path B, which Howard already executed. Patched onboard-tenant.sh to programmatically assign Conditional Access Administrator role to the Tenant Admin SP and backfill Policy.Read.All on existing tenants where the manifest update post-dates their consent.

Key Decisions

  • Path B (manual portal PIM assignment) for the CA Admin role instead of the Graph-API Path A Mike approved. Both achieve the same end state. Path B was faster on the day; Path A is now the backfilled default in onboard-tenant.sh.
  • Patch Policy.Read.All into Tenant Admin manifest. Microsoft tightened LIST /identity/conditionalAccess/* endpoints to require Policy.Read.All as the application permission. Policy.ReadWrite.ConditionalAccess (legacy) is no longer accepted for reads. New tenants get this from the manifest at consent time; existing tenants get it programmatically via the patched onboard script.
  • Reshape the CA bypass design. Replace the existing all-users-MFA policy with three policies that together produce: on-site + compliant = password only, off-site or non-compliant = MFA or block. The original Track A §5 design conflated "block off-site" with "require MFA on-site," which doesn't match the actual goal of bypassing MFA when network + device assurance are present.
  • Path B for the pilot (cloud-only test user) instead of Path A (exit Entra Connect staging first). Faster path to a meaningful test; the production rollout will use the synced SG-Caregivers group once staging exits, but that's a separate operation gated on the AD prereq cleanup (Wave 0.5 G1 from user-account-rollout-plan.md).
  • Sign-in frequency: 8 hours for caregivers (revised from initial "every hour" — caregivers re-auth at start of shift and work through without re-prompts; HIPAA-defensible as one strong factor among three).
  • Off-network behavior: block for caregivers, MFA for office allow-list. Caregivers have no personal device for MFA, so off-network access is denied entirely. Office staff in SG-External-Signin-Allowed get MFA off-network without compliant-device requirement (Howard's call — simpler, less brittle).
  • Path X (Managed Home Screen multi-app kiosk) instead of standard Android launcher. Provides keyboard lockdown, restricted app access, and HIPAA-defensible least-privilege UI for caregivers.
  • MHS auto-signout: 10 min idle, 1 min warning. Standard healthcare convention for shared-device session lifetime, separate from the device's 1-min screen lock and the 8-hour CA sign-in frequency.
  • Microsoft Launcher: leave unassigned. With MHS as the kiosk launcher, the Microsoft Launcher app is redundant.
  • Intune Manager app: convert to multi-tenant. Single-tenant gave AADSTS700016 when consenting in Cascades. PATCH on signInAudience to AzureADMultipleOrgs was the cleaner fix vs. adding DeviceManagement scopes to Tenant Admin.
  • Audit retention: defer to later. Microsoft default 30-day Entra retention plus Purview 180-day retention covers near-term forensics. Long-term 6-year HIPAA retention will be added via Azure Storage Account or Log Analytics workspace once an Azure pay-as-you-go subscription is set up. Cost estimate: Storage Account ~$0.20/mo at year-6 max; LAW with live monitoring ~$0.50-1/mo.
  • HIPAA BAA: confirmed automatic via Microsoft Online Services Terms. The old Admin Center checkbox is gone. Business Premium covers HIPAA-eligible services by default.

Problems Encountered

  • CA endpoints 403 after CA Admin role assigned — root cause not directory role missing (already fixed) but Microsoft tightening the OAuth scope. Fixed by patching Policy.Read.All into Tenant Admin manifest and re-consenting in Cascades.
  • Intune Manager app single-tenant — couldn't be consented in Cascades; got AADSTS700016. Fixed by PATCH on signInAudience to AzureADMultipleOrgs in ACG home.
  • Direct Graph add of Managed Play apps not supported — POST to /v1.0/deviceAppManagement/mobileApps with androidManagedStoreApp returns 400 because Managed Play apps must be approved through Google's Play console iframe. Howard added apps via UI; assignments + config policies done via Graph after.
  • Graph v1.0 mobileApps endpoint hides Managed Play apps — initially saw only ALIS in the inventory. Beta endpoint returned all 8 apps. Switched all subsequent app queries to beta.
  • Kiosk app schema discovery iterationkioskModeApps requires items typed as microsoft.graph.appListItem with required name field. Two failed attempts (androidDeviceOwnerKioskModeManagedAppItem, androidDeviceOwnerKioskModeAppPositionItem) before landing on the correct shape.
  • Phones still noncompliant after all policy work — expected. Compliance requires a real user sign-in flow to set the 6-digit PIN and trigger Authenticator SDM registration. Will resolve when the pilot user signs into one of the test phones.
  • Existing all-users-MFA policy is enforced, not Report-only — invalidates Gate A7 from Track A. Reshaped CA design described above.
  • Diagnostic Settings page requires Azure subscription — no Azure subscription on Cascades yet. Audit retention plan deferred until subscription decision (Cascades direct billing vs ACG bundles it into MSP invoice).
  • Sync notification surfaced Mike's note (now superseded) — Mike approved Path A while we were already doing Path B. Net result is the same; need a follow-up note to Mike to close the loop.

Configuration Changes

ComputerGuru ACG home tenant (ce61461e-81a0-4c84-bb4a-7b354a9a356d)

  • ComputerGuru - Tenant Admin app manifest: added Policy.Read.All (246dd0d5-5bd0-4def-940b-0421030a5b68) to requiredResourceAccess. Granted appRoleAssignment in home tenant.
  • ComputerGuru - Intune Manager app manifest: flipped signInAudience from AzureADMyOrg to AzureADMultipleOrgs.

Cascades tenant (207fa277-e9d8-4eb7-ada1-1064d2221498)

  • Tenant Admin SP (a5fa89a9-b735-4e10-b664-f042e265d137) now holds Conditional Access Administrator directory role (PIM-managed, Active assignment, permanent, no expiration). Status Provisioned since 2026-04-28T18:45:50Z.
  • Tenant Admin SP now also has Policy.Read.All appRoleAssignment (added via re-consent).
  • Intune Manager SP consented + provisioned in Cascades after multi-tenant flip.
  • Cascades named location (id 061c6b06-b980-40de-bff9-6a50a4071f6f):
    • Was: 72.211.21.217/32 only (secondary WAN)
    • Now: 72.211.21.217/32 + 184.191.143.62/32 (both WANs)
    • isTrusted: true
  • CSC - Android Shared Phones Restrictions (id 070a76c2-a8c3-4f7f-9ba7-1f4ac5084184) — version bumped 2 → 4:
    • cameraBlocked: true
    • bluetoothBlockConfiguration: true
    • dataRoamingBlocked: true
    • kioskModeUseManagedHomeScreenApp: "multiAppMode"
    • kioskModeApps: [ALIS, Microsoft Teams]
    • kioskModeManagedHomeScreenAutoSignout: true
    • kioskModeManagedHomeScreenInactiveSignOutDelayInSeconds: 600 (10 min)
    • kioskModeManagedHomeScreenInactiveSignOutNoticeInSeconds: 60 (1 min warning)
    • kioskModeManagedHomeScreenPinRequired: false
  • Microsoft Outlook added to mobile apps via Intune portal (Managed Play). Pending sync, then assignment + add to MHS app list.

CS-SERVER (Cascades on-prem DC, 192.168.2.254)

  • \\CS-SERVER\homes SMB share: EncryptData was False, Howard ran Set-SmbShare -Name homes -EncryptData $true -Force to flip it.

Repo

  • .claude/skills/remediation-tool/scripts/onboard-tenant.sh patched:
    • Added ROLE_CA_ADMIN constant (b1be1c3e-b65d-4f19-8427-f6fa0d97feb9)
    • Added Tenant Admin SP → Conditional Access Administrator assignment block (with role activation, idempotent)
    • Added Policy.Read.All backfill block before the consent_app loop (idempotent — only grants if missing)
    • Added Tenant Admin row to the final status table

Commands & Outputs

Cascades named location PATCH

TOKEN=$(bash .claude/skills/remediation-tool/scripts/get-token.sh \
  207fa277-e9d8-4eb7-ada1-1064d2221498 tenant-admin)
NL_ID="061c6b06-b980-40de-bff9-6a50a4071f6f"
curl -X PATCH \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  "https://graph.microsoft.com/v1.0/identity/conditionalAccess/namedLocations/$NL_ID" \
  -d '{
    "@odata.type": "#microsoft.graph.ipNamedLocation",
    "isTrusted": true,
    "ipRanges": [
      {"@odata.type": "#microsoft.graph.iPv4CidrRange", "cidrAddress": "72.211.21.217/32"},
      {"@odata.type": "#microsoft.graph.iPv4CidrRange", "cidrAddress": "184.191.143.62/32"}
    ]
  }'
# HTTP 204

Tenant Admin manifest patch (Policy.Read.All)

Inline bash (mirrored Mike's patch-tenant-admin-manifest.sh pattern):

POLICY_READ_ALL_ID="246dd0d5-5bd0-4def-940b-0421030a5b68"
# Patch requiredResourceAccess to include Policy.Read.All
# Then grant appRoleAssignment in ACG home
# Howard re-consented in Cascades via:
#   https://login.microsoftonline.com/207fa277-e9d8-4eb7-ada1-1064d2221498/adminconsent?client_id=709e6eed-0711-4875-9c44-2d3518c47063&redirect_uri=https://azcomputerguru.com&prompt=consent

Intune Manager multi-tenant flip

INTUNE_APP_OBJ_ID="31017446-c01a-4775-864f-aef96ce43797"
curl -X PATCH \
  -H "Authorization: Bearer $MGMT_TOKEN" -H "Content-Type: application/json" \
  "https://graph.microsoft.com/v1.0/applications/$INTUNE_APP_OBJ_ID" \
  -d '{"signInAudience": "AzureADMultipleOrgs"}'
# HTTP 204 (initial verify lagged; re-verified after 8s — confirmed)

Device restrictions PATCHes

TOKEN=$(bash .claude/skills/remediation-tool/scripts/get-token.sh \
  207fa277-e9d8-4eb7-ada1-1064d2221498 intune-manager)
RESTRICT_ID="070a76c2-a8c3-4f7f-9ba7-1f4ac5084184"

# Block camera + bluetooth + roaming
curl -X PATCH -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations/$RESTRICT_ID" \
  -d '{
    "@odata.type": "#microsoft.graph.androidDeviceOwnerGeneralDeviceConfiguration",
    "cameraBlocked": true,
    "bluetoothBlockConfiguration": true,
    "dataRoamingBlocked": true
  }'

# Enable MHS multi-app kiosk
curl -X PATCH -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations/$RESTRICT_ID" \
  -d '{
    "@odata.type": "#microsoft.graph.androidDeviceOwnerGeneralDeviceConfiguration",
    "kioskModeUseManagedHomeScreenApp": "multiAppMode",
    "kioskModeApps": [
      {"@odata.type": "#microsoft.graph.appListItem", "name": "ALIS",            "appId": "fcbf803d-ceb7-4f4e-93ed-2be1b91a05f3"},
      {"@odata.type": "#microsoft.graph.appListItem", "name": "Microsoft Teams", "appId": "0eb81676-299b-4eb2-bfd9-8be914a82f91"}
    ],
    "kioskModeManagedHomeScreenAutoSignout": true,
    "kioskModeManagedHomeScreenInactiveSignOutDelayInSeconds": 600,
    "kioskModeManagedHomeScreenInactiveSignOutNoticeInSeconds": 60,
    "kioskModeManagedHomeScreenPinRequired": false
  }'

CS-SERVER SMB encryption

Set-SmbShare -Name homes -EncryptData $true -Force
Get-SmbShare -Name homes | Select Name,EncryptData
# Name  EncryptData
# ----  -----------
# homes        True

CA design correction (revised from user-account-rollout-plan.md §5)

Existing all-users MFA policy is enabled not Report-only. Original §5 design said "block off-site, require MFA on-site" — that conflicts with Howard's actual goal of bypass on-site + compliant. Corrected design (deferred for build until break-glass exists):

# Name Users Conditions Grant
(DELETE) Require multifactor authentication for all users
1 CSC - Require MFA off Cascades network All users (admins still hit by separate admin policy) Locations: include All, exclude Cascades named location Require MFA
2 CSC - Require MFA on non-compliant device All users Filter for devices: include device.isCompliant -eq False Require MFA
3 CSC - Block off-network unless allow-listed All users except SG-External-Signin-Allowed and break-glass Locations: include All, exclude Cascades named location Block
4 CSC - Sign-in frequency 8h (session control) SG-Caregivers-Pilot (then SG-Caregivers) (none — applies to all sessions for the group) Session control: re-auth every 8 hours

Logic verification: caregiver on Cascades + compliant phone → no policy applies → password only. Caregiver off-network → policy 3 blocks. Caregiver on Cascades + non-compliant → policy 2 → MFA (which they can't do → effectively blocked, by design). External-allowed user off-site + compliant device → policy 1 → MFA only. Office user not allow-listed off-site → policies 1 + 3 → block wins.

Keep existing risk-based + admin-targeted policies as defense in depth (they'll continue to add MFA on top in suspect scenarios, even when the bypass would otherwise apply — which is correct for HIPAA).


Pending / Incomplete Tasks

Immediate (resume here)

  • Howard finishes Outlook Managed Play sync, tells me, I assign + add to MHS app list
  • Howard adds LinkRx + Helpany web apps when URLs available
  • Pick a phone and run real user sign-in flow → verify compliance flips to compliant

Path B pilot

  • Decide: create new pilot.test@cascadestucson.com cloud user, or use an existing cloud user
  • Create cloud-only Entra group SG-Caregivers-Pilot, add pilot user
  • Assign Business Premium license to pilot user

Wave 0 HIPAA pre-flight (before any CA change goes live)

  • Break-glass admin: design + create. Cloud-only Global Admin, FIDO2 (1 YubiKey on hand), excluded from all CA, vaulted password, sign-in alerts to Howard + Mike
  • Audit retention 6yr: decide Cascades-billed vs ACG-billed, then create Azure pay-as-you-go subscription, Log Analytics workspace, Diagnostic Settings export
  • ALIS BAA: ask Meredith (Howard sends email)
  • Risk Analysis doc: draft via Ollama, Mike reviews

CA bypass build

  • Stage 4 new policies in Report-only, assigned to SG-Caregivers-Pilot initially
  • Run pilot validation tests (the 8 from the earlier write-up)
  • After 24-48h Report-only and break-glass verified working, flip to On

Production rollout (later)

  • AD prereq cleanup (G1 from §7) — renames, UPN suffix add, former-employee deletes, etc.
  • Exit Entra Connect staging mode (G3-G5)
  • Replace SG-Caregivers-Pilot with synced SG-Caregivers in CA policy targets
  • Roll Phase 3 (all users at Cascades on Cascades net + compliant device → bypass)
  • Run patched onboard-tenant.sh against all other already-onboarded ACG customer tenants to backfill CA Admin role + Policy.Read.All

Side-track from 4/25 (still in limbo)

  • 7-mailbox shared conversion + Jodi Ramstack license removal (blocked on Exchange RBAC propagation lag)

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
  • Intune Manager SP appId: 46986910-aa47-4e5e-b596-f65c6b485abb
  • Cascades named location id: 061c6b06-b980-40de-bff9-6a50a4071f6f
  • Trusted IPs (both WANs): 72.211.21.217/32 (secondary), 184.191.143.62/32 (primary)
  • Vault: clients/cascades-tucson/wifi-cscnet.sops.yaml, clients/cascades-tucson/mdm-service-account.sops.yaml

Cascades Intune resources

  • Compliance policy: CSC - Android Compliance id 27eeaeda-8390-462e-a514-7d2a558f412c
  • Wi-Fi config: CSC - CSCNet Wi-Fi (WPA2-Personal) id b572ba54-1a04-4c40-9ac5-dd5aec444611
  • Device restrictions: CSC - Android Shared Phones Restrictions id 070a76c2-a8c3-4f7f-9ba7-1f4ac5084184
  • SDM Authenticator config: id a1bfbda0-a36c-45e5-8844-8470f80ecc8d
  • SDM Teams config: id 3c6a354c-1616-434b-ac81-4dad7795e67b
  • Enrollment profile: CSC - Android Shared Phones, token MVDVVDMPSHYJAGDAJOCN (expires 2026-06-22)
  • Target group: Cascades - Shared Phones (cloud, dynamic, security) id ea96f4b7-3000-45da-ab1f-ddb28f509526, rule: device.enrollmentProfileName -eq "CSC - Android Shared Phones"

Microsoft directory role template IDs

  • Conditional Access Administrator: b1be1c3e-b65d-4f19-8427-f6fa0d97feb9
  • Security Administrator: 194ae4cb-b126-40b2-bd5b-6091b380977d
  • Global Reader: f2ef992c-3afb-46b9-b7cf-a126ee74c451

Microsoft Graph appRole IDs

  • Policy.Read.All: 246dd0d5-5bd0-4def-940b-0421030a5b68
  • Policy.ReadWrite.ConditionalAccess: 01c0a623-fc9b-48e9-b794-0756f8e8f067
  • RoleManagement.ReadWrite.Directory: 9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8

Currently-enrolled test phones (both noncompliant pending real sign-in flow)

  • Device 1: SM-A146U, enrolled 2026-04-20, last sync 2026-04-23, isEncrypted=true, jailBroken=Unknown
  • Device 2: SM-A146U, enrolled 2026-04-23, last sync 2026-04-27, isEncrypted=true, jailBroken=Unknown

Note for Mike

Closing the loop on your 2026-04-28 note re: Cascades CA fix.

Path A vs Path B: I executed Path B (PIM portal click as sysadmin@cascadestucson.com, Active assignment, permanent) before seeing your note approving Path A. Both produce the same end state — the directory role is in place on the Tenant Admin SP since 2026-04-28T18:45:50Z. No follow-up needed on the Cascades-specific assignment; it's done.

The actual blocker turned out to be different: even with the directory role, CA endpoints kept returning 403 with "required scopes are missing in the token." Microsoft tightened LIST /identity/conditionalAccess/namedLocations and /policies to require Policy.Read.All as the application permission — Policy.ReadWrite.ConditionalAccess (which the SP carried) is no longer accepted for reads. Patched the Tenant Admin app manifest to add Policy.Read.All, granted in ACG home, Howard re-consented in Cascades. CA reads then worked.

onboard-tenant.sh patch — done. Per the new tool-vs-project approval workflow, Howard approved this and I patched. Two changes:

  1. Tenant Admin SP now gets Conditional Access Administrator directory role assigned at onboard time (idempotent — handles already-assigned via the existing Conflict-fallback in assign_role).
  2. New backfill block: detects whether Tenant Admin SP has Policy.Read.All and grants it programmatically if missing. Required for tenants where Tenant Admin was consented before the manifest update on 2026-04-29.

Validated with bash onboard-tenant.sh 207fa277-e9d8-4eb7-ada1-1064d2221498 --dry-run — clean.

Recommended backfill against other onboarded tenants: re-run bash onboard-tenant.sh <tenant-id> against every customer where Tenant Admin was consented before 2026-04-29 today's manifest update. Idempotent — safe to re-run. If a tenant has a pre-existing PIM-managed CA Admin assignment (like Cascades does after Howard's PIM click), the role_assigned helper might mistakenly report MISSING because PIM-managed assignments may not appear in the legacy roleAssignments query. The actual assign_role call will hit Conflict and the helper treats that as success — so the script is still correct, just slightly noisy in its reporting. Worth a follow-up to teach role_assigned about roleAssignmentSchedules too, but not blocking.

Phase B Intune state at Cascades: done in full (compliance, Wi-Fi, restrictions w/ MHS multi-app kiosk, both SDM app configs, all 8 apps assigned except Microsoft Launcher). Pilot phone enrollment will validate the full flow once Outlook landed (Howard added it tonight).

Wave 0 HIPAA pre-flight status: BAA confirmed automatic via MOST. Break-glass admin not yet created — that's the next pre-flight before we touch CA policies. Audit retention deferred until Cascades-billed vs ACG-billed decision (your call when you're back). The CA bypass design needed reshaping — original §5 plan didn't actually achieve the bypass goal; corrected design is in this log under "CA design correction."

If anything in the corrected CA design or the onboard-tenant patch isn't to your liking, ping back and I'll adjust.


Session duration: ~7 hours continuous (2026-04-28 ~16:00 → 2026-04-29 ~07:30 PT, with breaks for portal tasks) Commits during session: 1 sync auto-commit (ff4577c) before this log; this log + onboard-tenant patch will land in a fresh commit after /save Files changed in this log's commit: 2 (.claude/skills/remediation-tool/scripts/onboard-tenant.sh, this session log)