Open-MFA is a demo project that implements an authentication server supporting OTP (One-Time Password), HOTP (HMAC-Based One-Time Password) and TOTP (Time-Based One-Time Password) algorithms.
- The authentication server creates a unique Flask session ID for each user. All OTP codes generated for a user are linked to their unique session ID and stored into a Redis database. Both sessions and OTP codes have a 60-minutes expiration.
- For properly validating HOTP and TOTP codes, URIs should be converted into QR Code using tools like 2FA-QR. These QR codes can then be scanned with any authenticator app, such as Google Authenticator, which supports OTP algorithms generation.
- In a real-world authentication server, the Identity and Access Management (IAM) would be much more robust and complex, however for demo purposes, this application has been deliberately simplified.
- OTP algorithms use hash functions (like HMAC-SHA1) that receive two inputs: a seed and a moving factor.
- The seed is a static and non-guessable secret that may be shared with the client in HOTP and TOTP implementations, but must always be securely stored by the authentication server.
- The moving factor is a dynamic value that must be distinct for each OTP code generation. This value, combined with the seed, produces different OTP codes for each authentication request.
- Different OTP implementations exist due to variations in how the moving factor is generated and whether the HMAC secret is shared with the client.
- While there are RFCs for HOTP (RFC 4226) and TOTP (RFC 6238), there is no specific RFC for a simplified OTP implementation. However, such implementation may be the most common on the world wide web today, often found in scenarios like email verification or temporary login codes. Despite their widespread use, any simplified OTP implementation should still follow the security guidelines outlined in the HOTP and TOTP specs.
- All implementations must use HTTPS to secure communication between the authentication server and the client.
- The authentication server must randomly generate OTP HMAC secrets at the hardware level, or using a cryptographically strong pseudorandom generators.
- The authentication server must securely store OTP HMAC secrets in a controlled access database.
- The authentication server must deny replay attacks by rejecting any already-used OTP code.
- The authentication server or infrastructure must throttle (rate limit) brute-force attacks.
- While the HOTP and TOTP specifications recommend using HMAC-SHA1 method, modern and safer methods like HMAC-SHA256 are preferable.
- Install Docker engine for development and staging deployment.
- Install AWS CLI and Terraform for production deployment.
Inside /deploy/docker-compose directory:
- Copy the
.env.examplefile todev/.envand replace the variables with real values. - Run
chmod +x ./dev/setup.shandsudo ./dev/setup.shto install and configure mkcert and hosts file. - Run
make dev-upto start the stack. - The application will be available at:
https://open-mfa.local
Inside /deploy/docker-compose directory:
- Copy the
.env.examplefile tostaging/.envand replace the variables with real values. - Run
make staging-upto start the stack. - The application will be available at:
https://${DNS_DOMAIN}
- Create an AWS
IAM userfor terraform operations withAdministratorAccesspolicy attached. - Configure an
AWS CLI profileusing the IAM user credentials. - Set up
core-stackmodule variables file based onterraform.tfvars.example. - Initialize the terraform modules in the following order:
- Bootstrap - Initializes the S3 remote state backend. This must be created first to store the entire stack's state and cannot be destroyed.
- Core Stack - Deploys ECR, Route53 hosted zone and application secrets. These are the critical infra components required by CI/CD and the application, and cannot be destroyed.
- App Stack - Deploys ECS, VPC, ELB, CloudWatch and WAF. This is the application stack that can be destroyed and redeployed at any time.
This project is a case study demonstrating the use of the following technologies:
- Architecture:
- RESTful API design.
- Clean architecture.
- Layered architecture.
- Domain-driven design (DDD).
- Backend:
- Flask - Web framework.
- PyOTP - Library for OTP algorithms implementation.
- Marshmallow - Library for REST API data validation.
- Redis - Database for OTP storage.
- Python Logging - Configurable runtime logging.
- Pytest and Hypothesis - Unit, integration, and property-based testing.
- Flasgger - Swagger UI and OpenAPI documentation.
- DevOps:
- Codecov - Code coverage reports.
- Docker - Services containerization.
- GitHub Actions - CI/CD pipelines for testing and deployment.
- GitHub Container Registry - Public container image registry.
- AWS Elastic Container Registry - Private container image registry.
- Docker Compose - Multi-service orchestration.
- Development deployment:
- Staging deployment:
- Gunicorn WSGI production-grade server.
- Nginx-proxy and letsencrypt for HTTPS, reverse proxy and rate-limit.
- AWS and Terraform - Infrastructure as Code (IaC) for production deployment.
- S3 - Remote terraform state backend storage.
- ECS Fargate - Serverless container deployment.
- ELB - Application Load Balancing.
- Route 53 - DNS management and routing.
- Cloudwatch - Observability for ECS services.
- AWS WAF - Web Application Firewall for rate limiting.