Skip to content

feat(auth): lock accounts after repeated failed sign-ins (#102) - #103

Merged
amar-python merged 1 commit into
mainfrom
feat/m2a2-login-lockout
Oct 26, 2026
Merged

amar-python merged 1 commit into
mainfrom
feat/m2a2-login-lockout

Conversation

@amar-python

Copy link
Copy Markdown
Owner

Fixes #102 (approved by you on 26 Oct). Part of ART Milestone 2 (BR-36).

Behaviour

  • The lock. After 10 wrong passwords within 15 minutes, the account is locked for 15 minutes. Both numbers are configurable: LOGIN_MAX_FAILURES and LOGIN_LOCKOUT_MINUTES.
  • What a locked account sees. Sign-in returns the same 401 as any other failure, so the response doesn't reveal that the account exists. Password checking still runs, so a locked attempt takes as long as any other.
  • Resetting the count. A successful sign-in clears it. So do failures more than 15 minutes apart, which start a new count.
  • What counts. Only wrong passwords for a real user. A correct password for a tenant the user doesn't belong to doesn't count.
  • The rate limit stays. The existing per-client limit (20 writes a minute) still applies on top.
  • Migration 0005. Adds the counters to control.users. Like 0004, it only touches the shared control schema, not tenant schemas.

Evidence

All runs are against local PostgreSQL 16.

Check Result
Local replica of the CI integration job (scripts/test_report.py --strict) 285 passed, 0 failed, 0 skipped (281 on main + 4 new)
Evals p,i,s,e 26/26
tests/test_accounts.py 16 passed, including 4 lockout tests:
• the 11th attempt is refused even with the right password
• 9 failures and then a success resets the count
• the lock expires
• old failures fall out of the window
Same tests with the lock check removed lockout test fails (as expected)
DB-free pytest 128 passed
scripts/lint.sh clean

Generated by Claude Code

After LOGIN_MAX_FAILURES (10) wrong passwords within LOGIN_LOCKOUT_MINUTES
(15), the account is locked for 15 minutes. A locked account gets the
same 401 as any other failure; a success clears the count. Migration
0005 adds the counters to control.users and, like 0004, skips tenant
schemas.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YPoXzBSj89ZHgw7nfTmbB
@amar-python amar-python added this to the ART extension milestone Oct 26, 2026 — with Claude
@amar-python amar-python added enhancement New feature or request art ART framework extension work labels Oct 26, 2026 — with Claude
@amar-python
amar-python merged commit 6731f8b into main Oct 26, 2026
3 checks passed
@amar-python
amar-python deleted the feat/m2a2-login-lockout branch October 27, 2026 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

art ART framework extension work enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M2a-2: lock accounts after repeated failed sign-ins (BR-36)

2 participants