diff --git a/docs/OIDC.md b/docs/OIDC.md index 398caf1905..bcc6c20914 100644 --- a/docs/OIDC.md +++ b/docs/OIDC.md @@ -43,6 +43,14 @@ Only after verifying SSO, optionally hide the local username/password form with Appending `?show_local=true` to your Pulse URL shows that form again; it does not create or restore local credentials, bypass the proxy or revoke SSO sessions. +**Hiding the form is not SSO-only enforcement.** Local password authentication +remains enabled: valid existing local credentials can still sign in, including +through the local login endpoint. The visibility setting does not reject those +requests or revoke local sessions. Keep the independent administrator recovery +path; do not remove credentials or disable authentication to simulate an +OIDC-only policy. Login restrictions and group-role mappings below apply to SSO +sign-ins, not to the separate local password login. + ## ⚙️ Configuration | Setting | Description | diff --git a/frontend-modern/public/docs/OIDC.md b/frontend-modern/public/docs/OIDC.md index 398caf1905..bcc6c20914 100644 --- a/frontend-modern/public/docs/OIDC.md +++ b/frontend-modern/public/docs/OIDC.md @@ -43,6 +43,14 @@ Only after verifying SSO, optionally hide the local username/password form with Appending `?show_local=true` to your Pulse URL shows that form again; it does not create or restore local credentials, bypass the proxy or revoke SSO sessions. +**Hiding the form is not SSO-only enforcement.** Local password authentication +remains enabled: valid existing local credentials can still sign in, including +through the local login endpoint. The visibility setting does not reject those +requests or revoke local sessions. Keep the independent administrator recovery +path; do not remove credentials or disable authentication to simulate an +OIDC-only policy. Login restrictions and group-role mappings below apply to SSO +sign-ins, not to the separate local password login. + ## ⚙️ Configuration | Setting | Description | diff --git a/frontend-modern/src/features/docs/__tests__/oidcSetupDocs.test.ts b/frontend-modern/src/features/docs/__tests__/oidcSetupDocs.test.ts index cf305769b4..8f1f24206f 100644 --- a/frontend-modern/src/features/docs/__tests__/oidcSetupDocs.test.ts +++ b/frontend-modern/src/features/docs/__tests__/oidcSetupDocs.test.ts @@ -43,6 +43,25 @@ describe('OIDC setup without losing access', () => { expect(readFileSync(resolve(process.cwd(), 'public/docs/OIDC.md'), 'utf8')).toBe(read('OIDC')); }); + it('distinguishes hiding local login from enforcing SSO-only authentication', () => { + const guide = article('OIDC'); + const warning = [...guide.querySelectorAll('p')].find((paragraph) => + text(paragraph).startsWith('Hiding the form is not SSO-only enforcement.'), + )!; + expect(warning).toBeDefined(); + expect(text(warning.querySelector('strong')!)).toBe( + 'Hiding the form is not SSO-only enforcement.', + ); + expect(text(warning.previousElementSibling!)).toContain('PULSE_AUTH_HIDE_LOCAL_LOGIN=true'); + expect(text(warning.previousElementSibling!)).toContain('?show_local=true'); + expect(text(warning)).toContain('valid existing local credentials can still sign in'); + expect(text(warning)).toContain('does not reject those requests or revoke local sessions'); + expect(text(warning)).toContain('Keep the independent administrator recovery path'); + expect(text(warning)).toContain('do not remove credentials or disable authentication'); + expect(text(warning)).toContain('not to the separate local password login'); + expect(warning.querySelector('pre, form, input, button')).toBeNull(); + }); + it('links all setup decisions to real focused documentation headings', () => { const guide = article('OIDC'); for (const [name, fragment] of [