Files
zeekay 10716f8a5a auth: Hanzo IAM is the only way in
`/login` looped. It redirects to `/login/oidc/`, and `sso_login` answers a
backend it cannot find with `/login?error_code=invalid_sso_provider`, which is
`/login` again. The gate that decides which backends exist,
`get_instance_available_sso_providers`, only ever named github, gitlab and
google-oauth2 — none of which are in `AUTHENTICATION_BACKENDS`. The one backend
that IS wired, `social_core.backends.open_id_connect.OpenIdConnectAuth`, was
never in the map, so the one real provider was the one that could not be
reported available. It now answers `oidc` (the backend's own `name`), gated on
the three settings the handshake needs, and the vendor keys that fed the old
answer are gone.

A failed handshake also has somewhere to land: bare `/login` still goes straight
to the IdP, but `/login?error_code=...` renders the scene instead of bouncing
back into the retry that produced it.

The other door is deleted rather than repaired. Local password login, the dev
login, password reset, email verification, TOTP and backup codes, code-based
email verification, passkeys, and signup-with-password could each mint a session
without IAM ever being asked. Deleting them removes 29k lines: the views and
serializers, their routes and router registrations, the throttles, the emails
and templates, the admin actions, the SPA scenes that posted to them, and their
tests. django-axes goes with them — it exists to slow password guessing, and
there are no passwords to guess. django_otp stays installed only because
organization_member and the admin inlines still read its models.

What survives is the pipeline: `sso_login`, `social_create_user`, invite
acceptance and JIT provisioning through the IdP, and `social_login_notification`.
Invited users now join by signing in — `process_social_invite_signup` consumes
the invite held in the session. `ModelBackend` stays for Django's permission
lookups, which the OIDC backend does not implement; nothing calls
`authenticate()` with a password any more.

Two password checks are NOT user auth and are untouched: the share-link password
on exported dashboards, and `credentials_reviewed_at`, which surfaces
partner-issued personal API keys for review.

No model or migration is touched. `WebauthnCredential` and `User.password`
outlive their callers because this repo's migration graph cannot currently
build, so no migration can run; removing the views is what removes the ability
to authenticate.
2026-08-08 14:29:12 -07:00
..