Skip to content

auth: add local TOTP enrollment helpers#103

Merged
joshcramer merged 3 commits intomainfrom
feat/dd-043-totp-support-pr2
Apr 29, 2026
Merged

auth: add local TOTP enrollment helpers#103
joshcramer merged 3 commits intomainfrom
feat/dd-043-totp-support-pr2

Conversation

@larimonious
Copy link
Copy Markdown
Contributor

Summary

Implements DD-043 PR 2: Strong TOTP Support for local auth.

  • Adds local TOTP lifecycle helpers:
    • begin_totp_enrollment(identifier, options?)
    • confirm_totp_enrollment(identifier, code, options?)
    • verify_local_totp(identifier, code, options?)
    • totp_status(identifier, options?)
    • reset_totp(identifier, options?)
  • Stores TOTP lifecycle state under reserved auth-owned local identity metadata (auth.totp) instead of requiring template-owned TOTP tables.
  • Keeps pending/confirmed TOTP secrets out of safe payloads (local_user, totp_status, current_user); enrollment returns only one-time setup URI material for QR display.
  • Preserves active TOTP during re-enrollment: starting a new enrollment leaves enabled=true while pending=true, avoiding a password-only downgrade window.
  • Rejects disabled/locked local accounts consistently across TOTP helpers.
  • Adds typechecker signatures and user-facing docs for staged password → TOTP challenge composition.
  • Marks DD-043 PR2 complete and records attempt throttling/replay tracking as future policy if apps need std/auth-owned lockout.

Test Plan

  • Red/green TDD for new TOTP helpers:
    • cargo test totp -- --nocapture
  • Targeted auth suite:
    • cargo test auth -- --test-threads=1
  • Full suite:
    • cargo test
  • Pre-push/core checks:
    • cargo fmt
    • cargo fmt -- --check
    • cargo build --profile dev-release
    • ./target/dev-release/ntnt docs --generate
    • git diff --check
    • ./target/dev-release/ntnt validate examples/
    • ./target/dev-release/ntnt lint examples/

Notes:

  • Example validation passes with existing warnings in examples/collections_demo.tnt.
  • Example lint passes with existing warnings/suggestions; no new lint errors.
  • Local auth backend contract env vars are set in this environment, so auth contract tests exercised configured live backends as well as memory/SQLite.

Review

  • Ran delegated security/code review before push.
  • Fixed first-pass findings around active re-enrollment, disabled/locked status, current-user leakage tests, unsafe docs examples, setup URI handling guidance, and TOTP throttling/replay policy deferral.
  • Second-pass review found no remaining Bucket 1/2/3 findings.

Known Limitations / Deferrals

  • verify_local_totp(...) verifies codes but does not own failed-attempt throttling, lockout policy, or last-used-step replay tracking. DD-043 now records that as a future std/auth refinement if real apps need it centralized; apps should wrap TOTP routes with their normal rate limiting/backoff today.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 29, 2026

Greptile Summary

This PR implements five local TOTP lifecycle helpers (begin_totp_enrollment, confirm_totp_enrollment, verify_local_totp, totp_status, reset_totp) storing enrollment state under the reserved auth.totp metadata namespace, keeping keys out of all safe payloads and preserving active TOTP during re-enrollment. The implementation is thorough — enumeration resistance is carefully maintained across not-found, disabled/locked, missing-key, and malformed-metadata paths, created_at is correctly preserved on confirmation, and the previously noted issuer divergence in verify_totp_code is fixed.

Confidence Score: 5/5

Safe to merge; the single finding is a P2 edge case on the storage-error path that doesn't affect the primary auth or enumeration-resistance paths.

Only P2 findings present. The implementation correctly handles all major security concerns: key isolation, enumeration resistance across all normal failure modes, active-TOTP preservation during re-enrollment, and disabled/locked account rejection. The one gap (storage errors returning raw error strings) is a minor inconsistency on an exceptional path.

src/stdlib/auth/local.rs — storage error path in verify_local_totp_record (lines 172–175)

Important Files Changed

Filename Overview
src/stdlib/auth/local.rs Core TOTP lifecycle implementation — enrollment, confirmation, verification, status, reset — well-structured with good enumeration resistance; one gap where storage errors return raw error strings instead of the generic TOTP failure message.
src/stdlib/auth/primitives.rs Adds issuer parameter to verify_totp_code, addressing the previously noted divergence between enrollment and verification TOTP instances.
src/stdlib/auth.rs Registers five new TOTP native functions with correct arity guards, auth-initialized checks, and argument parsing; helper utilities string_arg, parse_totp_options, optional_string_option are clean and reusable.
src/typechecker.rs Adds correct Result<Map, String> type signatures for all five TOTP helpers with proper required(n) arity; type-checker tests verify argument type checking and optional map options.
docs/AI_AGENT_GUIDE.md Adds a comprehensive TOTP enrollment/verification code example with correct staged-challenge composition; setup URI handling guidance and rate-limiting caveats are well-placed.
docs/STDLIB_REFERENCE.md Adds reference entries for all five TOTP helpers with correct signatures, parameter descriptions, and cross-references; table of contents entries are properly alphabetized.

Reviews (3): Last reviewed commit: "fix: harden local TOTP verification erro..." | Re-trigger Greptile

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class local-auth TOTP enrollment/verification helpers to std/auth, persisting lifecycle state in reserved local-identity metadata (auth.totp) and documenting staged password → TOTP flows.

Changes:

  • Added new std/auth native functions for TOTP enrollment, confirmation, verification, status, and reset.
  • Implemented local-record helpers that store/read TOTP lifecycle state in local identity metadata without leaking secrets in safe payloads.
  • Updated typechecker signatures, added tests, and extended user-facing docs/design docs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/typechecker.rs Adds type signatures + typechecker tests for new std/auth TOTP helpers.
src/stdlib/auth/primitives.rs Extends verify_totp_code to accept an issuer (used by local TOTP helpers).
src/stdlib/auth/local.rs Implements local TOTP lifecycle record helpers + metadata utilities (auth.totp).
src/stdlib/auth.rs Exposes new std/auth native functions, shared arg/options parsing helpers, and adds integration tests around non-leakage + reenrollment behavior.
docs/STDLIB_REFERENCE.md Documents new std/auth functions and examples.
docs/AI_AGENT_GUIDE.md Adds guidance and sample flow for local TOTP enrollment + staged login challenges.
design-docs/dd-043-auth-excellence.md Marks DD-043 PR2 items complete and records deferred lockout/throttling.

Comment thread src/stdlib/auth/local.rs Outdated
@joshcramer joshcramer merged commit 3b3155f into main Apr 29, 2026
10 checks 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.

3 participants