feat(auth): TOTP MFA with recovery codes and pre-auth step-up - #62
Merged
Conversation
Implements comprehensive TOTP-based multi-factor authentication with: - TOTP secret generation and provisioning URI for QR codes (pyotp) - Per-user recovery codes (8 single-use codes, bcrypt hashed) - Pre-auth token step-up (5-minute JWT, scope='mfa:verify') - TOTP replay attack prevention (timestamp counter tracking) - Fernet encryption for secret storage using app SECRET_KEY + HKDF-SHA256 - Full enroll → activate → login → verify → disable lifecycle - Security: constant-time recovery code comparison, never logs codes/secrets Files: - mfa_service.py: core MFA logic (TOTP, recovery codes, tokens, encryption) - mfa.py blueprint: enroll, activate, disable endpoints + auth/mfa-verify - auth.py: modified login to return pre_auth_token when mfa_enabled - schema.py: added mfa_enabled, mfa_secret, mfa_recovery_codes, mfa_last_totp_counter - 008_add_mfa_fields.py: Alembic migration - 29 tests: enroll, activate, verify, disable, replay detection, security All 171 tests pass (169 existing + 2 new security tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🧙 Sourcery is reviewing your pull request! Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Sorry @PenguinzTech, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
This was referenced Jul 26, 2026
PenguinzTech
added a commit
that referenced
this pull request
Jul 27, 2026
008_add_mfa_fields (#62) and 008_machine_clients/008_audit_events (already-merged #61/#63) both independently claimed down_revision=007_revoked_token, creating two divergent heads (009_oidc_trust_anchors and 008_add_mfa_fields). Git's merge saw no textual conflict since they're different files, so this surfaced only after the merge completed. Re-chained 008_add_mfa_fields after 009_oidc_trust_anchors so the migration graph has a single linear head again. Full manager suite: 229/229 passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PenguinzTech
added a commit
that referenced
this pull request
Jul 27, 2026
- .pre-commit-config.yaml: combined the 3-way pre-commit divergence. Took this branch's flake8 approach (single .flake8 source of truth via --config, precise files: scoping to app/bins dirs, flake8-bugbear added) over the earlier same-session emergency inline-args patch on v2.1.x. Took this branch's newer valid hadolint tag (v2.14.0) over v2.13.1. gitleaks entry was already identical on both sides (protect --staged --source .) — no divergence there after all. - .gitleaks.toml: added an allowlist entry for the well-known pyotp/Google-Authenticator tutorial TOTP secret (base32 for "Hello!!!"), which #62 (MFA, merged after this branch was created) uses in docstrings/tests — not a real credential. - dhcp-server test-isolation fix (found during this merge's full-suite re-verification, not part of either branch's original diff): test_dhcp_allocation.py imports app.db at collection time, which imports app.config and caches JWT_PUBLIC_KEY=None before any fixture sets the env var; later test_auth.py tests then ran against the stale cached None. Fixed by clearing app.*/bins.server from sys.modules in the setup_env fixture so every test gets a fresh import after env vars are set. Test-harness-only — the real server imports config exactly once at actual startup. - flake8-bugbear (newly enforced by this merge) caught 3 genuine minor issues in the kid-rotation code: an unused import and unused loop variables (kid_val -> _kid_val) in dhcp-server/app/auth.py and ntp-server/bins/server.py's multi-key verification loops. Full suite after combine: manager 229/229, dns-server 63/63, dhcp-server 32/32 (order-independent), ntp-server 51/51, squawk-client 13/13. flake8 clean, gitleaks clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TOTP multi-factor auth for manager users: enroll → activate (returns 8 bcrypt-hashed single-use recovery codes once) → step-up login. Users with MFA get a 5-minute pre-auth JWT scoped only
mfa:verify(rejected by all normal endpoints — tested), then/api/v1/auth/mfa-verifyissues the real pair. Secrets Fernet-encrypted at rest (HKDF from SECRET_KEY); TOTP replay blocked via last-used timestep; disable requires password + code. pyotp==2.9.0 exact-pinned.Tests: 171 green (29 new). Login-route diff kept to 9 lines; non-MFA users unaffected.
Merge note: contains alembic migration
008— collides with 008 in the audit and NHI branches; renumber whichever merges later.Stack note: bases on
chore/dedup-reusable-code(top of the #53–#59 chain); auto-retargets towardv2.1.xas the stack merges bottom-up.🤖 Generated with Claude Code
Summary by Sourcery
Introduce TOTP-based multi-factor authentication with a pre-auth step-up login flow, recovery codes, and supporting database and service changes.
New Features:
Enhancements:
Build:
Deployment:
Tests: