Designing a Reactive, Event-Driven Email OTP Login System with CQRS and Event Sourcing

Designing a Reactive, Event-Driven Email OTP Login System with CQRS and Event Sourcing

Modern authentication systems are moving beyond passwords. With the rise of passwordless authentication, One-Time Passwords (OTPs) delivered over email or SMS are becoming a trusted standard for secure and seamless user logins.

However, implementing an OTP-based login mechanism that is scalable, reactive, and audit-compliant requires more than a simple verification service. It demands an architecture that supports asynchronous workflows, event traceability, and reactive scalability — all while keeping the system maintainable and extendable.

In this post, we’ll walk through the conceptual design of a Reactive OTP Login System built using Spring Boot, CQRS (Command Query Responsibility Segregation), and Event Sourcing.
We’ll focus purely on the architecture and system flow — without diving into code — to illustrate how such a system achieves high throughput, clean separation of concerns, and full auditability.

Architectural Overview

At its core, this system adopts a Reactive CQRS + Event Sourcing design:

  • Commands modify the system state (e.g., logging in a user).
  • Queries fetch or compute data without altering state (e.g., generating OTP for a user).
  • Events record every state transition as an immutable fact.
  • Reactive Streams (Mono/Flux) ensure non-blocking, backpressure-aware execution.

Step 1: Requesting an Email OTP

The OTP generation process begins when a user initiates a login using their email.

Conceptual Flow

  1. The client sends a request to /api/v1/user/request/emailloginotp/{email}.
  2. The Query Controller constructs a RequestEmailLoginOTPQuery, encapsulating the user’s email and tenant metadata.
  3. The Query Dispatcher routes the query to the appropriate Query Handler.
  4. The Query Handler verifies whether the user exists and is active using a reactive repository.
  5. If valid, it invokes EmailLoginOTPService to generate a unique OTP.
  6. It then emits an EmailOTPSentEvent, which is published to Kafka for asynchronous notification delivery and audit tracking.
  7. The API responds with a confirmation that the OTP request was processed successfully.

Step 2: Validating the Email OTP (Login Process)

Once the user receives the OTP, they can authenticate using it.

Conceptual Flow

  1. The client submits a POST request to /api/v1/user/validate/emailloginotp with email and otp.
  2. The Command Controller validates the OTP through the EmailLoginOTPService.
  3. On success, it dispatches a LogInWithEmailOTPCommand to the Command Handler.
  4. The Command Handler performs several key actions:
    • Rehydrates the user’s aggregate state from the Event Store.
    • Raises a LoggedInWithEmailOTPEvent to represent successful login.
    • Persists this event back to the Event Store.
  5. The Event Handler listens for the event, updating the read projection (user table) to reflect login status.
  6. The JWT Token Provider issues a new access token for the authenticated session.
  7. The client receives a success response along with the token.

Event Sourcing Lifecycle

Event Sourcing lies at the heart of this system.
Every change in user state — from OTP sent to login success — is captured as a domain event and stored immutably in the Event Store.

Conceptual Event Chain

SequenceEvent NameDescription
1EmailOTPSentEventOTP generated and dispatched via Kafka.
2LoggedInWithEmailOTPEventUser successfully logged in with the OTP.
3AuditRecordedEventLogin and OTP actions recorded for compliance.

Replaying these events allows the system to rebuild state from history, ensuring full traceability and fault recovery without traditional database state dependencies.

Security and Compliance Considerations

Security is baked into every stage of the pipeline:

  • OTP expiration, uniqueness, and rate limiting are handled by the EmailLoginOTPService.
  • JWT tokens provide stateless, secure session management.
  • Audit events ensure all critical actions are logged for compliance.
  • Tenant-aware scoping enforces strict data isolation in multi-tenant setups.

By combining event logs with JWT-based access, the system achieves both security and observability.

Conclusion

Building an OTP-based authentication system using Reactive, CQRS, and Event Sourcing principles enables:

Scalable, non-blocking performance under heavy traffic
Strict auditability with event logs
Fault tolerance through event replay
Extensibility for future login channels or audit pipelines
Seamless user experience with real-time responsiveness

In essence, this architecture transforms a simple OTP mechanism into a production-grade authentication framework — one that is reactive by nature, event-driven by design, and compliant by default.

Read more