Phase 4: real OIDC human login (enterprise/internal/loginhandler)
Closes the other major named gap from this phase: until now, there was no way for a human to actually log in -- only /alerting's RoleService credential could be minted. GET /auth/oidc/login and GET /auth/oidc/callback drive the real coreos/go-oidc flow already wired in enterprise/internal/oidc: CSRF state in a short-lived cookie, code exchange, ID token verification, upserting a users row, resolving tenant/role from exactly one tenant_memberships row (refusing outright on zero or more than one, rather than guessing), and issuing a real session cookie. Unlike everything else built this phase, this one is genuinely verified end to end: the tests spin up coreos/go-oidc's own oidctest fake IdP, which signs real RS256 ID tokens, and drive the full login->callback-> session-cookie round trip through actual signature verification -- no live database or Docker needed, so nothing here is asserted without having actually been run in this session. Also fixes a real bug caught while wiring this into enterprise-auth's main.go: assigning a nil *oidc.Provider to the handler's interface field would have produced a non-nil interface wrapping a nil pointer (Go's classic typed-nil trap), silently breaking the "OIDC not configured" no-op path -- New() now takes the concrete pointer type and checks it before ever converting to the interface, with a regression test pinning the fix down. Still missing: SAML's equivalent (ACS endpoint), a tenant-picker UI for multi-membership identities, and any admin UI to actually create a tenant_memberships row (today that's manual SQL, documented in the runbook's new bootstrap walkthrough).
This commit is contained in:
@@ -152,17 +152,24 @@ access partway through the phase, so only the audit-logging guarantees
|
||||
were actually confirmed against a live database; the rest is untested
|
||||
beyond "compiles, and skips cleanly when no live database is
|
||||
configured" (see `/docs/phase-4-runbook.md`'s verification-status
|
||||
section). Two things still keep this phase from being done: SSO login
|
||||
(OIDC/SAML protocol wiring exists, no
|
||||
HTTP login handler calls it), and Tantivy/free-text queries have no
|
||||
per-tenant index routing at all (`enterprise-api` closes the ClickHouse
|
||||
half of tenant isolation, not the Tantivy half) — plus a deployment gap
|
||||
worth naming explicitly: nothing yet forces or even flags whether a
|
||||
given deployment is actually running the isolated binary
|
||||
(`enterprise-api`) versus the plain single-tenant one (`api`); both
|
||||
still exist and nothing currently prevents mixing them up. Full
|
||||
accounting: `/docs/security/threat-model.md`; step-by-step verification
|
||||
procedure (not yet run against a live cluster in this environment):
|
||||
section). Human OIDC login is now built too
|
||||
(`enterprise/internal/loginhandler`: `GET /auth/oidc/login` +
|
||||
`GET /auth/oidc/callback`, issuing a real session cookie after resolving
|
||||
tenant/role from `tenant_memberships`) — genuinely verified, unlike the
|
||||
ClickHouse pieces, via a real fake IdP that signs and verifies actual
|
||||
RS256 tokens (`loginhandler_test.go`, all passing), though never tried
|
||||
against a real external IdP or through a running `enterprise-auth`
|
||||
container. Two things still keep this phase from being done: SAML login
|
||||
(protocol wiring exists, no ACS handler calls it, following OIDC's now
|
||||
-built pattern), and Tantivy/free-text queries have no per-tenant index
|
||||
routing at all (`enterprise-api` closes the ClickHouse half of tenant
|
||||
isolation, not the Tantivy half) — plus a deployment gap worth naming
|
||||
explicitly: nothing yet forces or even flags whether a given deployment
|
||||
is actually running the isolated binary (`enterprise-api`) versus the
|
||||
plain single-tenant one (`api`); both still exist and nothing currently
|
||||
prevents mixing them up. Full accounting:
|
||||
`/docs/security/threat-model.md`; step-by-step verification procedure
|
||||
(not yet run against a live cluster in this environment):
|
||||
`/docs/phase-4-runbook.md`. The rest of this section describes the exit
|
||||
bar this phase is aiming at, not a completed state.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user