diff --git a/CHANGELOG.md b/CHANGELOG.md index fbbbaea..528c7c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,29 @@ ### Security +- **OIDC provider "Test connection" panel (Audit 2026-05-11 Fix 09 — MED-5 GUI half).** + MED-5's backend dry-run endpoint (`POST /api/v1/auth/oidc/test`, gated + `auth.oidc.create`) shipped on `dev/auth-bundle-2` but had no GUI caller — + the `authOIDCTestProvider` function in `web/src/api/client.ts` was dead + code. Operators had to complete the create form blind, save, then click + "Refresh" to discover whether the issuer URL worked; failures left a + broken provider row in the database that had to be deleted before + retrying. New shared component + `web/src/pages/auth/OIDCTestConnectionPanel.tsx` calls the backend + against the live form state and renders a four-row status panel inline: + Discovery fetched, JWKS reachable, supported algs (warns when the IdP + advertises none), and RFC 9207 iss-parameter advertisement (informational + `·` glyph, not ✗, because the spec is SHOULD). Backend per-leg `errors[]` + flow into an inline bullet list. The panel is mounted in the + OIDCProvidersPage create modal AND the OIDCProviderDetailPage edit form — + the edit-form half is load-bearing for verifying IdP rotations (Keycloak + realm rename, Okta tenant move) without committing first. Run button is + disabled until the issuer URL is non-empty (whitespace-trimmed); the + component is read-only — safe to run repeatedly. 8 Vitest tests pin the + glyph-vs-glyph contract (✓/✗/⚠/·), the button-disabled-without-issuer + shape, and the test-id-suffix collision-prevention when the panel is + mounted twice on the same page. + - **Scope-aware actor-role revoke (Audit 2026-05-11 A-4).** HIGH-10 made it possible to grant the same role to the same actor at multiple scopes (e.g. `r-operator` on `profile=p-acme` AND `profile=p-globex`) diff --git a/web/src/pages/auth/OIDCProviderDetailPage.tsx b/web/src/pages/auth/OIDCProviderDetailPage.tsx index 2bef966..da96d85 100644 --- a/web/src/pages/auth/OIDCProviderDetailPage.tsx +++ b/web/src/pages/auth/OIDCProviderDetailPage.tsx @@ -12,6 +12,7 @@ import { useAuthMe } from '../../hooks/useAuthMe'; import PageHeader from '../../components/PageHeader'; import ErrorState from '../../components/ErrorState'; import { validateEmailDomain } from './OIDCProvidersPage'; +import OIDCTestConnectionPanel from './OIDCTestConnectionPanel'; // ============================================================================= // Bundle 2 Phase 8 — OIDCProviderDetailPage. @@ -623,6 +624,17 @@ export default function OIDCProviderDetailPage() { )} {editing && ( <> + {/* Audit 2026-05-11 Fix 09 — Test Connection panel (MED-5 GUI half). + Lets the operator verify an issuer URL change post-rotation + (e.g. Keycloak realm rename, Okta tenant move) without + committing first. Reads from the live edit state so the + scope of the test matches what Save would persist. */} + + + {err && ( +
+ {err} +
+ )} + {result && ( + + )} + + ); +}