Skip to content

eVault-Core: Security Questions Backend — Normalisation, Hashing & Validation #967

@plansombl

Description

@plansombl

Description

Implement the backend module for security questions in eVault-Core. Questions themselves are human-readable and served as plaintext. Answers must be normalised (trimmed, lowercased, whitespace-collapsed, punctuation stripped) and then hashed with Argon2id before storage — they are never persisted in raw form. A validation mechanism applies the same normalisation pipeline to any incoming answer before comparing it against the stored hash.

Reference

Answer Ingestion & Storage Pipeline

flowchart TD
    A([Raw Answer Input]) --> B[Trim leading & trailing whitespace]
    B --> C[Collapse internal whitespace]
    C --> D[Convert to lowercase]
    D --> E[Strip punctuation & special characters]
    E --> F[Normalised Answer String]
    F --> G[Hash via Argon2id]
    G --> H[(Store: answer_hash)]

    Q([Question Text]) --> QS[(Store: question plaintext)]
Loading

Validation Flow

flowchart TD
    A([User submits answer]) --> B[Apply normalisation pipeline]
    B --> C[Normalised candidate string]
    C --> D[Fetch stored answer_hash for user + question]
    D --> E{Hash comparison}
    E -- Match --> F[✅ Validation passed]
    E -- No match --> G[❌ Validation failed]
    G --> H[Increment failed attempt counter]
    H --> I{Attempt limit reached?}
    I -- Yes --> J[🔒 Lock / rate-limit user]
    I -- No --> K[Return error to caller]
Loading

Data Model

erDiagram
    SECURITY_QUESTION {
        uuid        id          PK
        string      text
        bool        is_active
        timestamp   created_at
    }

    USER_SECURITY_ANSWER {
        uuid        id              PK
        uuid        user_id         FK
        uuid        question_id     FK
        string      answer_hash
        timestamp   created_at
        timestamp   updated_at
    }

    USER ||--o{ USER_SECURITY_ANSWER : "sets"
    SECURITY_QUESTION ||--o{ USER_SECURITY_ANSWER : "answered via"
Loading

Acceptance Criteria

  • Questions are retrievable as plaintext via a read endpoint
  • Answer normalisation pipeline is applied consistently on both write and validate paths:
    • Trim leading/trailing whitespace
    • Collapse internal whitespace
    • Convert to lowercase
    • Strip punctuation, special characters, and padding
  • Answers are hashed with Argon2id and never stored in raw or reversible form
  • A validation endpoint accepts a candidate answer, applies the normalisation pipeline, and compares the resulting hash against the stored hash
  • Failed validation attempts are tracked per-user; account is locked / rate-limited after a configurable threshold
  • Unit tests cover: normalisation edge cases, hash round-trips, validation success & failure paths

Desired Output (may vary)

A secure, testable backend service/module within eVault-Core that cleanly separates question storage, answer normalisation, hashing, and validation concerns.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions