Files
claudetools/clients/cascades-tucson/session-logs/2026-06/2026-06-30-howard-caregiver-phone-sso-license-onboarding.md
Howard Enos 6cc0c08ac4 sync: auto-sync from HOWARD-HOME at 2026-06-30 08:45:13
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-06-30 08:45:13
2026-06-30 08:45:47 -07:00

91 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## User
- **User:** Howard Enos (howard)
- **Machine:** Howard-Home
- **Role:** tech
## Session Summary
Resumed the Cascades caregiver phone-SSO rollout. The goal: get caregiver staff onto the shared Samsung phones with silent ALIS SSO, which requires each caregiver to be (1) in the `SG-Caregivers` security group (so they bypass the tenant-wide all-users-MFA CA policy and fall under the location+device posture instead), (2) M365-licensed, and (3) ALIS staff `Email` = Entra UPN. This session completed the Entra/identity side (group + license + AD temp passwords); the ALIS email-match was left to Howard.
Started blocked: GuruRMM (`172.16.3.30:3001`) and the coord API (`:8001`) were unreachable from Howard-Home while the Cascades VPN (`192.168.0.1`) was up — the ACG-internal `172.16.x` route was down. Howard reconnected the ACG VPN and RMM came back (ping 54ms, API HTTP 422 on empty body = up).
Established live state via read-only RMM (AD) and Graph (Entra) pulls: `OU=Caregivers` holds 42 objects = 40 enabled real caregivers + `pilot.test` (test artifact, licensed, logged in) + `n.castro` (disabled). `SG-Caregivers` started at 38 members (all in `OU=Caregivers`, no admins/managers). All 40 real caregivers were UNLICENSED — confirmed the "caregivers we've been waiting on" are the unlicensed population (no other department had unlicensed enabled staff). All 40 had NEVER logged into the domain (`lastLogon`/`lastLogonTimestamp` = NEVER; bulk-created 2026-05-16/18).
Cross-referenced the AD caregiver roster against the live ALIS staff roster (107 Hired, communityId 622) by name (ALIS `primaryEmail` is blank or personal for nearly all, so email-join was not viable). Of the 40 AD caregivers: 23 carry an ALIS caregiver job role (Certified/Resident Caregiver), 5 are ALIS "Med Tech", 5 are in ALIS with a blank job role, and 7 have NO ALIS staff record at all. 3 ALIS caregivers (Judith Palmer, Joey Ty, Alejandra Vallejo) have no AD account.
Executed the writes after Howard's go: added Celia Lassey + Patricia Sandoval-Beck to `SG-Caregivers` (the only 2 of 40 missing) → group now 40. Howard bought 11 additional Business Premium (SPB) seats mid-session (SKU went 34→45 enabled); assigned Business Premium to all 40 (set `usageLocation=US` first, then `assignLicense` — two passes due to Graph propagation lag on usageLocation). Generated unique phone-typeable temp passwords for all 40, reset them in AD with `ChangePasswordAtNextLogon=true` via RMM, vaulted them, and delivered the list to Howard via Discord DM.
## Key Decisions
- **`SG-Caregivers` = frontline caregivers ONLY** (Howard's correction). Reversed the prior 6/4 plan to add Veronica Feller + Christine Nyanzunda — both are admin-adjacent (Feller in `OU=Care-Assisted Living`, Nyanzunda in `OU=Care-Memorycare`), so excluded. Also excluded `pilot.test` (test artifact) and `n.castro` (disabled).
- **License SKU = Microsoft 365 Business Premium (SPB)**, not Office 365 Standard (O365_BUSINESS_PREMIUM is suspended: 0 enabled / 37 suspended). Business Premium also includes Entra ID P1, which the caregiver Conditional Access lockdown requires per-user.
- **Licensed all 40** once Howard purchased the extra 11 seats (29 free → 45 enabled/40 free). Original plan was 29-now/defer-11; the purchase removed the shortfall.
- **Membership change is on-prem only** — `SG-Caregivers` is an on-prem AD group synced via Entra Connect; cloud/Graph adds fail (HTTP 400). All group writes done on CS-SERVER via RMM.
- **Name-based ALIS reconciliation** — ALIS `primaryEmail` is blank/personal for ~all caregivers, so matched on surname rather than email.
- **Temp passwords forced-change + vaulted** — generated locally (control + vaulting), set via RMM, stored in SOPS, plaintext scratch deleted. Hybrid PHS means the AD password is also the M365/phone sign-in.
## Problems Encountered
- **RMM/coord unreachable at session start** — `172.16.3.30` (ACG-internal) not routable from Howard-Home though Cascades VPN was up. Resolved when Howard reconnected the ACG VPN. Logged as `--friction` in errorlog.
- **`get-token.sh` read the wrong `identity.json`** (`~/.claude/identity.json`, no `vault_path`) instead of the repo one. Worked around with `VAULT_ROOT_ENV="D:/vault"`.
- **`--json` is a global flag** for `alis.py` (before the subcommand), not per-subcommand; `alis staff --json` errored until moved to `alis --json staff`.
- **`assignLicense` "invalid usage location"** — Graph eventual-consistency: assigning a license in the same call right after the `usageLocation` PATCH fails. Resolved by two passes (set all usageLocations, then assign all).
- **`UID` is a readonly shell variable** — using it for a UPN expanded to the OS uid (197609) → Graph 404. Renamed to `U`.
- **ALIS auto-match polluted by placeholder records** — agency-pool staff with blank surnames ("Preferred Home 1-3", "Reliable 1-3") matched everything via empty-string containment; filtered out for the real reconciliation.
- **Vault `get-field` returned null** on the temp-password entry — keys contain dots (`a.mcferren`) which break dot-notation. Data is correct; retrieve via full `vault get`.
## Configuration Changes
- **AD (CS-SERVER, cascades.local):**
- `SG-Caregivers` += `c.lassey`, `p.sandoval-beck` (group now 40 members).
- All 40 `OU=Caregivers` enabled accounts: AD password reset + `ChangePasswordAtLogon=true`, `PasswordNeverExpires=false`.
- **M365 (cascadestucson.com, tenant 207fa277-e9d8-4eb7-ada1-1064d2221498):**
- All 40 caregivers: `usageLocation=US` + Business Premium (SPB) license assigned.
- **Vault:** created `clients/cascades-tucson/caregiver-temp-passwords-2026-06-30.sops.yaml` (40 entries, committed + pushed).
- **errorlog.md:** 1 `--friction` (172.16.3.30 unreachable) + 1 `--correction` (SG-Caregivers = caregivers only).
## Credentials & Secrets
- **Caregiver AD temp passwords (40):** vaulted at `clients/cascades-tucson/caregiver-temp-passwords-2026-06-30.sops.yaml`. Keys = sAMAccountName (= UPN local part). All forced-change-at-next-login. Hybrid PHS → also the M365/phone sign-in. Retrieve with `bash /d/vault/scripts/vault.sh get clients/cascades-tucson/caregiver-temp-passwords-2026-06-30.sops.yaml` (NOT get-field — dotted keys). Delivered to Howard via Discord DM.
- **GuruRMM API:** `infrastructure/gururmm-server.sops.yaml` (`credentials.gururmm-api.admin-email`/`admin-password`).
- **ALIS API user:** `clients/cascades-tucson/alis-api-howard-user.sops.yaml` (username must be tenant-qualified `howard.enos@cascadestucson`).
- **M365 MSP apps:** Security Investigator `bfbc12a4-f0dd-4e12-b06d-997e7271e10c` (read), User Manager `64fac46b-8b44-41ad-93ee-7da03927576c` (write). Tokens via `get-token.sh <tenant> <tier>` with `VAULT_ROOT_ENV="D:/vault"`.
## Infrastructure & Servers
- **CS-SERVER** — DC/DNS/file/Hyper-V, cascades.local; GuruRMM agent `c39f1de7-d5b6-45ae-b132-e06977ab1713` (resolve live; UUID changes on re-enroll). Clients reach it at 192.168.2.248 (the .254 NIC is Hyper-V vEthernet).
- **GuruRMM API:** `http://172.16.3.30:3001` (also coord `:8001`; ClaudeTools DB).
- **M365 tenant:** cascadestucson.com, `207fa277-e9d8-4eb7-ada1-1064d2221498`.
- **Business Premium (SPB) SKU:** `cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46`; now 45 enabled / 45 consumed / 0 free.
- **ALIS:** communityId 622 (Cascades of Tucson); `https://cascadestucson.alisonline.com`; API `https://api.alisonline.com` (staff endpoints read-only).
- **`OU=Caregivers,OU=Departments,DC=cascades,DC=local`** — 42 objects (40 real caregivers + pilot.test + disabled n.castro). `SG-Caregivers` GUID `8b8d9222`.
## Commands & Outputs
- License seat check: `GET https://graph.microsoft.com/v1.0/subscribedSkus` → SPB enabled=34→45, free=29→40 after Howard's purchase.
- License assign (per user): PATCH `/users/{upn}` `{"usageLocation":"US"}` (204), then POST `/users/{upn}/assignLicense` `{"addLicenses":[{"skuId":"cbdc14ab-..."}],"removeLicenses":[]}`. Result: assigned OK=40 FAIL=0.
- AD group add: `Add-ADGroupMember -Identity SG-Caregivers -Members c.lassey,p.sandoval-beck` → group count 40, both verified.
- AD password reset (per user): `Set-ADAccountPassword -Identity <sam> -Reset -NewPassword (ConvertTo-SecureString <pw> -AsPlainText -Force)` + `Set-ADUser -ChangePasswordAtLogon $true -PasswordNeverExpires $false` → pwreset OK=40 FAIL=0.
- ALIS roster: `alis --json staff --status Hired --limit 300` → 107 staff; jobRole distribution: 24 Certified Caregiver, 5 Med Tech, 2 Resident Caregiver (non-certified), plus directors/managers/support.
## Pending / Incomplete Tasks
- **ALIS email-match (Howard is handling)** — set each caregiver's ALIS staff `Email` = Entra UPN so "Sign in with Microsoft" resolves on the phones. Build path: `alis` skill (`build-import` → upload .xls in ALIS UI; no staff-write API). Buckets:
- 23 confirmed ALIS caregivers (Certified/Resident Caregiver) — just need Email=UPN.
- 5 in ALIS with blank job role (Atwood, Hogan, Huerta, Lopez, Reed) — confirm caregiver + Email=UPN.
- 5 Med Techs (Camarena Doran, Clarke, Esperance, R. Flores, Padilla) — Email=UPN (Howard earlier said med-techs were "ignore for the moment"; revisit).
- 7 with NO ALIS staff record (Baker, Fierros, K. Flores, Kariuki, Mendoza, Tate, Williford) — create ALIS records before SSO can work.
- 3 ALIS caregivers with no AD account (Judith Palmer, Joey Ty, Alejandra Vallejo) — create AD accounts if they need phones.
- **Turn off ALIS-native 2FA** for the caregiver bucket (blanket) as records are matched.
- **Zeke Huerta** stays `e.huerta@cascadestucson.com` (Howard: leave as-is, do not "correct" to z.huerta) — ALIS Email must therefore be `e.huerta@`.
- The 11 extra Business Premium seats were applied this session, so no deferred-license batch remains.
## Reference Information
- Session work: caregiver phone SSO — group + license + temp-password onboarding (Cascades, Syncro customer 20149445).
- RMM command IDs: SG add `2d55103c`, license validation `a.mcferren`, password reset `8fffbe4e`, membership/logon reads `5ca1e5bf`/`00a755c8`/`34a62f0c`/`f8859540`/`6218a452`/`2847353a`.
- Vault entry: `clients/cascades-tucson/caregiver-temp-passwords-2026-06-30.sops.yaml`.
- ALIS worklist (prior): `clients/cascades-tucson/reports/2026-06-04-caregiver-alis-sso-worklist.md`.
- Architecture reference: `wiki/clients/cascades-tucson.md` ("Entra Access Architecture").
- Discord DMs to Howard: caregiver roster + temp password sheet (message IDs 1521265741137969152, 15215290114973369021521529041474031733).