@@ -7,7 +7,8 @@ function Initialize-CIPPAuth {
77 Loads SAM credentials from Key Vault (or DevSecrets table),
88 auto-patches redirect URIs on the SAM and SSO app registrations,
99 and configures EasyAuth if SSO credentials are provisioned but
10- EasyAuth is not yet enabled.
10+ EasyAuth is not yet enabled. On a fresh deployment with nothing
11+ configured, requests Craft's setup wizard mode.
1112 #>
1213 [CmdletBinding ()]
1314 param ()
@@ -19,26 +20,41 @@ function Initialize-CIPPAuth {
1920 NeedsSetup = $true
2021 }
2122
22- # 1. Determine Key Vault name
23+ # -- Entry logging --
24+ $EasyAuthEnabled = [Craft.Services.AppLifecycleBridge ]::IsEasyAuthConfigured()
25+ $IsDevStorage = ($env: AzureWebJobsStorage -eq ' UseDevelopmentStorage=true' ) -or ($env: NonLocalHostAzurite -eq ' true' )
2326 $KVName = ($env: WEBSITE_DEPLOYMENT_ID -split ' -' )[0 ]
2427
25- # 2. Try loading SAM credentials
26- if ($KVName -or $env: AzureWebJobsStorage -eq ' UseDevelopmentStorage=true' -or $env: NonLocalHostAzurite -eq ' true' ) {
28+ Write-Information " [Auth-Init] Starting — EasyAuth=$EasyAuthEnabled , DevStorage=$IsDevStorage , KVName='$KVName ', DeploymentId='$env: WEBSITE_DEPLOYMENT_ID '"
29+
30+ # 1. Try loading SAM credentials
31+ if ($KVName -or $IsDevStorage ) {
2732 $AuthState.HasKeyVault = [bool ]$KVName
33+ Write-Information " [Auth-Init] Credential source available (KV=$ ( $AuthState.HasKeyVault ) , DevStorage=$IsDevStorage ) — attempting SAM load"
2834 try {
2935 $Auth = Get-CIPPAuthentication
3036 if ($Auth -and $env: ApplicationID -and $env: TenantID ) {
3137 $AuthState.HasSAMCredentials = $true
3238 $AuthState.NeedsSetup = $false
3339 $AuthState.IsConfigured = $true
34- Write-Information " [Auth-Init] SAM credentials loaded (AppID: $ ( $env: ApplicationID ) )"
40+ Write-Information " [Auth-Init] SAM credentials loaded (AppID: $ ( $env: ApplicationID ) , TenantID: $ ( $env: TenantID ) )"
41+ } else {
42+ Write-Information ' [Auth-Init] SAM credential load returned but env vars not populated — credentials not available yet (expected on fresh deployment)'
3543 }
3644 } catch {
37- Write-Information " [Auth-Init] Could not load SAM credentials: $_ "
45+ $ErrorMessage = " $_ "
46+ # Distinguish "not found" from real access errors
47+ if ($ErrorMessage -match ' SecretNotFound|not found|does not exist|Development variables not set' ) {
48+ Write-Information " [Auth-Init] SAM credentials not found in storage — expected on fresh deployment"
49+ } else {
50+ Write-Information " [Auth-Init] ERROR accessing credential storage (possible permission/network issue): $ErrorMessage "
51+ }
3852 }
53+ } else {
54+ Write-Information ' [Auth-Init] No credential source available — WEBSITE_DEPLOYMENT_ID is not set and not using dev storage. Cannot load SAM credentials.'
3955 }
4056
41- # 3 . Auto-patch redirect URIs if we have credentials
57+ # 2 . Auto-patch redirect URIs if we have credentials
4258 if ($AuthState.HasSAMCredentials ) {
4359 try {
4460 Update-CIPPSAMRedirectUri
@@ -53,13 +69,86 @@ function Initialize-CIPPAuth {
5369 }
5470 }
5571
56- # 4. If EasyAuth is not configured, check for SSO credentials and set it up
57- $EasyAuthEnabled = [Craft.Services.AppLifecycleBridge ]::IsEasyAuthConfigured()
58- if (-not $EasyAuthEnabled -and $AuthState.HasSAMCredentials ) {
59- # If the central migration app ID is set, configure EasyAuth with implicit auth
60- # (no client secret). This lets the user log in via the shared app while the
61- # ForcedSsoMigrationDialog guides them through creating their own CIPP-SSO app.
62- # Once they complete migration, step 5 detects the clientId change and cleans up.
72+ # 3. Handle EasyAuth configuration based on current state
73+ if ($EasyAuthEnabled ) {
74+ Write-Information ' [Auth-Init] EasyAuth is already configured'
75+
76+ # 3a. If CIPP_SSO_MIGRATION_APPID is set, check if migration is complete
77+ if ($env: CIPP_SSO_MIGRATION_APPID ) {
78+ Write-Information ' [Auth-Init] EasyAuth is active but CIPP_SSO_MIGRATION_APPID still set — checking if migration is complete...'
79+ try {
80+ $AuthConfigJson = $env: WEBSITE_AUTH_V2_CONFIG_JSON
81+ if ($AuthConfigJson ) {
82+ $AuthConfig = $AuthConfigJson | ConvertFrom-Json - ErrorAction Stop
83+ $ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
84+
85+ if ($ConfiguredAppId -eq $env: CIPP_SSO_MIGRATION_APPID ) {
86+ Write-Information ' [Auth-Init] EasyAuth clientId matches migration app — migration still pending'
87+ } elseif ($ConfiguredAppId ) {
88+ Write-Information " [Auth-Init] EasyAuth clientId ($ConfiguredAppId ) differs from migration app — migration complete, cleaning up"
89+ $Removed = Remove-CIPPMigrationAppSetting - SettingName ' CIPP_SSO_MIGRATION_APPID'
90+ if ($Removed ) {
91+ [Craft.Services.AppLifecycleBridge ]::RequestRestart(' SSO migration env var cleaned up during warmup' )
92+ }
93+ } else {
94+ Write-Information ' [Auth-Init] No clientId found in EasyAuth config — skipping cleanup'
95+ }
96+ }
97+ } catch {
98+ Write-Information " [Auth-Init] Migration cleanup check failed (non-fatal): $_ "
99+ }
100+ }
101+
102+ # 3b. Reconcile EasyAuth issuer with SSOMultiTenant setting
103+ if ($AuthState.HasSAMCredentials -and -not $env: CIPP_SSO_MIGRATION_APPID ) {
104+ try {
105+ $AuthConfigJson = $env: WEBSITE_AUTH_V2_CONFIG_JSON
106+ if ($AuthConfigJson ) {
107+ $AuthConfig = $AuthConfigJson | ConvertFrom-Json - ErrorAction Stop
108+ $CurrentIssuer = $AuthConfig.identityProviders.azureActiveDirectory.registration.openIdIssuer
109+ $ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
110+
111+ if ($CurrentIssuer -and $ConfiguredAppId ) {
112+ $SSOMultiTenant = $false
113+ if ($IsDevStorage ) {
114+ try {
115+ $DevSecretsTable = Get-CIPPTable - tablename ' DevSecrets'
116+ $Secret = Get-CIPPAzDataTableEntity @DevSecretsTable - Filter " PartitionKey eq 'SSO' and RowKey eq 'SSO'" - ErrorAction SilentlyContinue
117+ $SSOMultiTenant = $Secret.SSOMultiTenant -eq ' True'
118+ } catch { }
119+ } elseif ($KVName ) {
120+ try {
121+ $MtVal = Get-CippKeyVaultSecret - VaultName $KVName - Name ' SSOMultiTenant' - AsPlainText - ErrorAction Stop
122+ $SSOMultiTenant = $MtVal -eq ' True'
123+ } catch { }
124+ }
125+
126+ $ExpectedIssuer = if ($SSOMultiTenant ) {
127+ ' https://login.microsoftonline.com/common/v2.0'
128+ } else {
129+ " https://login.microsoftonline.com/$ ( $env: TenantID ) /v2.0"
130+ }
131+
132+ if ($CurrentIssuer -ne $ExpectedIssuer ) {
133+ Write-Information " [Auth-Init] EasyAuth issuer mismatch: current=$CurrentIssuer expected=$ExpectedIssuer — updating"
134+ $Configured = Set-CIPPSSOEasyAuth - AppId $ConfiguredAppId - MultiTenant $SSOMultiTenant - TenantId $env: TenantID
135+ if ($Configured ) {
136+ Write-Information ' [Auth-Init] EasyAuth issuer updated — requesting container restart'
137+ [Craft.Services.AppLifecycleBridge ]::RequestRestart(' EasyAuth issuer updated to match SSOMultiTenant setting during warmup' )
138+ }
139+ } else {
140+ Write-Information " [Auth-Init] EasyAuth issuer matches SSOMultiTenant setting ($SSOMultiTenant ) — no update needed"
141+ }
142+ }
143+ }
144+ } catch {
145+ Write-Information " [Auth-Init] EasyAuth issuer reconciliation failed (non-fatal): $_ "
146+ }
147+ }
148+ } elseif ($AuthState.HasSAMCredentials ) {
149+ # EasyAuth NOT configured but we DO have SAM credentials — try to auto-configure
150+ Write-Information ' [Auth-Init] EasyAuth not configured but SAM credentials available — attempting auto-configuration'
151+
63152 if ($env: CIPP_SSO_MIGRATION_APPID ) {
64153 Write-Information " [Auth-Init] CIPP_SSO_MIGRATION_APPID is set ($ ( $env: CIPP_SSO_MIGRATION_APPID ) ) — configuring implicit auth EasyAuth"
65154 try {
@@ -74,12 +163,12 @@ function Initialize-CIPPAuth {
74163 return $AuthState
75164 }
76165
77- Write-Information ' [Auth-Init] EasyAuth not configured — checking for SSO credentials... '
166+ # Try to find SSO credentials and configure EasyAuth automatically
78167 try {
79168 $SSOAppId = $null
80169 $SSOMultiTenant = $false
81170
82- if ($env: AzureWebJobsStorage -eq ' UseDevelopmentStorage=true ' -or $ env: NonLocalHostAzurite -eq ' true ' ) {
171+ if ($IsDevStorage ) {
83172 $DevSecretsTable = Get-CIPPTable - tablename ' DevSecrets'
84173 $Secret = Get-CIPPAzDataTableEntity @DevSecretsTable - Filter " PartitionKey eq 'SSO' and RowKey eq 'SSO'" - ErrorAction SilentlyContinue
85174 $SSOAppId = $Secret.SSOAppId
@@ -100,95 +189,23 @@ function Initialize-CIPPAuth {
100189 [Craft.Services.AppLifecycleBridge ]::RequestRestart(' EasyAuth configured from SSO credentials during warmup' )
101190 }
102191 } else {
103- Write-Information ' [Auth-Init] No SSO credentials found — enabling setup wizard'
104- [Craft.Services.AppLifecycleBridge ]::RequestSetupMode(' No SSO credentials found — setup wizard needed for initial EasyAuth configuration ' )
192+ Write-Information ' [Auth-Init] SAM credentials loaded but no SSO AppId found — enabling setup wizard'
193+ [Craft.Services.AppLifecycleBridge ]::RequestSetupMode(' SAM credentials available but no SSO app configured — setup wizard needed' )
105194 }
106195 } catch {
107196 Write-Information " [Auth-Init] SSO EasyAuth setup failed (non-fatal): $_ "
197+ [Craft.Services.AppLifecycleBridge ]::RequestSetupMode(' SSO setup failed — setup wizard needed for manual configuration' )
108198 }
199+ } else {
200+ # No EasyAuth AND no SAM credentials — this is a fresh/unconfigured deployment
201+ Write-Information ' [Auth-Init] Fresh deployment detected — no EasyAuth configured and no SAM credentials available'
202+ Write-Information ' [Auth-Init] Requesting setup wizard mode for initial configuration'
203+ [Craft.Services.AppLifecycleBridge ]::RequestSetupMode(' Fresh deployment — no credentials or EasyAuth configured' )
204+ $AuthState.NeedsSetup = $true
109205 }
110206
111- # 5. Reconcile EasyAuth issuer with SSOMultiTenant setting: if EasyAuth is already
112- # configured, check whether the issuer URL matches the current SSOMultiTenant value
113- # from Key Vault. If it changed (e.g. toggled from single to multi-tenant), update
114- # the EasyAuth config via ARM and restart.
115- if ($EasyAuthEnabled -and $AuthState.HasSAMCredentials -and -not $env: CIPP_SSO_MIGRATION_APPID ) {
116- try {
117- $AuthConfigJson = $env: WEBSITE_AUTH_V2_CONFIG_JSON
118- if ($AuthConfigJson ) {
119- $AuthConfig = $AuthConfigJson | ConvertFrom-Json - ErrorAction Stop
120- $CurrentIssuer = $AuthConfig.identityProviders.azureActiveDirectory.registration.openIdIssuer
121- $ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
122-
123- if ($CurrentIssuer -and $ConfiguredAppId ) {
124- # Read SSOMultiTenant from KV/DevSecrets
125- $SSOMultiTenant = $false
126- if ($env: AzureWebJobsStorage -eq ' UseDevelopmentStorage=true' -or $env: NonLocalHostAzurite -eq ' true' ) {
127- try {
128- $DevSecretsTable = Get-CIPPTable - tablename ' DevSecrets'
129- $Secret = Get-CIPPAzDataTableEntity @DevSecretsTable - Filter " PartitionKey eq 'SSO' and RowKey eq 'SSO'" - ErrorAction SilentlyContinue
130- $SSOMultiTenant = $Secret.SSOMultiTenant -eq ' True'
131- } catch { }
132- } elseif ($KVName ) {
133- try {
134- $MtVal = Get-CippKeyVaultSecret - VaultName $KVName - Name ' SSOMultiTenant' - AsPlainText - ErrorAction Stop
135- $SSOMultiTenant = $MtVal -eq ' True'
136- } catch { }
137- }
138-
139- $ExpectedIssuer = if ($SSOMultiTenant ) {
140- ' https://login.microsoftonline.com/common/v2.0'
141- } else {
142- " https://login.microsoftonline.com/$ ( $env: TenantID ) /v2.0"
143- }
144-
145- if ($CurrentIssuer -ne $ExpectedIssuer ) {
146- Write-Information " [Auth-Init] EasyAuth issuer mismatch: current=$CurrentIssuer expected=$ExpectedIssuer — updating"
147- $Configured = Set-CIPPSSOEasyAuth - AppId $ConfiguredAppId - MultiTenant $SSOMultiTenant - TenantId $env: TenantID
148- if ($Configured ) {
149- Write-Information ' [Auth-Init] EasyAuth issuer updated — requesting container restart'
150- [Craft.Services.AppLifecycleBridge ]::RequestRestart(' EasyAuth issuer updated to match SSOMultiTenant setting during warmup' )
151- }
152- } else {
153- Write-Information " [Auth-Init] EasyAuth issuer matches SSOMultiTenant setting ($SSOMultiTenant ) — no update needed"
154- }
155- }
156- }
157- } catch {
158- Write-Information " [Auth-Init] EasyAuth issuer reconciliation failed (non-fatal): $_ "
159- }
160- }
161-
162- # 6. Post-migration cleanup: if CIPP_SSO_MIGRATION_APPID is still set but EasyAuth
163- # is now configured, check whether the EasyAuth clientId still matches the migration
164- # app. If it differs, the customer's own CIPP-SSO app is active and we can remove
165- # the migration trigger env var.
166- if ($EasyAuthEnabled -and $env: CIPP_SSO_MIGRATION_APPID ) {
167- Write-Information ' [Auth-Init] EasyAuth is active but CIPP_SSO_MIGRATION_APPID still set — checking if migration is complete...'
168- try {
169- $AuthConfigJson = $env: WEBSITE_AUTH_V2_CONFIG_JSON
170- if ($AuthConfigJson ) {
171- $AuthConfig = $AuthConfigJson | ConvertFrom-Json - ErrorAction Stop
172- $ConfiguredAppId = $AuthConfig.identityProviders.azureActiveDirectory.registration.clientId
173-
174- if ($ConfiguredAppId -eq $env: CIPP_SSO_MIGRATION_APPID ) {
175- # EasyAuth is still using the central migration app — migration not done yet
176- Write-Information ' [Auth-Init] EasyAuth clientId matches migration app — migration still pending'
177- } elseif ($ConfiguredAppId ) {
178- # EasyAuth clientId differs from the migration app — customer's own app is active
179- Write-Information " [Auth-Init] EasyAuth clientId ($ConfiguredAppId ) differs from migration app — migration complete, cleaning up"
180- $Removed = Remove-CIPPMigrationAppSetting - SettingName ' CIPP_SSO_MIGRATION_APPID'
181- if ($Removed ) {
182- [Craft.Services.AppLifecycleBridge ]::RequestRestart(' SSO migration env var cleaned up during warmup' )
183- }
184- } else {
185- Write-Information ' [Auth-Init] No clientId found in EasyAuth config — skipping cleanup'
186- }
187- }
188- } catch {
189- Write-Information " [Auth-Init] Migration cleanup check failed (non-fatal): $_ "
190- }
191- }
207+ # -- Exit logging --
208+ Write-Information " [Auth-Init] Complete — IsConfigured=$ ( $AuthState.IsConfigured ) , HasSAM=$ ( $AuthState.HasSAMCredentials ) , NeedsSetup=$ ( $AuthState.NeedsSetup ) , EasyAuth=$EasyAuthEnabled "
192209
193210 return $AuthState
194211}
0 commit comments