# Cascades — MHS web app tiles fix (added Managed Play web links to kioskModeApps)

**Date:** 2026-05-11
**Client:** Cascades of Tucson (Syncro 20149445, Tenant `207fa277-e9d8-4eb7-ada1-1064d2221498`)

## User
- **User:** Howard Enos (howard)
- **Machine:** Howard-Home
- **Role:** tech

## Session Summary

Picked up from 2026-05-08 with the three Managed Play web link tiles (Alis, HelpAny, LinkRx) still not visible on the pilot phones' Managed Home Screen, despite the apps being created as `androidManagedStoreWebApp` and assigned to the `Cascades - Shared Phones` group with intent `required`. The Microsoft doc that Howard referenced (`add-web`) confirmed the path taken yesterday was correct — that page explicitly says "For Android Enterprise devices, see Managed Google Play web links," ruling out the basic `microsoft.graph.webApp` type for AE dedicated devices.

Investigation via the Tenant Admin SP found that the assignment records on all three web links were structurally identical to a known-working app (Microsoft Authenticator), targeting the right group with `androidManagedStoreAppAssignmentSettings`. The `isAssigned: false` value returned by the single-app GET was misleading — the type-filtered list endpoint reports `isAssigned: true` for the same three apps, and Authenticator (a working tile) also reports `false` on its single-app GET, so that flag is a Graph response quirk and not the cause.

Root cause: `CSC - Android Shared Phones Restrictions` (id `070a76c2-a8c3-4f7f-9ba7-1f4ac5084184`) had `kioskModeApps` populated with only the six native packages (Authenticator, Outlook, Teams, Edge, MHS, Company Portal). The three new Managed Play web link packages were never added. MHS multi-app kiosk mode only displays tiles for apps whose package IDs appear in `kioskModeApps`; the underlying web links did install into the device app drawer but had no kiosk entry, so no tile.

Fix: PATCHed the device restrictions profile to v15 with all nine apps in the order Howard approved — caregiver line-of-business apps first (Alis, HelpAny, LinkRx), then communications (Outlook, Teams), then admin/utility (Authenticator, Edge, MHS, Company Portal).

Howard is now signing in as `pilot.test@cascadestucson.com` on the live phone to verify ALIS launches and SSO completes end-to-end.

## Key Decisions

- **Kept current order intent: LoB apps first, comms second, admin/utility last.** Caregivers' daily tap targets (Alis primarily) should be the most visually prominent tiles on a 9-tile kiosk grid. Authenticator was moved down from position 1 since SDM is now bootstrapped and caregivers don't routinely interact with it; if a re-bootstrap is needed later, the icon is still on the home screen, just lower in the list.

- **Did NOT add the web link packages to anything other than `kioskModeApps`.** The assignments on the three `androidManagedStoreWebApp` objects were already valid and pointing at the right group; no need to touch them. Avoiding extra changes preserves the minimal diff and makes the fix easy to revert (just remove the three entries from `kioskModeApps`).

## Problems Encountered

- **`isAssigned: false` on single-app GET was a red herring.** Wasted ~5 minutes assuming the assignment hadn't propagated. Confirmed by checking Microsoft Authenticator's same single-app GET — it also returns `false`. The flag is only reliable when fetched via the type-filtered list endpoint.

- **`POST /managedDevices/{id}/syncDevice` returns 403 from Tenant Admin SP.** SP lacks `DeviceManagementManagedDevices.PrivilegedOperations.All`. Already documented as an open item in the 2026-04-30 session log; non-blocking — phones sync on their own ~every 8h or via manual Sync from the device.

## Configuration Changes

### Device restrictions profile updated (v14 → v15)

`CSC - Android Shared Phones Restrictions` (id `070a76c2-a8c3-4f7f-9ba7-1f4ac5084184`)

PATCH body sent to `/beta/deviceManagement/deviceConfigurations/070a76c2-a8c3-4f7f-9ba7-1f4ac5084184` — set `kioskModeApps` to:

| Order | Name | appId (Android package) |
|---|---|---|
| 1 | Alis | `com.google.enterprise.webapp.x830557c4d8441444` |
| 2 | HelpAny | `com.google.enterprise.webapp.x6c759d4796c8526c` |
| 3 | LinkRx | `com.google.enterprise.webapp.x5fc56faf2fae1246` |
| 4 | Microsoft Outlook | `com.microsoft.office.outlook` |
| 5 | Microsoft Teams | `com.microsoft.teams` |
| 6 | Microsoft Authenticator | `com.azure.authenticator` |
| 7 | Microsoft Edge | `com.microsoft.emmx` |
| 8 | Managed Home Screen | `com.microsoft.launcher.enterprise` |
| 9 | Intune Company Portal | `com.microsoft.windowsintune.companyportal` |

Response: HTTP 204. Verified via re-GET — `version: 15`, `lastModifiedDateTime: 2026-05-11T17:34:14Z`.

### Managed Google Play sync triggered

`POST /beta/deviceManagement/androidManagedStoreAccountEnterpriseSettings/syncApps` — HTTP 200. Done as part of diagnosis; touched `lastModifiedDateTime` on the three web link apps but did not change their assignment state.

## Verification State

### Intune objects (current)

| Object | ID | State |
|---|---|---|
| Device restrictions profile | `070a76c2-a8c3-4f7f-9ba7-1f4ac5084184` | v15 with 9 kioskModeApps |
| Alis app | `8c0ae9bf-000d-4ae4-9b41-74afd186ad37` | androidManagedStoreWebApp, published, assigned required to Cascades - Shared Phones |
| HelpAny app | `cbb9404b-2413-40c1-823d-e10337d5238f` | androidManagedStoreWebApp, published, assigned required to Cascades - Shared Phones |
| LinkRx app | `c70f62bc-a2ff-4744-925a-a409e38c6690` | androidManagedStoreWebApp, published, assigned required to Cascades - Shared Phones |
| Cascades - Shared Phones group | `ea96f4b7-3000-45da-ab1f-ddb28f509526` | 2 members (both test phones) |

### Phone sync state at time of PATCH

| Phone | Intune ID | Last sync (pre-PATCH) | Expected to pick up v15 |
|---|---|---|---|
| CSC-R92W310H31N | `a46a2daf-b8c5-4c19-ac71-0fdc7341928a` | 2026-05-11T16:39:27Z | Within next checkin window or via manual Sync |
| CSC-R9TW207FSXA | `41345e4a-c58f-4b0d-9678-cd6da47acf6a` | 2026-05-10T13:42:46Z (stale 27h) | Likely needs manual Sync or reboot |

### Leftover (non-blocking)

`CSC-R9TTC0JSDPJ` (Intune id `01b8ba03-fd97-4e0f-ba94-4c1b9e5f5a12`) — third managed device record with `joinType: unknown`, `complianceState: unknown`, `azureADDeviceId: 00000000-...`. Not in `Cascades - Shared Phones` group, so won't get any of the SDM policies. Looks like an orphan from a prior re-enrollment attempt. Can clean up later via portal or `DELETE /managedDevices/{id}`.

## Pending / Incomplete Tasks

### In progress (Howard right now)
- [ ] Sign in to live phone as `pilot.test@cascadestucson.com`, wait for v15 to propagate, verify the three new tiles render on MHS in the configured order, tap Alis to verify it opens at `https://cascadestucson.alisonline.com/Login` and that the ALIS-side SSO redirect to Entra completes silently using the existing Authenticator broker session.

### Carryover from 2026-05-08 (still open)
- [ ] If pilot SSO works end-to-end: plan staged caregiver rollout — flip ONE user at a time. Per Medtelligent: "once a user account is linked to SSO, they will not be able to log in with their ALIS credentials unless a company administrator edits their login settings."
- [ ] Each caregiver's ALIS staff record's Email field must match their Entra UPN exactly (e.g. `firstname.lastname@cascadestucson.com`) before flip. Without exact email match → ALIS errors "user not found" on SSO sign-in.
- [ ] Provision the remaining 30 phones using the proven SDM-token enrollment profile playbook.
- [ ] Replace landscape wallpaper with a portrait-format Cascades logo when someone with WordPress access can upload one.
- [ ] Investigate MHS welcome-screen branding logo via an MHS app config policy (using documented keys only).
- [ ] Flip third caregiver CA policy (`CSC - Block caregivers on non-compliant device`) from Report-only to Enforced after pilot SSO verified.
- [ ] Login PINs feature — ask Medtelligent about enabling for Cascades next time ALIS support is engaged.
- [ ] Clean up stale Entra Android device records (`samsungSM-A146U`, the `31fb90e5...AndroidEnterprise_5/8/2026` orphan, and now `CSC-R9TTC0JSDPJ` Intune-side leftover).

### Long-term
- [ ] Disable `devices@cascadestucson.com` once production rollout completes.

## Reference Information

### Microsoft documentation
- **Add Web Apps to Intune** (the page Howard referenced): https://learn.microsoft.com/en-us/intune/app-management/deployment/add-web — confirms that for Android Enterprise devices the correct type is the Managed Google Play web link (the `microsoft.graph.webApp` type is only valid for iOS, macOS, Windows, and legacy Android Device Admin).
- **Managed Google Play web links** (the actual reference for what we deployed): https://learn.microsoft.com/en-us/intune/app-management/deployment/add-managed-google-play#managed-google-play-web-links — describes how web links install just like other Android apps and appear in the user's app list. Does NOT discuss MHS kiosk visibility; that's controlled by `kioskModeApps` on the device restrictions profile, which is a separate layer.

### Key insight worth remembering
The Microsoft docs treat Managed Play web link **assignment** and MHS **kiosk visibility** as two independent layers:
1. App must be `androidManagedStoreWebApp` and assigned to the device group → installs into the app drawer.
2. App's Android package name must appear in `kioskModeApps` on the AndroidDeviceOwnerGeneralDeviceConfiguration → renders as a tile in MHS multi-app mode.

Missing step 2 yesterday is what cost us the overnight wait — the assignment was correct, the apps were silently installing into the drawer, but MHS had no kiosk entry telling it to render the tile.

### Useful API patterns from this session
```bash
# Fetch isAssigned via type-filtered list (returns correct value)
curl -s -H "Authorization: Bearer $TOK" \
  "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?\$filter=isof('microsoft.graph.androidManagedStoreWebApp')" \
  | jq '.value[] | {id, displayName, isAssigned}'

# PATCH pattern to update kioskModeApps (must include the @odata.type discriminator on the body
# and on each appListItem, otherwise Graph rejects with InvalidPropertyType)
curl -X PATCH -H "Authorization: Bearer $TOK" -H "Content-Type: application/json" \
  --data '{"@odata.type":"#microsoft.graph.androidDeviceOwnerGeneralDeviceConfiguration",
           "kioskModeApps":[{"@odata.type":"#microsoft.graph.appListItem","name":"...","appId":"..."}]}' \
  "https://graph.microsoft.com/beta/deviceManagement/deviceConfigurations/{id}"
```

---

## Part 2 — Eliminating the MFA registration nudge for caregivers (HIPAA compensating-controls design)

After the MHS tile fix landed and Howard signed in as pilot.test, the ALIS "Sign in with Microsoft" button correctly redirected through Entra — but Entra interrupted with an Authenticator-registration prompt. Wrong outcome: the design is "caregivers bypass MFA entirely when on cscnet + on a managed compliant phone." Shared phones have no personal MFA hook, so registering MFA per caregiver is operationally infeasible and a workaround for a real architectural gap.

Diagnosis traced the prompt to three independent sources:

1. **Authentication Methods Registration Campaign** (`/policies/authenticationMethodsPolicy`) — tenant default, `includeTargets: [all_users → microsoftAuthenticator]`, `excludeTargets: []`. Nudges any unregistered user with a one-tap registration prompt during any browser-mediated sign-in.
2. **CA `Require MFA when risky sign-ins are detected`** (id `76f1dd72-…`) — All Users, no group excludes, MFA on signInRiskLevels medium+high. If pilot.test's fresh browser sign-in evaluates risky, this fires.
3. **CA `Require MFA and password change when high-risk users are detected`** (id `9f123001-…`) — All Users, no group excludes, MFA+passwordChange on userRiskLevels high.

The Teams/Outlook sign-ins on the phone never hit these because Authenticator's broker flow uses device-bound PRT/FOCI tokens that skip the AAD interactive sign-in page where Registration Campaign lives. The ALIS-via-Edge OIDC flow does go through that page.

### HIPAA review before changing CA state

Howard asked whether the no-MFA architecture is HIPAA-defensible. Conclusion: yes under §164.306(b) "reasonable and appropriate safeguards," but only if compensating controls are tight and the decision is documented. HIPAA Security Rule §164.312(a)/(d) require unique user ID and person authentication — both satisfied by per-caregiver UPN + password. MFA itself is not mandated by the Rule (it's recommended by NIST SP 800-66r2 and HHS Cybersecurity Performance Goals as best practice). The compensating-controls design replaces the MFA factor with strict network+device+session controls.

See companion doc: `clients/cascades-tucson/docs/security/hipaa-caregiver-controls.md` for the full architecture write-up.

### Decisions made

- **Don't create block-on-risk clones.** Attempted POST of caregiver-targeted block-on-risk CA policies got HTTP 400 / error 1039 "Cannot create or update policies with premium P2 features" — Cascades doesn't have Entra ID P2 licensing, and risk-level conditions are P2-gated for new policies. The existing risk-based MFA policies are grandfathered from prior tenant state.
- **Leave caregivers IN the risk-based MFA policies.** Without P2 we can't clone-and-block. But the operational outcome is the same: when a sign-in is flagged risky, MFA gets challenged → caregiver has no MFA registered → challenge fails → de facto block. Microsoft's risk engine remains active for caregivers; the user-visible behavior under risk is rejection, which is what we want.
- **Eliminate only the Registration Campaign nudge.** That's what was actually interrupting normal sign-ins. Risk-policy interaction with caregivers is the de-facto-block path described above.
- **Flip the device-compliance block to Enforced.** The whole no-MFA architecture rests on this control. Leaving it Report-only was the load-bearing HIPAA gap.

### Configuration Changes

#### ACG home tenant — Tenant Admin app manifest

PATCH `/v1.0/applications/18ad80fd-ad17-4915-acf0-eb2c52e5feb9` adding one Graph application permission, plus `POST /servicePrincipals/{TA_SP}/appRoleAssignments` grant in home tenant (per established 2026-04-30 pattern):

| Permission | Permission ID | App role grant (home tenant) |
|---|---|---|
| `Policy.ReadWrite.AuthenticationMethod` | `29c18626-4985-4dcd-85c0-193eef327366` | `cH9qBAi7CUOuFF-16eeLYiGIHbGwtk5PnOx9YX0xcWk` |

**Tenant Admin SP now holds 16 Graph application roles total.** Updated full set:

```
AppRoleAssignment.ReadWrite.All
Application.ReadWrite.All
DeviceManagementApps.Read.All
DeviceManagementConfiguration.Read.All
DeviceManagementConfiguration.ReadWrite.All
DeviceManagementManagedDevices.Read.All
Directory.ReadWrite.All
Policy.Read.All
Policy.ReadWrite.AuthenticationMethod   (NEW this session)
Policy.ReadWrite.ConditionalAccess
RoleManagement.ReadWrite.Directory
SecurityEvents.Read.All
Sites.FullControl.All
Sites.ReadWrite.All
User.ReadWrite.All
UserAuthenticationMethod.ReadWrite.All
```

#### Cascades tenant — re-consent

Howard clicked `https://login.microsoftonline.com/207fa277-e9d8-4eb7-ada1-1064d2221498/adminconsent?client_id=709e6eed-0711-4875-9c44-2d3518c47063&redirect_uri=https://azcomputerguru.com&prompt=consent` and approved. Confirmed by clearing the cached token and decoding the fresh JWT — `roles` claim contains the new `Policy.ReadWrite.AuthenticationMethod`.

#### Cascades tenant — Authentication Methods Policy

PATCH `/beta/policies/authenticationMethodsPolicy` — set `registrationEnforcement.authenticationMethodsRegistrationCampaign.excludeTargets` to `[{id: "0674f0bc-6ff4-49c7-802d-2abf591ba371", targetType: "group"}]`. Verified post-PATCH. Result: SG-Caregivers-Pilot members no longer receive the Authenticator registration nudge during sign-in.

#### Cascades tenant — `CSC - Block caregivers on non-compliant device`

PATCH `/v1.0/identity/conditionalAccess/policies/ede985e2-ee7e-4521-88b2-34c847c3db20` — `state: "enabledForReportingButNotEnforced"` → `"enabled"`. Verified post-PATCH at `modifiedDateTime: 2026-05-11T18:06:21.9069392Z`. Result: caregivers can no longer sign in from a non-Intune-compliant device, closing the load-bearing HIPAA gap.

### Verification snapshot

| Object | ID | State after changes |
|---|---|---|
| ACG Tenant Admin app | `18ad80fd-ad17-4915-acf0-eb2c52e5feb9` | 16 Graph application roles in manifest |
| ACG TA SP grant | `046a7f70-bb08-4309-ae14-5fb5e9e78b62` | `appRoleId 29c18626-…` assigned 2026-05-11T18:07:01Z |
| Cascades Auth Methods policy | tenant-singleton | registration campaign excludes SG-Caregivers-Pilot |
| Cascades CA: `CSC - Block caregivers on non-compliant device` | `ede985e2-ee7e-4521-88b2-34c847c3db20` | **enabled** (was Report-only) |
| Cascades CA: `Require MFA when risky sign-ins are detected` | `76f1dd72-4003-4984-bb4a-6fcead072c2c` | unchanged (caregivers stay in scope as de-facto-block) |
| Cascades CA: `Require MFA and password change when high-risk users are detected` | `9f123001-a95f-4e50-9860-4dd2254cccad` | unchanged (same reasoning) |
| Cascades CA: `CSC - Block caregivers off Cascades network` | `e35614e1-e896-4a13-9407-076963af488f` | unchanged (enabled) |
| Cascades CA: `CSC - Caregiver sign-in frequency 8h` | `7d491c7a-ad90-4420-9990-40a1e676a76c` | unchanged (enabled) |
| Cascades named location `Cascades` (trusted) | `061c6b06-b980-40de-bff9-6a50a4071f6f` | unchanged, `isTrusted: true` |

### Problems Encountered

- **Tenant Admin SP lacked `Policy.ReadWrite.AuthenticationMethod`** — first PATCH attempt returned 403 `accessDenied`. Resolved via the established manifest-patch + home-tenant-grant + customer-tenant-re-consent pattern (one round-trip, ~5 min).
- **Couldn't create block-on-risk CA clones** — POST returned 400 / error 1039 "Cannot create or update policies with premium P2 features." Cascades doesn't have Entra ID P2 licensing. Existing risk-based policies in the tenant were grandfathered (probably from a prior P2 trial or come from Microsoft-managed templates that bypass the create-time license check). The no-P2 design described above is the workaround.
- **Cached token after grant** — fresh token had to be force-refreshed; deleted the cache file at `/tmp/remediation-tool/{tenant}/tenant-admin.jwt` before retrying. Same trap from 2026-04-30 — worth keeping muscle-memorized.

### Carryover open items

- [ ] Howard retest: tap ALIS tile on pilot phone as pilot.test, click "Sign in with Microsoft" — should now go silent (no Authenticator nudge, no MFA prompt, no friction).
- [ ] If silent SSO completes: next question is whether ALIS finds a matching staff record for `pilot.test@cascadestucson.com`. If "user not found," create a throwaway staff record with that email or temporarily set an existing staff record's Email to a Cascades UPN we can log in as.
- [ ] Sign-in log monitoring plan — define cadence for reviewing caregiver sign-ins for anomalies (compensating control for risk-based detection loss-of-friction).
- [ ] Carryover from earlier: Verify ALIS BAA (`billing-log.md:254`) and Microsoft BAA (`m365.md:288`) — separate HIPAA findings, not introduced by today's changes but on the same compliance posture.

---

**Session duration through Part 2:** ~2.5 hours total (MHS kiosk fix + MFA architecture rework)
**Status at Part 2:** All three changes (registration campaign exclude, compliance block enforced, manifest scope expansion) live and verified. HIPAA architecture documented at `clients/cascades-tucson/docs/security/hipaa-caregiver-controls.md`.

---

## Part 3 — SSPR registration was the final layer; scoped off-ramp group created

Howard retested after Part 2 and the prompt was still there. Pulled the sign-in log from the Investigator SP (`AuditLog.Read.All`) and the failure was definitive:

- Error code **50125**
- `additionalDetails`: "User authentication was blocked because they need to provide password reset information. Their next interactive sign in will ask them for this, which the app should trigger next."
- `riskState: none`, all CA policies `result: notApplied`, `caStatus: success`, `authReq: singleFactorAuthentication`, `perUserMfaState` on the user: `disabled`

So the interrupt was **SSPR registration enforcement**, not MFA. The "Let's keep your account secure" UI is the Combined Security Info Registration page — it's shared between SSPR and MFA, but in this case SSPR is the trigger. SSPR is a tenant feature configured at Entra → Protection → Password reset, completely independent of CA policies and the Authentication Methods Registration Campaign.

### HIPAA / security analysis

Howard surfaced a concern that disabling SSPR registration could weaken security against the email-spoofing-and-sign-in attacks Cascades has seen. The answer:

SSPR registration enforcement is about *recovery* (letting users reset their own password if forgotten), not about *preventing attacks*. The attack pattern Howard described is blocked by CA policies, MFA enforcement, and Microsoft's risk-based detection — none of which are affected by SSPR scope.

Two fix options were considered:

- **Option A (chosen):** Scope SSPR enablement to a specific group containing only the staff who should retain SSPR; caregivers naturally excluded by not being in the group. Does not modify any per-user property — only group membership for scoping purposes. Office staff experience is identical to today (still get SSPR registration prompts if not yet registered; already-registered users see no change). MFA defense-in-depth preserved because the Authentication Methods Registration Campaign continues to nudge office staff to register Authenticator.

- **Option B (rejected):** Disable the tenant-wide "Require users to register when signing in?" toggle. Less surgical — would affect any future or currently-unregistered user across the whole tenant.

### Configuration Changes

#### New group: `SG-SSPR-Eligible`

- **ID:** `d6044864-a0ef-4c30-ba37-cdba7074437e`
- **Type:** Static security group (no membership rule)
- **Description:** "Members can use Self-Service Password Reset. Starting point for the SSPR migration off-ramp: as accounts are locked down with admin-managed password resets, remove from this group. SSPR scope in Entra portal must point to this group, not 'All'. Caregivers are intentionally excluded."
- **Initial membership (25 enabled human users — all current office and clinical staff):**
  - Allison Reibschied, Alyssa Brooks, Ashley Jensen, Britney Thompson, Christina Dupras, Christine Nyanzuda, Crystal Rodriguez, Dax Howard, JD Martin, Jodi Ramstack, John Trozzi, Karen Rossini, Lauren Hasselman, Lois Lane, Lupe Sanchez, Matthew Brooks, Megan Hiatt, Meredith Kuhn, Ramon Castaneda, Shelby Trozzi, Sharon Edwards, Susan Hicks, Tamra Matthews, Veronica Feller, Zachary Nelson
- **Intentionally excluded from initial membership:**
  - `pilot.test@cascadestucson.com` (caregiver)
  - Service / shared mailbox accounts: `kitchenipad`, `mdms`, `training`, `accounting`, `accountingassistant`, `admin`, `boadmin`, `devices`, `fax`, `frontdesk`, `hr`, `medtech`, `memcarereceptionist`, `nurse`, `security`, `sysadmin`, `transportation` — service accounts should be admin-managed for password resets, not self-service

#### Migration design

This group is the **off-ramp** for the eventual SSPR retirement. Plan:
1. As each office department gets its security hardening pass, the department's users will be evaluated for SSPR need vs. admin-managed reset
2. Users no longer needing SSPR get removed from `SG-SSPR-Eligible`
3. Eventually the group can shrink to admins-only, then deleted entirely with SSPR scoped to `None` or admin-only

### Howard's portal action (handed off)

After this session, Howard does the following step in the Entra portal:
1. Entra Admin Center → Protection → Password reset → Properties
2. "Self service password reset enabled" → switch from **All** to **Selected**
3. Pick **SG-SSPR-Eligible**
4. Save

Documented here so the next session can verify completion.

### Carryover open items

- [ ] Howard: complete the portal SSPR scope change above. Verify pilot.test sign-in to ALIS no longer interrupted.
- [ ] After pilot SSO succeeds end-to-end, the remaining ALIS question is whether the staff record's Email field for `pilot.test@cascadestucson.com` exists in ALIS. If not, create or temporarily map an existing staff record's Email to that UPN.

---

**Session duration through Part 3:** ~3 hours total
**Status at Part 3 update:** SG-SSPR-Eligible created and populated with 25 human staff; SSPR scope change deferred to Howard's portal action. Caregiver MFA architecture (Parts 1-3) complete pending the SSPR portal flip.

---

## Part 4 — Clean slate for next test (full wipe + Entra device cleanup)

ALIS sign-in functional once the SSPR layer was identified. Howard called for a complete reset of everything device-side to start the next round from a true zero state ("phones like the system has never seen them"). Full inventory pulled before doing anything destructive — turned up more state than expected.

### Inventory at decision time

**4 Intune managed phones** (all Samsung Galaxy SM-A146U, all currently online and SDM-enrolled):

| Name | Intune ID | Entra Device ID | Last sync | Compliance |
|---|---|---|---|---|
| CSC-R9TTC0JSDPJ | `01b8ba03-fd97-4e0f-ba94-4c1b9e5f5a12` | `185c05d1-cc40-4b70-a504-23ce97080152` | 17:51Z | compliant |
| CSC-R92W315YRLL | `1f05054e-8b6e-477a-a6ee-47749cb4adfb` | `6edb883e-18bb-4994-92ff-50488656a493` | 18:15Z | compliant (new today — added during session) |
| CSC-R92W310H31N | `a46a2daf-b8c5-4c19-ac71-0fdc7341928a` | `e2b0d244-6e25-4fd8-9a67-b0ab6bcb5f73` | 17:36Z | compliant |
| CSC-R9TW207FSXA | `41345e4a-c58f-4b0d-9678-cd6da47acf6a` | `5a693650-2ee9-4e25-8b29-da6891fe089d` | 18:32Z | compliant (came back online after 27h stale earlier in session) |

**2 orphan Entra device records** (no corresponding Intune record, leftover from earlier pre-SDM enrollment attempts):
- `samsungSM-F731U` (Entra object `2dfb6dbe-a552-4822-b19b-399bdb676cd6`, registered 2026-02-12)
- `samsungSM-A146U` (Entra object `fd13cfb2-d03b-4574-a210-a4d75e16b035`, registered 2026-05-08)

### ACG home tenant — Tenant Admin app manifest

To execute wipe + Entra-device-DELETE from API, two more Graph application permissions were added (PATCH application manifest + POST appRoleAssignment grant, same pattern as earlier today):

| Permission | Permission ID |
|---|---|
| `DeviceManagementManagedDevices.PrivilegedOperations.All` | `5b07b0dd-2377-4e44-a38d-703f09a0dc3c` |
| `Device.ReadWrite.All` | `1138cb37-bd11-4084-a2b7-9f71582aeddb` |

**Tenant Admin SP now holds 18 Graph application roles total** (up from 16 at end of Part 2). Updated full set:

```
AppRoleAssignment.ReadWrite.All
Application.ReadWrite.All
Device.ReadWrite.All                              (NEW Part 4)
DeviceManagementApps.Read.All
DeviceManagementConfiguration.Read.All
DeviceManagementConfiguration.ReadWrite.All
DeviceManagementManagedDevices.PrivilegedOperations.All  (NEW Part 4)
DeviceManagementManagedDevices.Read.All
Directory.ReadWrite.All
Policy.Read.All
Policy.ReadWrite.AuthenticationMethod
Policy.ReadWrite.ConditionalAccess
RoleManagement.ReadWrite.Directory
SecurityEvents.Read.All
Sites.FullControl.All
Sites.ReadWrite.All
User.ReadWrite.All
UserAuthenticationMethod.ReadWrite.All
```

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` and cleared the cached Cascades token before retrying.

### Destructive actions executed

**Phase 1 — Wipe (factory reset) all 4 Intune managed phones.** `POST /v1.0/deviceManagement/managedDevices/{id}/wipe` with body `{"keepEnrollmentData": false, "keepUserData": false, "useProtectedWipe": false}`. All four returned HTTP 204. CSC-R9TW207FSXA flipped to `managementState: wipeIssued` within seconds; the other three were still in `managed` state at verification but the wipe commands were accepted and queued via FCM. Each phone receives the wipe over Google Play Services, executes the factory reset, then the Intune record auto-removes when the phone fails to check in post-reset (typical lag 5-30 min).

**Phase 2 — Delete all 6 Entra device records.** `DELETE /v1.0/devices/{object-id}` issued for the 4 phone records plus the 2 orphan records. All six returned HTTP 204.

### Verification snapshot (immediately post-action)

| Category | State |
|---|---|
| Entra device records (Android) in tenant | **0** (was 6, including 2 orphans) ✓ |
| SG-Caregivers-Pilot device members | **empty** (was 2) ✓ |
| Intune managed CSC-* devices | 4 still listed; 1 already in `wipeIssued`, 3 in `managed` awaiting next check-in — auto-cleans 5-30 min post-reset |
| Cascades - Shared Phones device group | empty pending re-enrollment |
| Mobile app assignments (Alis, HelpAny, LinkRx, native apps) | unchanged — assignments persist on the apps, will re-apply when phones re-enroll |
| Compliance policy `CSC - Android Compliance` | unchanged |
| Device restrictions `CSC - Android Shared Phones Restrictions` v15 (with all 9 kiosk apps) | unchanged |
| Enrollment profile `CSC - Android Shared Phones (Entra SDM)` (id `9a0fcc6d-…`) | unchanged — same QR token `KJCFJUWKRCOGATEHBTGYJZXM`, expires 2027-05-07 |
| CA policies (all CSC-* + tenant defaults) | unchanged |
| SG-Caregivers-Pilot user membership (pilot.test) | unchanged |
| Registration Campaign exclusion | unchanged |
| SG-SSPR-Eligible group + members | unchanged |

### Resume path for next test

For each phone (after factory reset finishes physically):

1. Factory reset already initiated — phone reboots to "Welcome to your device" / Samsung setup wizard
2. On the "Sign in to Google" or "Add an account" prompt, **tap 6× in the empty area to bring up the QR scanner** (or follow the "afw#setup" pattern — depends on Android version)
3. Scan the SDM enrollment QR for profile `CSC - Android Shared Phones (Entra SDM)` (id `9a0fcc6d-0a88-466e-aa53-44401bb74fca`)
4. Phone auto-enrolls, downloads policies, applies kiosk mode v15 with all 9 tiles
5. Test caregiver sign-in: pilot.test@cascadestucson.com — should be silent (no MFA registration nudge, no SSPR nudge once Howard completes the portal SSPR scope change)
6. Tap Alis tile → expect silent SSO via Microsoft button (assuming ALIS staff record's Email matches the Entra UPN)

### Carryover for after the next test

- [ ] If any of the 4 Intune managed device records linger past 30 minutes post-wipe, DELETE them via `/beta/deviceManagement/managedDevices/{id}` (we now have `DeviceManagementManagedDevices.PrivilegedOperations.All` so this works from API).
- [ ] Confirm Howard's SSPR portal action (Part 3) is complete — Entra → Protection → Password reset → Properties → "Selected: SG-SSPR-Eligible" → Save.

---

**Session duration through Part 4:** ~3.5 hours total
**Status at Part 4 update:** Complete clean slate — 6 Entra device records deleted, 4 phone wipes issued and accepted, ready for fresh SDM enrollment on factory-reset hardware. Tenant Admin SP scope now covers wipe + Entra device DELETE for any future operations.

---

## Part 5 — Fleet re-enrollment + ALIS SSO end-to-end validation + MHS scaling issue (carryover)

### Re-enrollment of ~17 unique caregiver phones

Howard updated all phones to the same OS / Samsung One UI version before scanning the SDM enrollment QR, then enrolled the fleet. Final Intune count at end of session: **21 managed device records, ~17 unique serials** (4 are duplicate ghost records from re-wipes during the night). All members of `Cascades - Shared Phones` (dynamic group, rule `device.enrollmentProfileName -startsWith "CSC - Android Shared Phones"`).

Hardware mix:
- SM-A146U (US unlocked Galaxy A14 5G): R92W310H31N, R9TWA0SN2BD, R9TTC0JSDPJ, R9TW207FSXA, R92W315YRLL, R9TTC0LZM2A, R92W3165MLD, R92W40PQLPJ, R9TW20CHP1D, R92WC09ZNXM, R9TW20DGYKF
- SM-S146VL (Verizon / Tracfone Galaxy A14 5G): R92X10S624D, R92W60LRA8Z, R92X411HYEP, R92X617NT7X, R9TXA0T1V4L, R9TX500YAWN

All phones compliant in Intune within ~20-30 min of enrollment.

### ALIS SSO end-to-end VALIDATED on caregiver phone (architectural success)

Howard signed in as pilot.test on `CSC-R9TW207FSXA` (entraDeviceId ending `e2c0`):
- Tapped Alis tile in MHS
- Tapped "Sign in with Microsoft" on ALIS login page
- Microsoft auth completed silently (no MFA prompt, no SSPR prompt, no device-registration prompt — all the work in Parts 1-3 fully effective)
- ALIS detected the SSO config and signed pilot.test in via federated SSO
- **End-to-end caregiver → MHS → ALIS via Entra SSO is working.**

This validates the full architecture: SDM enrollment → MHS kiosk → web-link tiles → ALIS SSO → silent federated login. Ready for caregiver rollout planning pending the cosmetic MHS scaling issue (below) and the staff-record-email-match prep on the ALIS side for each real caregiver.

### MHS rendering / scaling issue (open carryover)

**Symptom:** ~67% of finished phones (4 of 6 at observation time, scaled up as more phones enrolled) show Microsoft Managed Home Screen rendering only in the upper portion of the display. The lower portion shows the Samsung One UI default launcher. When the user opens an app from MHS, the app fills MHS's letterboxed area; the bottom strip goes black. The unaffected ~33% of phones render MHS full-screen as expected.

**Diagnosis:**
- All phones on identical OS / Samsung One UI version (Howard pre-updated before SDM scan)
- All same hardware variant within each subgroup (SM-A146U or SM-S146VL)
- Same enrollment QR, same policies, same MHS app deployment
- Non-deterministic ~50% hit rate → race condition during MHS first launch OR MHS APK version variance from Google Play distribution timing
- Persists across `rebootNow` and `syncDevice` actions

**Attempts that did NOT fix it:**
1. `rebootNow` + `syncDevice` on the 4 affected phones (intuneIds `5b7e4313-…`, `f5dbbfa3-…`, `25782867-…`, `b68cb53c-…`). Phones rebooted; MHS came back with the same half-screen behavior.
2. **New MHS App Configuration Policy** (`CSC - MHS layout (force grid + portrait)`, id `27683709-7b78-4b52-9c53-bb4401955bbf`, base64 payload encoding `screen_orientation:1`, `set_grid_size:"4;6"`, `lock_home_screen:true`). Created via Graph after expanding Tenant Admin SP scope with `DeviceManagementApps.ReadWrite.All`. Assigned to `Cascades - Shared Phones`. Force-synced to affected phones. **No effect** — issue still present after policy propagated.

**Conclusion:** The MHS app config knobs available via Microsoft Graph do not address this issue. The remaining real fix paths require longer lifts than fit in this session:

- **Samsung Knox OEMConfig** — deterministic fix. Requires verifying Knox license status (especially for SM-S146VL Verizon variants which can have constrained Knox), deploying Samsung's OEMConfig app via Intune, building an OEMConfig policy that autogrants MHS overlay permission and overrides per-app aspect-ratio behavior. Estimated 1-2 hour setup, then deterministic across all phones.
- **Wait for Microsoft to patch MHS** — Microsoft pushes MHS updates regularly; this may resolve naturally as a newer APK version lands on the broken phones. No timeline.
- **Microsoft support ticket** — file with symptom + tenant ID; Microsoft has fixed similar Samsung-specific MHS issues in past releases.

**Important note for tomorrow:** ALIS works regardless of the scaling issue. Caregivers can use the phones; the visual is ugly (lower half showing Samsung launcher) but tap-on-tile → app-launch → ALIS-SSO all function correctly. Cosmetic issue, not a blocker for rollout.

### Manifest expansion #4: `DeviceManagementApps.ReadWrite.All`

Fourth manifest expansion of the day, same pattern as the other three:

| Permission | Permission ID | Why |
|---|---|---|
| `DeviceManagementApps.ReadWrite.All` | `78145de6-330d-4800-a6ce-494ff2d33d07` | Required to POST `mobileAppConfigurations` (MHS app config policy creation) |

**Tenant Admin SP now holds 19 Graph application roles total.** Updated full set:

```
AppRoleAssignment.ReadWrite.All
Application.ReadWrite.All
Device.ReadWrite.All
DeviceManagementApps.Read.All
DeviceManagementApps.ReadWrite.All           (NEW Part 5)
DeviceManagementConfiguration.Read.All
DeviceManagementConfiguration.ReadWrite.All
DeviceManagementManagedDevices.PrivilegedOperations.All
DeviceManagementManagedDevices.Read.All
Directory.ReadWrite.All
Policy.Read.All
Policy.ReadWrite.AuthenticationMethod
Policy.ReadWrite.ConditionalAccess
RoleManagement.ReadWrite.Directory
SecurityEvents.Read.All
Sites.FullControl.All
Sites.ReadWrite.All
User.ReadWrite.All
UserAuthenticationMethod.ReadWrite.All
```

Cascades re-consented (4th consent click of the day). Howard pattern is now well-rehearsed: each scope add takes ~5 min round-trip.

### Accountability note: incorrect Entra device classification in Part 4

In Part 4, when wiping the 4 Cascades phones, I also deleted two Entra device records I labeled "orphans": `samsungSM-A146U` (correctly orphan — used only by service accounts) and **`samsungSM-F731U`**. The `F731U` (Galaxy Z Flip 5) was **not** an orphan. It was a legitimate Workplace-Joined personal phone of an office staff member. I extended the "orphan" label from the 5/8 session log's notes about `samsungSM-A146U` without verifying via sign-in history. The data was available (Investigator SP has `AuditLog.Read.All`); I just didn't check before classifying.

**Impact:** Whoever owned the Z Flip 5 needs to re-Workplace-Join their phone on next sign-in (~30 seconds, one prompt). Recoverable, but a real user experience friction caused by my mistake. Entra device DELETEs have no soft-delete — irreversible.

**Lesson encoded for future sessions:** "no Intune side" ≠ "orphan." Personal Workplace-Joined phones have no Intune side by design. Before classifying any Entra device record as orphan, verify with sign-in history (deviceDetail.deviceId filter on signIns).

### John Trozzi sign-in prompts (separate, unrelated to my delete)

Howard reported "all users are asking to register their devices to log in" — investigation showed John Trozzi was prompted. Sign-in log analysis:

- John's Android sign-ins back to 2026-04-16 all have `deviceId: ""` — his phone has never been Workplace-Joined in the directory.
- The `samsungSM-F731U` I deleted was NOT his (sign-in deviceId match returned 0).
- His current `errCode 50097` + `50129` prompts are from the **Microsoft Authenticator app's own setup flow demanding Workplace Join** when re-authenticating, triggered when stale broker tokens expired naturally (25 days idle since last Authenticator sign-in).
- This is NOT caused by today's policy changes. The only policy targeting any office staff are the ones we excluded caregivers from (Registration Campaign), which *narrowed* enforcement, never expanded it.

**Resolution for John:** complete the "Register this device" prompt on his phone (one tap). His phone will Workplace-Join (just an Entra identity record, no Intune enrollment, no MHS, no caregiver restrictions). 30 seconds total. He's better off after — proper device identity for future MFA tokens.

### Audit of tenant-wide impact from today's changes

| Was every change scoped only to caregivers (or SP scope)? | Verification |
|---|---|
| CA policy flips | YES — `CSC - Block caregivers on non-compliant device` targets only `SG-Caregivers-Pilot` (1 user, pilot.test) |
| Registration Campaign exclusion | YES — exclusion targets only `SG-Caregivers-Pilot` group |
| SSPR scope group `SG-SSPR-Eligible` (pending portal step) | YES — additive group, doesn't change anyone's existing SSPR experience until Howard does the portal step |
| MHS app config policy (Part 5) | YES — three-layer scoping: group rule restricts to SDM-enrolled, all members are CSC-* dedicated phones, MHS app only installed on this group |
| Manifest scope expansions | Multi-tenant SP scopes — only affect SP capability, no per-user effect on Cascades users |
| 4 phone wipes | Only the 4 Cascades caregiver test phones from earlier in the day |
| 6 Entra device DELETEs | 4 correct (Cascades phones) + 1 correct (orphan A146U) + 1 incorrect (F731U personal phone) |

The 89 Windows PCs in Cascades' tenant are untouched. Zero iOS records. All office staff PCs / laptops continue to function exactly as yesterday.

### Carryover for next session (priority order)

1. **Knox OEMConfig setup** (P1) — the real fix for the MHS scaling issue
   - Verify Knox license status on SM-A146U and SM-S146VL phones
   - Deploy Samsung OEMConfig app via Intune
   - Build OEMConfig policy with overlay permission autograding + aspect-ratio override
   - Test on one broken phone, then roll out
2. **Howard SSPR portal step** (P1) — Entra → Protection → Password reset → Properties → "Selected" → SG-SSPR-Eligible → Save. Until this is done, office staff who haven't registered SSPR will continue seeing the registration nudge.
3. **John Trozzi Workplace Join completion** (P2) — guide John through the one-tap re-register on his phone. Or if he's already done it, verify a new Entra device record was created for him.
4. **The 4 still-syncing phones** (P2) — if they didn't complete enrollment overnight, factory reset + re-enroll.
5. **Ghost Intune device records cleanup** (P3, cosmetic) — needs `DeviceManagementManagedDevices.ReadWrite.All` scope (one more manifest+consent), then DELETE the ~4 ghost records. Or use the Intune portal.
6. **ALIS staff-record-email-match prep** (P1) — for the real-caregiver rollout, every Cascades caregiver who uses ALIS needs their ALIS staff record's Email field set to match their Entra UPN exactly. Without exact match → "user not found" on SSO sign-in.
7. **Verify Microsoft BAA + ALIS BAA** (P2 — HIPAA carryover from earlier docs) — `m365.md:288` and `billing-log.md:254`.

### Reference IDs

| Object | ID | Notes |
|---|---|---|
| MHS app config policy (new) | `27683709-7b78-4b52-9c53-bb4401955bbf` | Force grid_size + portrait; no observed effect on half-screen issue |
| SG-SSPR-Eligible group (Part 3) | `d6044864-a0ef-4c30-ba37-cdba7074437e` | 25 human staff members, awaiting portal SSPR scope flip |
| Cascades - Shared Phones group | `ea96f4b7-3000-45da-ab1f-ddb28f509526` | Dynamic, 19 current members |
| SDM enrollment profile | `9a0fcc6d-0a88-466e-aa53-44401bb74fca` | Token `KJCFJUWKRCOGATEHBTGYJZXM`, expires 2027-05-07 |
| Device restrictions profile | `070a76c2-a8c3-4f7f-9ba7-1f4ac5084184` | v15 with 9 kiosk apps (Alis, HelpAny, LinkRx, Outlook, Teams, Authenticator, Edge, MHS, CP) |
| MHS app | `5dbe0c97-85fa-4e66-9765-2f02ec9d99d7` | com.microsoft.launcher.enterprise |

---

**Total session duration:** ~7+ hours (started 2026-05-11 ~11:00 PT, ended ~17:00 PT)
**Final state at wrap:** Caregiver architecture functionally validated (ALIS SSO working). 19 SDM phones enrolled in tenant. MHS scaling issue open, deferred to Knox OEMConfig followup. Tenant Admin SP at 19 Graph roles. One personal Workplace-Join record (Z Flip 5) incorrectly deleted — affected user needs ~30 sec re-register on next sign-in. John Trozzi prompt resolves via same Workplace Join flow (unrelated to today's changes). All other office staff devices and policies untouched.

## Note for Mike

If you read this in the morning before Howard resumes:

1. **Caregiver shared-phone architecture is validated end-to-end.** Pilot.test signed into ALIS from a caregiver phone via Microsoft SSO with zero prompts (no MFA registration, no SSPR, no device registration). The whole stack works.

2. **MHS rendering is cosmetically broken on ~67% of phones.** Half screen, ugly, but functional — caregivers can tap tiles and apps launch. Fix is Knox OEMConfig in next session.

3. **I incorrectly deleted one personal phone's Entra Workplace-Join record** today thinking it was an orphan. It was the Galaxy Z Flip 5 of an unknown office staff member. They'll see a one-time "register this device" prompt next sign-in and recover in ~30 sec. Documented in the accountability section above.

4. **Tenant Admin SP scopes added today** (4 manifest expansions): `Policy.ReadWrite.AuthenticationMethod`, `DeviceManagementManagedDevices.PrivilegedOperations.All`, `Device.ReadWrite.All`, `DeviceManagementApps.ReadWrite.All`. SP is now at 19 Graph application roles. These are now available against any tenant that re-consents to the app.

5. **HIPAA compensating-controls architecture document created** at `clients/cascades-tucson/docs/security/hipaa-caregiver-controls.md`. Worth a read-through for the audit-defensibility argument. Cross-referenced from `hipaa.md` table.
