Matt Mabrey 7ed3cbec4c T10.3: identity matching and JIT provisioning for Okta sign-in
okta_callback() now completes the sign-in instead of stopping at the claim:

- Matches the OKTA_IDENTITY_CLAIM value to a local account via
  auth.find_user() (username or email, case-insensitive) — the same lookup
  login() already uses, so an account whose username mirrors its AD
  identity needs no migration.
- No match: JIT-provisions a new account at the lowest-privilege role
  (project_user), no project membership, no password hash. Access beyond
  that is still granted locally by an admin/project super user, same as
  any account created by hand via create_user(). Logs a user_created audit
  event (via: okta_jit) for parity with that route.
- Match found but is_active is False: blocked with the same 403 'Account
  is disabled' login() raises today. Okta granting the challenge does not
  override an account this app has disabled locally (D15: 'roles stay
  local').
- On success: issues the same session cookie login() does (auth.create_
  token / auth.set_session_cookie), then redirects the browser to
  /index.html — this route is reached by a full-page navigation from
  Okta's redirect, not a fetch call, so a redirect is required rather than
  the JSON body login() returns.

Verified with a fake Okta client against a throwaway SQLite DB: new
identity provisions correctly (role/email/name/no-password), a repeat
sign-in matches the existing row without duplicating it or touching a
role an admin has since changed, a locally-disabled account is blocked
despite a valid Okta claim, and a missing identity claim is rejected
before touching the database.

wave-10.md T10.3 / D15
2026-09-03 10:16:50 -07:00
Description
No description provided
8.9 MiB
Languages
Python 49.3%
JavaScript 32.6%
CSS 8.9%
HTML 8.7%
Shell 0.4%