367 lines
15 KiB
Markdown
367 lines
15 KiB
Markdown
# Phone SSO Pilot Runbook — Cascades of Tucson
|
||
|
||
**Built:** 2026-04-24 by Howard + Claude
|
||
**Target:** Pilot caregiver phone usable end-to-end by Monday 2026-04-27
|
||
**Reference:** `PLAN-AND-QUESTIONS-2026-04-24.md` Track A
|
||
**Pilot identity:** `howard.enos@cascadestucson.com` (AD), linked to Howard's existing ALIS admin account (`howard.enos` login)
|
||
|
||
> This is the hands-on checklist. Each section has copy-paste-ready commands / field values. Check off as you go.
|
||
|
||
---
|
||
|
||
## Pre-flight (already done)
|
||
- [x] CS-SERVER preflight green (2026-04-22 post-reboot verification)
|
||
- [x] `OU=Caregivers,OU=Departments,DC=cascades,DC=local` created 2026-04-24
|
||
- [x] Orphan `OU=Sync-Phase1-Caregivers` removed
|
||
- [x] WAN IP discovered — primary `184.191.143.62` (confirmed, matches historical sign-in logs)
|
||
- [x] Master plan rewritten with Track A/B/C split
|
||
- [x] Risk Analysis draft saved (`docs/security/risk-analysis-2026-04.md`)
|
||
|
||
---
|
||
|
||
## Gate A1 — Install Entra Connect on CS-SERVER (staging mode)
|
||
|
||
**Prereq:** Domain admin logged into CS-SERVER console. Fresh download of Entra Connect Sync.
|
||
|
||
**Download path (updated 2026-04-24 — Microsoft moved distribution away from Download Center):**
|
||
1. Sign in to https://entra.microsoft.com as Cascades tenant Global Admin
|
||
2. Navigate: **Identity → Hybrid management → Microsoft Entra Connect → Connect Sync**
|
||
3. Download the installer MSI from that blade
|
||
|
||
The public Download Center now returns only a "DecommissionDownloadCentre" PDF notice. New versions are only released via the Entra admin portal.
|
||
|
||
### Installer wizard — field-by-field
|
||
|
||
| Wizard page | What to enter |
|
||
|---|---|
|
||
| Welcome | Accept license |
|
||
| Express Settings | Choose **Customize** (NOT Express) |
|
||
| Install required components | Leave defaults, Install |
|
||
| User sign-in | Select **Password Hash Synchronization**, check **Enable single sign-on** (optional — Seamless SSO for domain-joined PCs; safe to leave checked) |
|
||
| Connect to Azure AD | Sign in as Cascades tenant Global Admin (NOT the `howard.enos` test account — use your normal admin identity) |
|
||
| Connect your directories | Forest: `cascades.local`. Add with domain admin creds. |
|
||
| Azure AD sign-in configuration | Verify UPN suffix `cascadestucson.com` is verified in Azure (should be). If not, fix before proceeding. |
|
||
| Domain / OU filtering | Select **Sync selected domains and OUs**. Check **only** `OU=Caregivers,OU=Departments,DC=cascades,DC=local`. Uncheck everything else. |
|
||
| Uniquely identifying your users | Leave default: "Users are represented only once across all directories" + "objectGUID" |
|
||
| Filter users and devices | Synchronize all users and devices |
|
||
| Optional features | Leave defaults |
|
||
| **Ready to configure** | **CHECK "Enable staging mode"** — this is the key box. Install will run but NOT push anything to Azure. |
|
||
| Confirm → Install | |
|
||
|
||
### Post-install verification (run from CS-SERVER PowerShell)
|
||
|
||
```powershell
|
||
# Confirm staging mode is ON
|
||
Get-ADSyncScheduler | Select-Object StagingModeEnabled, SyncCycleEnabled, MaintenanceEnabled
|
||
|
||
# Force a sync cycle (still staging — nothing pushed)
|
||
Start-ADSyncSyncCycle -PolicyType Initial
|
||
|
||
# Check what would sync
|
||
Get-ADSyncConnector | Select-Object Name, Type
|
||
|
||
# List staged-up users (should only include howard.enos once the account is created in A4)
|
||
Get-ADSyncCSObject -ConnectorName "cascades.local" | Select-Object DistinguishedName, ConnectorState | Select-Object -First 20
|
||
```
|
||
|
||
---
|
||
|
||
## Gate A2 — Named Location + Conditional Access (Report-only)
|
||
|
||
**Where:** Microsoft Entra admin center (https://entra.microsoft.com) → Protection → Conditional Access
|
||
|
||
### A2.1 Named Location
|
||
|
||
Entra → Protection → Conditional Access → **Named locations** → **+ IP ranges location**
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| Name | `Cascades Office` |
|
||
| Mark as trusted location | **Yes** (checkbox) |
|
||
| IP ranges (IPv4) | `184.191.143.62/32` |
|
||
|
||
**Note on dual-WAN:** if pfSense query confirms a secondary WAN with a separate public IP, add that as a second `/32` entry later. Until then, we let Report-only mode show us which IPs are actually observed.
|
||
|
||
### A2.2 CA Policy — Report-only
|
||
|
||
Two policies implement: *"skip MFA only when SG-Caregivers member AND device compliant AND on trusted network; otherwise MFA."*
|
||
|
||
**Policy 1: `Cascades - Caregivers - Untrusted Location - MFA + Compliant`**
|
||
|
||
| Section | Setting |
|
||
|---|---|
|
||
| Users | Include: `SG-Caregivers` group |
|
||
| Cloud apps | Include: All cloud apps |
|
||
| Conditions → Locations | Include **Any location**, Exclude **Cascades Office** |
|
||
| Grant | **Require multi-factor authentication** AND **Require device to be marked as compliant** (select "Require all the selected controls") |
|
||
| Enable policy | **Report-only** |
|
||
|
||
**Policy 2: `Cascades - Caregivers - Trusted Location - Non-Compliant - MFA`**
|
||
|
||
| Section | Setting |
|
||
|---|---|
|
||
| Users | Include: `SG-Caregivers` group |
|
||
| Cloud apps | Include: All cloud apps |
|
||
| Conditions → Locations | Include **Cascades Office** only |
|
||
| Conditions → Filter for devices | Include filter: `device.isCompliant -eq False` |
|
||
| Grant | **Require multi-factor authentication** |
|
||
| Enable policy | **Report-only** |
|
||
|
||
### A2.3 Verify via What-If tool
|
||
|
||
Entra → CA → **What If** → simulate:
|
||
- User: `howard.enos@cascadestucson.com`
|
||
- Cloud app: Office 365
|
||
- IP: `184.191.143.62`, location Cascades Office
|
||
- Device state: Compliant
|
||
- Expected: **no policies match** → no MFA would be required. This is the sign-in pattern we want.
|
||
|
||
Then test untrusted scenario:
|
||
- Same user, same app
|
||
- IP: `8.8.8.8` (random external)
|
||
- Device: Compliant
|
||
- Expected: **Policy 1 matches** → MFA required.
|
||
|
||
---
|
||
|
||
## Gate A3 — ALIS App Registration in Entra
|
||
|
||
**Where:** Entra admin center → Applications → **App registrations** → **+ New registration**
|
||
|
||
### A3.1 Register
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| Name | `Cascades of Tucson - ALIS SSO` |
|
||
| Supported account types | **Accounts in this organizational directory only (Default Directory only - Single tenant)** |
|
||
| Redirect URI — Platform | **Web** |
|
||
| Redirect URI — URL | `https://cascadestucson.alisonline.com/ExternalLoginCallback` |
|
||
|
||
Click **Register**.
|
||
|
||
### A3.2 Authentication
|
||
|
||
Left sidebar → **Authentication**:
|
||
- Under **Implicit grant and hybrid flows** → check **ID tokens (used for implicit and hybrid flows)**
|
||
- Supported account types → **Accounts in this organization directory only (Default - Single tenant)**
|
||
- **Save**
|
||
|
||
### A3.3 Client Secret
|
||
|
||
Left sidebar → **Certificates & secrets** → **+ New client secret**
|
||
|
||
| Field | Value |
|
||
|---|---|
|
||
| Description | `ALIS - Single Tenant Secret` |
|
||
| Expires | **24 months** (max — track in vault, renewal reminder required) |
|
||
|
||
**Copy the `Value` immediately.** It's shown only once. Also capture the `Secret ID`.
|
||
|
||
### A3.4 Capture the three values
|
||
|
||
From **Overview** page:
|
||
- **Directory (tenant) ID:** `207fa277-e9d8-4eb7-ada1-1064d2221498` (known from existing tenant records)
|
||
- **Application (client) ID:** _capture after registration_
|
||
- **Client Secret Value:** _captured in A3.3_
|
||
|
||
### A3.5 Vault the values
|
||
|
||
Create `clients/cascades-tucson/alis-sso-app-registration.sops.yaml` with the three values + secret expiry date. Template:
|
||
|
||
```yaml
|
||
kind: app-registration
|
||
name: Cascades ALIS SSO
|
||
tenant: cascadestucson.com
|
||
tenant_id: 207fa277-e9d8-4eb7-ada1-1064d2221498
|
||
application_id: <capture from portal>
|
||
client_secret_value: <one-time value — copy before leaving portal>
|
||
secret_description: ALIS - Single Tenant Secret
|
||
secret_created: 2026-04-24
|
||
secret_expires: 2028-04-24
|
||
notes: |
|
||
Track expiration — IT admin must update ALIS App Store SSO settings with a new
|
||
secret each renewal cycle or sign-in will stop working for all linked users.
|
||
Rotation reminder: add to calendar 30 days before expires.
|
||
```
|
||
|
||
### A3.6 ALIS App Store install (YOUR SIDE, not Entra)
|
||
|
||
Log into ALIS → App Store → search "Entra SSO" → Install → on the **Configure** tab, under **Outbound Connections**, paste:
|
||
- Directory ID
|
||
- Application ID
|
||
- Client Secret Value
|
||
|
||
Save.
|
||
|
||
---
|
||
|
||
## Gate A4 — Pilot AD account
|
||
|
||
Run via GuruRMM on CS-SERVER (I'll execute when you say go):
|
||
|
||
```powershell
|
||
# Generate a random initial password (you'll know it; caregiver won't need it since
|
||
# they'll set via self-service or login will SSO from phone directly)
|
||
$tempPass = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 16 | ForEach-Object {[char]$_}) + "!9"
|
||
$securePass = ConvertTo-SecureString $tempPass -AsPlainText -Force
|
||
|
||
New-ADUser `
|
||
-Name "Howard Enos" `
|
||
-GivenName "Howard" `
|
||
-Surname "Enos" `
|
||
-SamAccountName "howard.enos" `
|
||
-UserPrincipalName "howard.enos@cascadestucson.com" `
|
||
-EmailAddress "howard.enos@cascadestucson.com" `
|
||
-Path "OU=Caregivers,OU=Departments,DC=cascades,DC=local" `
|
||
-AccountPassword $securePass `
|
||
-Enabled $true `
|
||
-ChangePasswordAtLogon $false `
|
||
-Description "Phone SSO pilot test account — Howard's ALIS admin login target"
|
||
|
||
Write-Output "Account created. Temporary password: $tempPass"
|
||
|
||
# Add to SG-Caregivers (the group from G1)
|
||
Add-ADGroupMember -Identity "SG-Caregivers" -Members "howard.enos"
|
||
|
||
# Verify
|
||
Get-ADUser howard.enos -Properties MemberOf, DistinguishedName, EmailAddress |
|
||
Select-Object SamAccountName, UserPrincipalName, EmailAddress, DistinguishedName, @{N='Groups';E={$_.MemberOf -join '; '}}
|
||
```
|
||
|
||
After run, vault the temporary password to `clients/cascades-tucson/howard-enos-pilot.sops.yaml` so we can find it later if needed.
|
||
|
||
**ALIS side (you do):** in ALIS admin, update `howard.enos` staff profile's Email field to `howard.enos@cascadestucson.com` so it matches the Entra UPN. Required for SSO linking to resolve.
|
||
|
||
---
|
||
|
||
## Gate A5 — Exit staging, sync, verify
|
||
|
||
Run on CS-SERVER:
|
||
|
||
```powershell
|
||
# Turn off staging mode
|
||
Set-ADSyncScheduler -SyncCycleEnabled $true
|
||
Set-ADSyncSchedulerConnectorOverride -ConnectorIdentifier "cascades.local" -FullSyncRequired
|
||
|
||
# Open Azure AD Connect app from Start menu → Configure → Configure staging mode → UNCHECK "Enable staging mode" → Next → Configure
|
||
|
||
# After exiting staging, force a full sync
|
||
Start-ADSyncSyncCycle -PolicyType Initial
|
||
```
|
||
|
||
Verify in Entra (https://entra.microsoft.com → Users):
|
||
- `howard.enos@cascadestucson.com` appears as hybrid (Source: Windows Server AD)
|
||
- The on-premises AD password hash should now be the M365 sign-in password
|
||
|
||
Test sign-in at https://portal.office.com with `howard.enos@cascadestucson.com` + the temp AD password. Should succeed. **May** prompt for MFA at first sign-in depending on tenant defaults — that's fine.
|
||
|
||
---
|
||
|
||
## Gate A6 — Enroll pilot phone
|
||
|
||
**Phone choice:** fresh Samsung A15 (one of the 24 unopened), OR wipe the existing enrolled Phone 1.
|
||
|
||
**Enrollment path:** MSDM shared-device mode, QR-code from `CSC - Android Shared Phones` profile (already configured in Intune).
|
||
|
||
Steps:
|
||
1. Factory reset phone (if reused)
|
||
2. At first-boot, scan the QR code from `CSC - Android Shared Phones`
|
||
3. Phone enrolls into Intune, joins `Cascades - Shared Phones` dynamic group automatically (rule based on enrollmentProfileName)
|
||
4. Policies apply — compliance, Wi-Fi profile, required apps
|
||
5. Wait ~5–15 min for compliance to be evaluated
|
||
|
||
**Test sign-in as pilot:**
|
||
- Open Teams or Authenticator → **Sign in**
|
||
- Enter `howard.enos@cascadestucson.com` + AD password
|
||
- **Expected (on Cascades Wi-Fi):** no MFA prompt (trusted location + compliant device → policies don't match)
|
||
- **Expected (off Cascades Wi-Fi):** MFA prompt (Policy 1 matches → require MFA + compliant)
|
||
- **ALIS web app:** should auto-SSO after M365 sign-in completes (ALIS OIDC app redirects to Entra for auth)
|
||
|
||
**Verify in Entra sign-in logs:**
|
||
https://entra.microsoft.com → Monitoring & Health → Sign-in logs → filter User = howard.enos
|
||
- Column "Conditional Access" → should show "Report-only" results matching expected behavior
|
||
- Column "IP address" → should match `184.191.143.62` when on Cascades Wi-Fi (confirms Named Location matched)
|
||
|
||
---
|
||
|
||
## Gate A7 — Flip CA to Enforcement (Monday AM)
|
||
|
||
After review of Sat–Sun sign-in logs:
|
||
- Confirm no "would have been blocked" events for legitimate sign-ins
|
||
- Both CA policies → **Enable policy: On** (was Report-only)
|
||
|
||
Run one more pilot sign-in from phone to confirm no regression.
|
||
|
||
---
|
||
|
||
## Parallel: ALIS support email (send anytime)
|
||
|
||
**To:** `support@medtelligent.com`
|
||
**Subject:** Cascades of Tucson — SSO setup, BAA request, and PIN feature availability
|
||
|
||
```
|
||
Hi ALIS team,
|
||
|
||
I'm the MSP IT contact for Cascades of Tucson (tenant: cascadestucson.alisonline.com).
|
||
We are setting up Microsoft Entra SSO for our staff per your documentation at
|
||
https://support.alisonline.com/hc/en-us/articles/34831696021901.
|
||
|
||
We have three asks:
|
||
|
||
1. HIPAA Business Associate Agreement (BAA) — Cascades is a HIPAA-covered entity
|
||
and we need a signed BAA with Medtelligent / ALIS on file. Please send the
|
||
current template.
|
||
|
||
2. User linking workflow — your documentation says users "link their ALIS account
|
||
to their Microsoft identity." Can you confirm whether linking is triggered by
|
||
administrator action (push) or by each user's first SSO sign-in attempt?
|
||
We are doing a controlled pilot rollout and need to know whether installing
|
||
the Entra SSO app will trigger any automatic re-linking for existing users,
|
||
or whether existing ALIS credentials keep working until each user is
|
||
individually linked.
|
||
|
||
3. Login PINs feature — your docs note this is "limited-release." Is this
|
||
feature available to us? It looks valuable for our shared-phone caregiver
|
||
workflow (faster re-auth without full OIDC redirect each time).
|
||
|
||
As a secondary item, we would also appreciate your FIPS 140-2 attestation /
|
||
compliance statement for our HIPAA risk analysis documentation.
|
||
|
||
Happy to connect with your Integrations team as needed.
|
||
|
||
Thanks,
|
||
Howard Enos
|
||
Arizona Computer Guru (MSP for Cascades of Tucson)
|
||
howard@azcomputerguru.com
|
||
```
|
||
|
||
---
|
||
|
||
## Rollback points
|
||
|
||
| Gate | Rollback |
|
||
|---|---|
|
||
| A1 | Uninstall Entra Connect from Control Panel → nothing synced |
|
||
| A2 | Delete CA policies + Named Location — zero impact if Report-only |
|
||
| A3 | Delete App Registration in Entra — ALIS SSO stops working but ALIS credential login still works |
|
||
| A4 | Disable / remove `howard.enos` AD account |
|
||
| A5 | Re-enter staging mode via ADConnect wizard; re-sync to remove pilot from cloud |
|
||
| A6 | Factory reset phone |
|
||
| A7 | Flip both policies back to Report-only |
|
||
|
||
No hard-to-reverse steps. Only concern: **after PHS is on, existing cloud-only M365 passwords for users in sync scope are overwritten by their AD password.** Phase 1 scope is just `howard.enos` (new account) — no existing-user password migration pain.
|
||
|
||
---
|
||
|
||
## Open items / decisions as of 2026-04-24
|
||
|
||
- [ ] Dual-WAN verdict from pfSense (Howard to check after lockout clears)
|
||
- [ ] `72.211.21.217` egress IP — confirm or discard after Named Location Report-only logs show actual sign-in IPs
|
||
- [ ] ALIS support email sent
|
||
- [ ] ALIS BAA received
|
||
- [ ] Login PINs feature availability confirmed
|
||
|
||
## Open questions handled elsewhere
|
||
- Everything Meredith-blocking → master plan Track B + `PLAN-AND-QUESTIONS-2026-04-24.md` §5
|
||
- ALIS password pasted in chat earlier → rotate when convenient (post-pilot)
|