## 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, 1521529011497336902–1521529041474031733).
