diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index ebe5e12..b3aeb99 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -37,6 +37,7 @@ - [Syncro — timer_entry response is FLAT](feedback_syncro_timer_response_shape.md) — POST /tickets/{id}/timer_entry returns `{"id": N, ...}` directly, NOT `{"timer": {...}}`. Parse as `.id`. The skill doc's `.timer.id // .timer_entry.id` fallback always resolves to null and causes duplicate-timer retries. Hit on #32253 2026-05-05. - [Syncro — warranty has its own product, never patch dollar amounts](feedback_syncro_warranty_product.md) — Warranty/no-charge work uses product `1049360` (Labor- Warranty work, $0). Do NOT use Remote/Onsite + `billable: false` — Syncro silently overrides the flag. Do NOT patch `price_retail` to convert one labor product into another; pick the correct product and re-run. Hit on #32225 2026-05-06. - [SQL instance role — verify by connections, not name](feedback_sql_instance_role_by_connection.md) — Standard installed under default `SQLEXPRESS` instance name is real. Prove role with `sys.dm_exec_sessions` + `Get-NetTCPConnection -OwningProcess` before recommending stop/uninstall. IMC1 2026-05-05/06 near-miss. +- [Syncro — confirm appointment owner explicitly](feedback_syncro_appointment_owner.md) — When creating tickets with appointments, always ask "who is the appointment owner?" in the preview. Don't auto-default to ticket's assigned tech. Don't add additional attendees without explicit confirmation. Howard caught on Kittle ticket #32263 2026-05-08. ## Machine - [ACG-5070 Workstation Setup](reference_workstation_setup.md) - Windows 11 Pro clean install 2026-03-30, replaced CachyOS. All tools installed. diff --git a/.claude/memory/feedback_syncro_appointment_owner.md b/.claude/memory/feedback_syncro_appointment_owner.md new file mode 100644 index 0000000..fbc47e6 --- /dev/null +++ b/.claude/memory/feedback_syncro_appointment_owner.md @@ -0,0 +1,40 @@ +--- +name: Syncro — confirm appointment owner explicitly when creating tickets with appointments +description: When creating Syncro tickets that include an appointment, always ask "who is the appointment owner?" before posting. Don't auto-default to the ticket's assigned tech, and distinguish owner from additional attendees. +type: feedback +--- + +**Rule:** When creating a Syncro ticket that includes an appointment (Onsite, Remote, Phone Call, etc.), explicitly **ask the user who the appointment owner is** in the preview phase. Do not assume the appointment owner equals the ticket's assigned tech, and do not silently add other techs as attendees. + +**Why:** The appointment owner is the person whose calendar the appointment lands on as the primary entry — they are the one accountable for being there. Additional `user_ids` in the appointment payload only add the entry to other techs' calendars as secondary/visible items, which clutters their schedule and creates ambiguity about who is actually on the hook for the visit. Howard caught this on 2026-05-08 after a ticket creation where I added the assigned tech to `user_ids` without confirming whether they should be the owner versus an attendee. + +**How to apply:** + +In the ticket creation preview (Step 3 of the ticket creation workflow), present the appointment block with the OWNER as a separate, explicit field — not buried as an inferred default. Example preview format: + +``` +APPOINTMENT +----------- +Type: Onsite +Owner: +Additional attendees: (optional, leave blank unless explicitly added) +Start: +End: +Location: +``` + +In the API payload, the appointment owner is the FIRST or PRIMARY entry in `user_ids`. Confirm: + +- The owner is the person actually attending the appointment (or the lead tech if multiple). +- If the user wants ONLY the owner with no co-attendees, `user_ids` should contain ONE id only. +- If the user wants additional attendees (e.g., "Mike will join remote, Howard onsite"), add them only after explicit confirmation in the preview. + +**What NOT to do:** + +- Do NOT auto-add the ticket's `user_id` (assigned tech) as the appointment owner without asking. +- Do NOT add additional attendees to `user_ids` without explicit user direction. +- Do NOT treat appointment owner as a passive inheritance from the ticket — surface it as an active confirmation field in the preview. + +**Trigger context:** + +Howard created the Kittle Design ticket (#32263) on 2026-05-08 for an 11:30 AM onsite to set up Joshua. I auto-added Howard's `user_id` to the appointment's `user_ids` array without confirming whether Howard was the owner or just an attendee. Howard flagged: "when setting up an appointment confirm the appointment owner — don't just add additional attendees." Save as a rule for syncro ticket creation. diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock index cc2dadf..216225e 100644 --- a/.claude/scheduled_tasks.lock +++ b/.claude/scheduled_tasks.lock @@ -1 +1 @@ -{"sessionId":"8a956328-8afb-492a-a3d3-709f80396122","pid":14796,"acquiredAt":1778100485870} \ No newline at end of file +{"sessionId":"f9033f52-984c-4db6-b26e-9071e65b9ee9","pid":19248,"acquiredAt":1778107526500} \ No newline at end of file diff --git a/clients/cascades-tucson/session-logs/2026-05-08-howard-cascades-sdm-token-success-and-alis-sso.md b/clients/cascades-tucson/session-logs/2026-05-08-howard-cascades-sdm-token-success-and-alis-sso.md new file mode 100644 index 0000000..74545c0 --- /dev/null +++ b/clients/cascades-tucson/session-logs/2026-05-08-howard-cascades-sdm-token-success-and-alis-sso.md @@ -0,0 +1,224 @@ +# Cascades — SDM token-type enrollment cracked + ALIS SSO infrastructure live + +**Date:** 2026-05-08 +**Client:** Cascades of Tucson (Syncro 20149445, Tenant `207fa277-e9d8-4eb7-ada1-1064d2221498`) + +## User +- **User:** Howard Enos (howard) +- **Machine:** Howard-Home +- **Role:** tech +- **Session span:** ~9 hours, full work day. End-to-end SDM rollout breakthrough. + +## Session Summary + +Investigated and resolved Cascades caregiver phone Shared Device Mode (SDM) issues by identifying a misconfigured enrollment profile using the default token type instead of the required "Corporate-owned dedicated device with Microsoft Entra ID shared mode" token type. A new enrollment profile was created and the old one deleted to ensure proper SDM configuration. The dynamic group rule was updated to allow automatic inclusion of devices from the new profile. Two test phones were wiped and re-enrolled using the new SDM token QR, successfully registering as shared devices. The end-to-end caregiver workflow was validated, confirming correct behavior of Microsoft Teams, Outlook, and sign-out functionality. ALIS SSO infrastructure was configured with Entra app registration values and credentials were vaulted. Web shortcuts were replaced with Android Enterprise type links to ensure visibility on kiosks. Device restrictions were updated with the Cascades-of-Tucson logo. A project update was added to the Cascades Entra setup ticket. Phones remain powered on for web link tile propagation and ALIS SSO testing in the next session. + +## Key Decisions + +- Chose to replace the existing enrollment profile with a new one using the correct SDM token type to align with Microsoft's recommended configuration for Android Enterprise dedicated devices in SDM. +- Updated the dynamic group rule from exact-match to startsWith to ensure compatibility with the new enrollment profile and automatic device grouping. +- Replaced basic Intune web links with Android Enterprise type (Managed Google Play web links) to ensure visibility on Android Enterprise kiosks. +- Vaulted Inbound Connections Basic Auth credentials for future Microsoft-to-ALIS API integrations. +- Wallpaper field uses the existing landscape Cascades logo URL on cascadestucson.com — known to stretch on portrait phone screens but acceptable as a starting visual; portrait-format file deferred until someone with WordPress access can upload one. + +## Problems Encountered + +- Initial SDM activation failures from prior sessions traced to incorrect token type on the enrollment profile. Resolved by identifying the correct token type from Microsoft documentation (https://learn.microsoft.com/en-us/intune/device-enrollment/android/setup-dedicated) and replacing the old profile. +- Old "Web link" type apps (`microsoft.graph.webApp`) did not render as tiles on Android Enterprise dedicated kiosks. Resolved by deleting and re-creating as Managed Google Play web links (`androidManagedStoreWebApp` type) which surface automatically as tiles. +- Web link tiles still not visible on phones at end of day; configuration verified correct (assignments, group membership, publishingState=published, isAssigned=true). Diagnosed as Google Managed Play distribution lag (typical 30 min to a few hours, sometimes overnight). Phones left powered on at Cascades to receive distribution overnight. + +## Configuration Changes + +### New Intune enrollment profile + +- **`CSC - Android Shared Phones (Entra SDM)`** (id `9a0fcc6d-0a88-466e-aa53-44401bb74fca`) + - Token type: **Corporate-owned dedicated device with Microsoft Entra ID shared mode** + - Token: `KJCFJUWKRCOGATEHBTGYJZXM` + - Token expires: 2027-05-07 + - Naming template: `CSC-{{SERIAL}}` + +### Old enrollment profile removed + +- **`CSC - Android Shared Phones`** (was id `3345721a-d9c3-4c79-9b3a-5c5e68849a9f`) — DELETED via Graph API. Profile used the default "Corporate-owned dedicated device" token type which doesn't activate SDM. + +### Dynamic group rule update + +`Cascades - Shared Phones` (id `ea96f4b7-3000-45da-ab1f-ddb28f509526`) — membershipRule changed from `(device.enrollmentProfileName -eq "CSC - Android Shared Phones")` to `(device.enrollmentProfileName -startsWith "CSC - Android Shared Phones")` so phones from either old or new profile name auto-join. Confirmed both new test phones (CSC-R92W310H31N, CSC-R9TW207FSXA) became members within ~5 min of registration. + +### Device restrictions profile (`CSC - Android Shared Phones Restrictions`, id `070a76c2-a8c3-4f7f-9ba7-1f4ac5084184`) + +- Bumped to **version 14** today +- Added: `kioskModeWallpaperUrl: https://cascadestucson.com/wp-content/uploads/2023/06/CascadesOfTucson-logo.png` + +### Mobile apps — replaced wrong-type web shortcuts + +| App | OLD (deleted) | NEW (created today) | New ID | +|---|---|---|---| +| ALIS / Alis | `fcbf803d-ceb7-4f4e-93ed-2be1b91a05f3` (webApp, wrong type) | `androidManagedStoreWebApp` | `8c0ae9bf-000d-4ae4-9b41-74afd186ad37` | +| Helpany / HelpAny | `97c294de-03ec-4053-b272-a4c956e408e9` (webApp) | `androidManagedStoreWebApp` | `cbb9404b-2413-40c1-823d-e10337d5238f` | +| LinkRx | `e4157faf-c47d-443d-96b3-59d7c4ba9ac2` (webApp) | `androidManagedStoreWebApp` | `c70f62bc-a2ff-4744-925a-a409e38c6690` | + +All three new web links: `intent: required`, `target: Cascades - Shared Phones group`, `publishingState: published`. + +### Test phones re-enrolled (clean Shared Devices) + +| Serial | Intune ID (today) | Entra device | profileType | +|---|---|---|---| +| R92W310H31N | `a46a2daf-b8c5-4c19-ac71-0fdc7341928a` | `CSC-R92W310H31N` | **Shared** ✓ | +| R9TW207FSXA | `41345e4a-c58f-4b0d-9678-cd6da47acf6a` | `CSC-R9TW207FSXA` | **Shared** ✓ | + +Both `trustType: Workplace`, `registeredOwners: 0`, `registeredUsers: 0`, `joinType: azureADRegistered`. + +### ALIS App Store / Microsoft SSO app configuration (on cascadestucson.alisonline.com) + +Configured by Howard via the ALIS admin UI: +- Outbound Connections → Provider Parameters: Directory ID, Application ID, Client Secret Value populated from Entra App Registration +- Inbound Connections (ALIS API): generated Basic Auth credentials (vaulted) +- ALIS install key: `d796539d-356b-4190-9c17-35f0f1129376` + +### Cascades Entra setup ticket #32214 — customer-visible comment posted + +Comment id `409911490` — "Project update 2026-05-08" — `hidden: false`, `do_not_email: true`. + +### Vault updates + +- `clients/cascades-tucson/alis-sso-app-registration.sops.yaml` — extended with ALIS Inbound Connections Basic Auth credentials + ALIS install key. Vault commit `25b0ed7`. + +## Credentials & Secrets + +### ALIS App Store SSO app — Inbound Connections (Basic Auth) +- **Username:** `microsoft@cascadestucson` +- **Password:** `nvw3JCL3VY8401N` +- **Auth Header:** `Basic bWljcm9zb2Z0QGNhc2NhZGVzdHVjc29uOm52dzNKQ0wzVlk4NDAxTg==` +- **Vault:** `clients/cascades-tucson/alis-sso-app-registration.sops.yaml` (vault commit `25b0ed7`) +- **Purpose:** Credentials for any future Microsoft → ALIS API call (currently unused; SSO sign-in itself doesn't require these — that's pure OIDC). + +### Entra App Registration (unchanged from yesterday, listed for completeness) +- **Application ID:** `d5108493-cba8-4f08-90b6-1bb0bc09eb2a` +- **Directory ID:** `207fa277-e9d8-4eb7-ada1-1064d2221498` +- **Client Secret Value:** `cCf8Q~eT3uKOqtW2DtLWxxP1uCSHUWFYimXYvdiJ` +- **Secret expires:** 2028-05-06 +- **Vault:** `clients/cascades-tucson/alis-sso-app-registration.sops.yaml` + +### `devices@cascadestucson.com` (provisioning account, unchanged) +- Password `Gptf*77ttb!`. Cloud Device Administrator role. +- **Note:** Today's SDM-token enrollment did NOT actually require devices@ to register the phones — the platform handled registration automatically using the enrollment token's authority. The account is still useful for any future operations that need a CDA. + +### Pilot caregiver test user (unchanged) +- `pilot.test@cascadestucson.com` / `8ajau==j2_MeBdW5XccKUEwx` +- Vault: `clients/cascades-tucson/pilot-test-user.sops.yaml` + +## Infrastructure & Servers + +### Tenant +- Tenant ID: `207fa277-e9d8-4eb7-ada1-1064d2221498` +- Default domain: `cascadestucson.com` +- Cascades Named Location: `061c6b06-b980-40de-bff9-6a50a4071f6f` (IPs `72.211.21.217/32` and `184.191.143.62/32`) + +### Intune objects (current state) + +| Object | ID | Notes | +|---|---|---| +| Enrollment profile | `9a0fcc6d-0a88-466e-aa53-44401bb74fca` | CSC - Android Shared Phones (Entra SDM) | +| Dynamic group | `ea96f4b7-3000-45da-ab1f-ddb28f509526` | Cascades - Shared Phones (rule = startsWith) | +| Device restrictions profile | `070a76c2-a8c3-4f7f-9ba7-1f4ac5084184` | v14, includes wallpaper URL | +| Compliance policy | `27eeaeda-8390-462e-a514-7d2a558f412c` | CSC - Android Compliance | +| Authenticator MSDM app config | `a1bfbda0-a36c-45e5-8844-8470f80ecc8d` | Manual config, redundant under SDM-token enrollment but kept | +| Teams MSDM app config | `3c6a354c-1616-434b-ac81-4dad7795e67b` | Manual config, redundant under SDM-token enrollment but kept | + +### Mobile apps assigned to Cascades - Shared Phones group + +Native: Microsoft Authenticator, Microsoft Teams, Microsoft Outlook, Microsoft Edge, Managed Home Screen, Intune Company Portal. +Managed Google Play web links (new today): Alis, HelpAny, LinkRx. + +## Commands & Outputs + +### Confirm SDM activation on phones (Microsoft canonical marker) +```bash +curl -sk -H "Authorization: Bearer $TOK_TA" \ + "https://graph.microsoft.com/beta/devices?\$filter=startswith(displayName,'CSC')&\$top=10" | \ + jq '.value[] | {displayName, profileType, trustType, enrollmentProfileName}' +``` +Result for today's phones: `profileType: "Shared"` on both — confirms SDM is genuinely active. (Yesterday's failed attempts had `profileType: RegisteredDevice` instead.) + +### Force Managed Google Play sync (to pull new web links into Intune) +```bash +curl -sk -X POST -H "Authorization: Bearer $TOK" \ + -H "Content-Type: application/json" --data '{}' \ + "https://graph.microsoft.com/beta/deviceManagement/androidManagedStoreAccountEnterpriseSettings/syncApps" +# HTTP 200 — new web links appeared in Intune apps list within 30 sec +``` + +### Update CA policy state (caregiver scope) — pattern for flipping Report-only -> Enforced +```bash +curl -X PATCH -H "Authorization: Bearer $TOK_TA" -H "Content-Type: application/json" \ + --data '{"state":"enabled"}' \ + "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/$ID" +# Sleep 6+ seconds before verifying read (eventual consistency). +``` + +### Sign-in test result (Phone A, pilot.test) +- Microsoft Teams sign-in: clean, no AADSTS50097, no register-device prompt +- Microsoft Outlook: silent broker sign-in (no password) +- Teams "Sign out": cleared all M365 sessions device-wide + +## Pending / Incomplete Tasks + +### Resume next session +- [ ] Verify the three Managed Google Play web link tiles (Alis, HelpAny, LinkRx) have appeared on both phones (they were propagating from Google when Howard left for the day; phones left powered on at Cascades to receive distribution overnight) +- [ ] End-to-end ALIS SSO sign-in test from phone: + - Make sure phone has pilot.test signed in (Teams + Outlook silent) + - Tap Alis tile in MHS + - Expected: ALIS detects SSO config server-side → redirects to Entra → broker silent-auth → ALIS opens with pilot.test logged in (no password) + - If working: SSO is fully functional, ready for staged caregiver rollout + +### Production rollout (after pilot SSO verified) +- [ ] Each Cascades caregiver who uses ALIS needs their ALIS staff record's Email field set to match their Entra UPN exactly (e.g., `firstname.lastname@cascadestucson.com`). This is the SSO join key. Without exact email match → ALIS errors "user not found" on SSO sign-in. +- [ ] Plan staged caregiver rollout — flip ONE user at a time. Per Medtelligent's docs: "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." Linking is admin-reversible per-user but not user-reversible. +- [ ] Provision the remaining 30 phones using the proven SDM-token enrollment profile playbook (factory reset → scan QR for `CSC - Android Shared Phones (Entra SDM)` → wait ~15 min → done). + +### Cosmetic / nice-to-have +- [ ] Replace wallpaper with a portrait-format Cascades logo image when someone with cascadestucson.com WordPress access can upload one. The current landscape image stretches on portrait phone screens. +- [ ] Investigate (carefully) MHS welcome-screen branding logo — would require an MHS app config policy with documented keys only (not the speculative-key approach that crashed the install loop earlier in the project). +- [ ] Flip the third caregiver CA policy `CSC - Block caregivers on non-compliant device` from Report-only to Enforced once pilot SSO is verified working and joinType propagation is reliable across all phones (currently in Report-only because some sign-ins evaluated as `reportOnlyFailure` due to device.isCompliant not always being true on the user's session). +- [ ] Login PINs feature — Medtelligent supports it but it's "limited release." When ALIS support call resumes, ask about enabling Login PINs for Cascades. PINs allow caregivers to re-auth via 6-digit PIN after timeout instead of full SSO redirect — meaningful UX improvement for shared phones. + +### Optional cleanup +- [ ] Two stale Entra Android device records still exist (`samsungSM-A146U` and `31fb90e5bbc239ba_AndroidEnterprise_5/8/2026_12:12 AM`) — Tenant Admin SP returns 403 on Entra device DELETE (lacks `Device.ReadWrite.All`). To clean up: portal delete by Howard (or grant the SP that scope). Non-blocking — orphans are inert. + +### Long-term +- [ ] Disable `devices@cascadestucson.com` once production rollout completes. Account preserves audit trail; devices stay in shared mode after. + +## Reference Information + +### Microsoft documentation (the docs that mattered today) +- Android Enterprise dedicated device setup (the article that revealed the SDM token type): https://learn.microsoft.com/en-us/intune/device-enrollment/android/setup-dedicated +- Managed Google Play web links: https://learn.microsoft.com/en-us/intune/app-management/deployment/add-managed-google-play (specifically the "Managed Google Play web links" section) +- ALIS SSO setup (Medtelligent): https://support.alisonline.com/hc/en-us/articles/34831696021901-Single-Sign-On-SSO +- ALIS Login PINs feature (limited release): https://support.alisonline.com/hc/en-us/articles/42638358994317-Login-PINs-for-SSO + +### Vault paths +- `clients/cascades-tucson/alis-sso-app-registration.sops.yaml` — Entra App Reg, ALIS Inbound creds, install key (vault commit `25b0ed7`) +- `clients/cascades-tucson/devices-account.sops.yaml` — devices@ provisioning account +- `clients/cascades-tucson/pilot-test-user.sops.yaml` — pilot.test caregiver test user +- `clients/cascades-tucson/wifi-cscnet.sops.yaml` — Wi-Fi PSK +- `clients/cascades-tucson/cs-server.sops.yaml` — domain controller + +### URLs +- Cascades ALIS tenant: `https://cascadestucson.alisonline.com` +- Entra portal: `https://entra.microsoft.com` +- Intune admin center: `https://intune.microsoft.com` +- ALIS support: `support@go-alis.com` / `888-404-ALIS (2547)` + +### Syncro tickets +- **#32214** — "Entra setup" (In Progress) — comment `409911490` posted today with project update +- **#32263** — Kittle Joshua Sutherland onsite (separate session log) + +### Microsoft support ticket +- **#2605070040009774** — Authenticator SDM activation troubleshooting (open from yesterday). Today's outcome (token type fix) is the resolution; will update + close on next session if pilot SSO test passes. + +--- + +**Session duration:** ~9 hours, 2026-05-08 ~07:00 PT through ~16:36 PT (last action: Cascades ticket comment post) +**End-of-day phone state:** Both test phones (R9TW207FSXA, R92W310H31N) physically left at Cascades, powered on, on Wi-Fi, awaiting Google Managed Play distribution to land the three web link tiles overnight. +**Resume:** Verify web tiles present + run end-to-end ALIS SSO test. diff --git a/clients/kittle/session-logs/2026-05-08-howard-joshua-onsite-and-gururmm-onboarding.md b/clients/kittle/session-logs/2026-05-08-howard-joshua-onsite-and-gururmm-onboarding.md new file mode 100644 index 0000000..980714d --- /dev/null +++ b/clients/kittle/session-logs/2026-05-08-howard-joshua-onsite-and-gururmm-onboarding.md @@ -0,0 +1,205 @@ +# Kittle — Joshua Sutherland AD onboarding + GuruRMM site setup + +**Date:** 2026-05-08 +**Client:** Kittle Design & Construction LLC (Syncro 32460233, Tenant `kittle.lan`) + +## User +- **User:** Howard Enos (howard) +- **Machine:** Howard-Home + onsite at Kittle 11:30 AM PT +- **Role:** tech + +## Session Summary + +Created Active Directory user `joshua.sutherland` at Kittle Design & Construction's domain (`kittle.lan`) for new employee Joshua Sutherland, who is taking over Wrex's existing workstation. Coordinated the onsite via Syncro ticket #32263 with an 11:30 AM PT scheduled appointment. Vaulted the Kittle GuruRMM site enrollment key (the Kittle GuruRMM client + site were created today) to enable agent deployment to Kittle endpoints going forward. Documented the working ScreenConnect command pattern (`#!ps` prefix required for PowerShell context) after Howard hit cmd-vs-PowerShell parsing errors. + +## Key Decisions + +- Joshua's email field uses the existing M365 domain (`joshua@kittlearizona.com`) — Kittle's M365 cloud identity layer is on `kittlearizona.com` while their on-prem AD is `kittle.lan`. Email field on the AD user reflects M365, not the on-prem domain. +- Initial AD password set to `Sutherland2026!`, then reset onsite to `Kota2020!` per Howard's direction. Force-change-at-logon enabled. +- Local admin rights on Wrex's PC handled separately — `Add-LocalGroupMember` must run on Wrex's actual workstation, not on the DC (which doesn't have a local Administrators group; that command targets the local SAM, not the domain). +- Kittle is now a GuruRMM client. Howard installing agents on SERVER2021 + Wrex's PC during the onsite to begin RMM coverage. +- Saved feedback memory: Syncro appointment owner must be explicitly confirmed when creating tickets — don't auto-default to ticket's assigned tech, don't add additional attendees without explicit user direction. + +## Problems Encountered + +- ScreenConnect command runner defaulted to `cmd` context, causing PowerShell syntax to fail. Resolved by prefixing scripts with `#!ps` to force PowerShell execution. +- Initial AD user creation had `-AccountPassword $Kota2020!` which PowerShell parsed as variable `$Kota2020` (empty) followed by `!` — `!` cannot be part of a variable name. Resolved by setting `$Password = ConvertTo-SecureString "Kota2020!" -AsPlainText -Force` first, then referencing `$Password`. +- `Add-LocalGroupMember` on the DC failed with "Group Administrators was not found." — DCs use Builtin\Administrators (domain-wide), not a local SAM group. Resolved by deferring the local-admin step to when Howard is at Wrex's actual workstation. + +## Configuration Changes + +### Active Directory user created (kittle.lan domain) + +``` +Name: Joshua Sutherland +SamAccountName: joshua.sutherland +UserPrincipalName: joshua.sutherland@kittle.lan +EmailAddress: joshua@kittlearizona.com +Enabled: true +ChangePasswordAtLogon: true +DistinguishedName: CN=Joshua Sutherland,CN=Users,DC=kittle,DC=lan +Description: Created 2026-05-08 by Howard for use on Wrex's machine +``` + +Password initially set to `Sutherland2026!`, then reset to `Kota2020!` per Howard's onsite preference (`Set-ADAccountPassword -Identity joshua.sutherland -NewPassword $Pwd -Reset`). + +### Kittle GuruRMM site (created today, agents pending) + +``` +Client: Kittle Design & Construction LLC (id d8b08837-78e0-441e-b824-e0abbf0254ed, code KITTLE) +Site: Main Office (id 851376d1-33be-46ee-9e48-be44767e4a0a, code SILVER-HAWK-7639) +Address: 2539 N Balboa Ave #125, Tucson AZ 85705 +API key: grmm_JA9bA45d7IGOf0bEifZnH9JjIBPOMZxq +``` + +Vaulted at `clients/kittle/gururmm-site-main.sops.yaml` (vault commit `6eb3414`). + +### Syncro ticket created + +- **#32263** — "Joshua - set up account on Wrex's computer" — Onsite, Scheduled, Howard Enos +- **Appointment** id `5585387825` — 2026-05-08 11:30 AM - 1:00 PM PT +- Customer: Kittle Design & Construction LLC, contact_id null per global rule + +### Memory updated +- New: `.claude/memory/feedback_syncro_appointment_owner.md` — confirm appointment owner explicitly when creating tickets, don't add attendees silently. + +## Credentials & Secrets + +### Joshua Sutherland AD account (kittle.lan) +- Username: `joshua.sutherland` +- UPN: `joshua.sutherland@kittle.lan` +- Email: `joshua@kittlearizona.com` +- **Password (current, after onsite reset): `Kota2020!`** +- Force change at next logon: yes + +### Kittle GuruRMM Main Office site enrollment key (NEW today) +- API key: `grmm_JA9bA45d7IGOf0bEifZnH9JjIBPOMZxq` +- Vault: `clients/kittle/gururmm-site-main.sops.yaml` + +### Kittle SERVER2021 admin (FROM Syncro customer notes — needs vault migration) +- Username: `administrator` +- Password: `AXman2Z` +- **Source: Syncro customer notes (plaintext exposure)** — flag for vault migration. Same pattern as Horseshoe Management. + +### Kittle M365 Outlook accounts (FROM Syncro customer notes — also flagged) +- `kittletucson@outlook.com` / `tick8800` +- `kittletucson2@outlook.com` / `Tick8800` + +## Infrastructure & Servers + +- **Kittle domain:** `kittle.lan` (NetBIOS: `KITTLE`) +- **DC + file server:** `SERVER2021` (Syncro asset id `10584015`) +- **M365 tenant:** `kittlearizona.com` +- **Other Syncro asset:** `FRONTDESK` (id `11122225`) +- **Wrex's workstation:** hostname unknown — not in Syncro asset inventory. Discovery pending onsite. +- **Office:** 2539 N Balboa Ave #125, Tucson AZ 85705 +- **Primary contact:** Kimberly Ross, `admin@kittlearizona.com` + +## Commands & Outputs + +### Working AD user creation script (run on DC via ScreenConnect with `#!ps` prefix) + +```powershell +#!ps +$Domain = Get-ADDomain +Write-Host "Domain: $($Domain.DNSRoot) ($($Domain.NetBIOSName))" + +$Password = ConvertTo-SecureString "Sutherland2026!" -AsPlainText -Force +$UPN = "joshua.sutherland@$($Domain.DNSRoot)" +$Path = "CN=Users,$($Domain.DistinguishedName)" + +New-ADUser ` + -Name "Joshua Sutherland" ` + -GivenName "Joshua" -Surname "Sutherland" ` + -SamAccountName "joshua.sutherland" ` + -UserPrincipalName $UPN ` + -EmailAddress "joshua@kittlearizona.com" ` + -AccountPassword $Password ` + -Enabled $true ` + -ChangePasswordAtLogon $true ` + -Path $Path ` + -Description "Created 2026-05-08 by Howard for use on Wrex's machine" + +Get-ADUser -Identity joshua.sutherland -Properties * | + Select-Object SamAccountName, UserPrincipalName, EmailAddress, Enabled, DistinguishedName +``` + +### Password reset (run on DC, ScreenConnect `#!ps`) + +```powershell +#!ps +$NewPassword = ConvertTo-SecureString "Kota2020!" -AsPlainText -Force +Set-ADAccountPassword -Identity "joshua.sutherland" -NewPassword $NewPassword -Reset +Set-ADUser -Identity "joshua.sutherland" -ChangePasswordAtLogon $true +Get-ADUser -Identity "joshua.sutherland" -Properties * | + Select-Object SamAccountName, Enabled, PasswordLastSet, ChangePasswordAtLogon +``` + +### Local admin add (run on Wrex's PC, NOT the DC) + +```powershell +#!ps +$DomainNetBIOS = "KITTLE" +$User = "$DomainNetBIOS\joshua.sutherland" +Add-LocalGroupMember -Group "Administrators" -Member $User +Get-LocalGroupMember -Group "Administrators" | Format-Table Name, ObjectClass, PrincipalSource +``` + +### GuruRMM agent deployment (working command) + +```powershell +#!ps +$u='https://rmm-api.azcomputerguru.com/downloads/gururmm-agent-windows-amd64-latest.exe'; +$d='C:\Windows\Temp\gururmm-agent.exe'; +Invoke-WebRequest $u -UseBasicParsing -OutFile $d; +& $d install --server-url 'wss://rmm-api.azcomputerguru.com/ws' --api-key 'grmm_JA9bA45d7IGOf0bEifZnH9JjIBPOMZxq' +``` + +The `#!ps` prefix is required when running via ScreenConnect Commands tab — without it, ScreenConnect runs in cmd context and `Invoke-WebRequest` fails. URL itself returns HTTP 200 (verified, 3.95 MB exe). + +## Pending / Incomplete Tasks + +### Onsite (in progress 11:30 AM PT) +- [ ] Add `KITTLE\joshua.sutherland` to local Administrators group on Wrex's workstation (script ready — run on Wrex's PC) +- [ ] Install GuruRMM agent on SERVER2021 (PowerShell command ready) +- [ ] Install GuruRMM agent on Wrex's workstation (same command) +- [ ] Optionally: roll out GuruRMM agent to FRONTDESK and any other Kittle endpoints +- [ ] Bill the Syncro ticket (#32263) at end of onsite + +### Vault hygiene +- [ ] Migrate Kittle SERVER2021 admin password (`administrator / AXman2Z`) from Syncro plaintext customer notes to SOPS vault (`clients/kittle/server2021.sops.yaml`) +- [ ] Migrate the two Kittle Outlook accounts (`kittletucson@outlook.com` / `kittletucson2@outlook.com`) from Syncro notes to vault +- [ ] Strip those plaintext credentials from Syncro after vaulting (same exposure pattern as Horseshoe Management — flagged on 2026-05-06) + +### Joshua workstation tasks (onsite) +- [ ] Confirm Joshua has signed in successfully on Wrex's PC and changed his password at first logon +- [ ] Verify joshua.sutherland is a local admin on Wrex's PC (`whoami /priv`, or test elevated UAC prompt) +- [ ] Email setup if needed (M365 mailbox provisioning is separate from AD creation — Joshua may need a Kittle M365 license assigned) + +## Reference Information + +### Vault paths +- `clients/kittle/gururmm-site-main.sops.yaml` — GuruRMM site enrollment key (NEW today, vault commit `6eb3414`) +- `clients/kittle/m365-michael-sanchez.sops.yaml` — existing M365 entry for Michael Sanchez + +### Syncro +- Customer ID: `32460233` +- Customer name: Kittle Design & Construction LLC +- Ticket: **#32263** (today's onsite) +- Direct link: https://computerguru.syncromsp.com/tickets/110024484 + +### GuruRMM +- API: `https://rmm-api.azcomputerguru.com` +- Dashboard: `https://rmm.azcomputerguru.com` +- Kittle Main Office: site code `SILVER-HAWK-7639`, id `851376d1-33be-46ee-9e48-be44767e4a0a` + +### Memory +- `.claude/memory/feedback_syncro_appointment_owner.md` — new today + +### Related work +- Cascades-of-Tucson session log for the same day: `clients/cascades-tucson/session-logs/2026-05-08-howard-cascades-sdm-token-success-and-alis-sso.md` + +--- + +**Onsite scheduled:** 2026-05-08 11:30 AM - 1:00 PM PT (Syncro #32263, appointment id `5585387825`) +**Resume:** Confirm onsite tasks (local admin, GuruRMM agents) completed; bill the ticket; vault migration follow-up. diff --git a/session-logs/2026-05-07-howard-gururmm-macos-installer-and-cf-bot-block.md b/session-logs/2026-05-07-howard-gururmm-macos-installer-and-cf-bot-block.md new file mode 100644 index 0000000..8e2f1ff --- /dev/null +++ b/session-logs/2026-05-07-howard-gururmm-macos-installer-and-cf-bot-block.md @@ -0,0 +1,92 @@ +# GuruRMM — macOS installer missing + Cloudflare blocking install one-liner + +**Date:** 2026-05-07 +**Tenant / Site:** Main Office (`WEST-MEADOW-9025`) +**Triggered by:** Sylvia's Mac mini (`Sylvias-Mini`) install attempt failed + +## User +- **User:** Howard Enos (howard) +- **Machine:** Howard-Home +- **Role:** tech + +## Summary + +While trying to enroll Sylvia's Mac mini in GuruRMM, two distinct issues surfaced. Both are server-side problems, not user error. + +1. The bootstrap one-liner (`curl -fsSL ... | sudo bash`) returns 403 because Cloudflare Bot Fight Mode blocks bare `curl/*` user agents. This affects every platform, not just Mac — anyone running the documented install command on Linux/Windows/Mac is hitting the CF challenge page before the request ever reaches the GuruRMM server. +2. There is no macOS installer route on the server. `/install//{macos,darwin,mac,osx}` all return 404. Only `linux` and `windows` are implemented. + +## Reproduction + +``` +sylvia@Sylvias-Mini ~ % curl -fsSL 'https://rmm.azcomputerguru.com/install/WEST-MEADOW-9025/linux' | sudo bash +curl: (22) The requested URL returned error: 403 +``` + +(she used `/linux` — wrong platform anyway, but the 403 is from Cloudflare, not GuruRMM) + +### Diagnosis from Howard-Home + +``` +$ curl -i https://rmm.azcomputerguru.com/install/WEST-MEADOW-9025/linux +HTTP/1.1 403 Forbidden +Server: cloudflare +Cf-Mitigated: challenge +... +``` + +With a normal browser UA, request reaches the server: + +``` +$ curl -A 'Mozilla/5.0 ... Safari/537.36' https://rmm.azcomputerguru.com/install/WEST-MEADOW-9025/linux +# GuruRMM Agent Installer +# Site: Main Office (WEST-MEADOW-9025) +HTTP 200 +``` + +Platform enumeration (with browser UA so CF doesn't block): + +| Path | Result | +|------|--------| +| `/install/WEST-MEADOW-9025/linux` | 200 (script) | +| `/install/WEST-MEADOW-9025/windows` | 200 | +| `/install/WEST-MEADOW-9025/macos` | 404 | +| `/install/WEST-MEADOW-9025/darwin` | 404 | +| `/install/WEST-MEADOW-9025/mac` | 404 | +| `/install/WEST-MEADOW-9025/osx` | 404 | +| `/install/WEST-MEADOW-9025/apple` | 404 | + +## Message for Mike + +Two GuruRMM items for you: + +### 1. Build the macOS agent + installer route (Sylvia is blocked) + +Sylvia (Main Office / `WEST-MEADOW-9025`) needs an agent on her Mac mini. There is no macOS target today. Scope: + +- Rust agent built for `aarch64-apple-darwin` (Apple Silicon) and `x86_64-apple-darwin` (Intel) +- Server route: `/install//macos` returning either a shell installer (parity with linux) or a signed `.pkg` +- LaunchDaemon for service supervision (mac equivalent of the systemd unit on Linux) +- Apple Developer ID signing + notarization so Gatekeeper doesn't block install on a stock Mac. Without notarization, every user has to right-click→Open or pop System Settings → Privacy & Security to allow it. Painful at scale. +- Install path convention: `/usr/local/gururmm` (or `/opt/gururmm` for parity with Linux, but `/usr/local` is more macOS-native) + +If notarization is too much work for v1, a shell-script installer that builds from a code-signed binary still works for mom-and-pop deployments, just expects user to right-click→Open the first time. + +### 2. Cloudflare bot challenge is blocking the install one-liner + +Independent of the macOS work, the Linux/Windows install commands documented in the dashboard don't work as written today. Bare `curl` is being challenged by CF. Three fixes (pick one): + +- **Server-side, recommended:** Cloudflare WAF rule to skip bot fight mode on `(http.request.uri.path matches "^/install/")`. That's the cleanest — install commands stay copy-pasteable. +- Page Rule: Security Level "Essentially Off" for `/install/*`. +- Document the UA flag in the install command: `curl -fsSL -A 'Mozilla/5.0 ...'` — but that's a bandage, every user hits it. + +I'd go with the WAF skip. The endpoint already requires a valid site code so we're not exposing anything new by removing the bot check on it. + +## Howard follow-ups + +- [ ] Sylvia's Mac mini: diagnose slowness / low-memory popups separately (this session) — not enrollment-related. +- [ ] Once Mike ships the macOS agent, return to Sylvia for enrollment. + +## Artifacts + +None — diagnosis was all live curl probes, no persistent state.