Skip to content

fix: enforce active account lifecycle - #47

Merged
HoungDev merged 2 commits into
mainfrom
agent/enforce-active-user-lifecycle
Aug 11, 2026
Merged

fix: enforce active account lifecycle#47
HoungDev merged 2 commits into
mainfrom
agent/enforce-active-user-lifecycle

Conversation

@HoungDev

@HoungDev HoungDev commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • add an admin account status endpoint that disables or re-enables users
  • atomically revoke all refresh-token sessions when an account is disabled
  • reject inactive accounts during password login, access-token resolution, refresh rotation, MFA/OIDC session issuance, and future session issuance paths
  • expose account status in admin responses and document the lifecycle contract

Root cause

User.is_active existed in the data model, and some MFA/OIDC paths checked it, but password login, current-user resolution, and refresh rotation did not enforce it consistently. The admin API also had no supported operation for changing account status and revoking sessions together.

Security behavior

  • disabled accounts cannot create new password sessions
  • otherwise valid access tokens are rejected after the current user is reloaded
  • disabling an account revokes every active refresh-token family with the account_disabled reason
  • refresh attempts for an inactive account fail closed and defensively revoke remaining sessions
  • re-enabling an account permits a new login but does not restore revoked sessions
  • session issuance flushes pending security state, then re-locks and refreshes the user row before creating tokens

Regression fix

The first CI run exposed that SessionLocal(autoflush=False) combined with populate_existing() could discard an accepted MFA counter before commit. Session issuance now explicitly flushes pending security state before reloading the locked user, and a focused regression test protects that ordering.

Validation

GitHub Actions CI run #99 passed:

  • Ruff lint and formatting
  • PostgreSQL 17 migrations and full test suite
  • account-disable integration and MFA replay regression coverage
  • database benchmark smoke test and fixture cleanup
  • coverage artifact upload
  • dependency audit
  • source distribution and wheel build
  • isolated wheel smoke test

Local validation also passed 16 focused unit/rollback tests, package build, OpenAPI smoke, and diff checks.

@HoungDev
HoungDev marked this pull request as ready for review August 11, 2026 13:58
@HoungDev
HoungDev merged commit 9362abc into main Aug 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant