A serverless Multi-Factor Authentication (MFA) service built with SST, supporting both app authenticator (TOTP) and email one-time password (OTP) methods.
npm install @xcelsior/mfa-apiA serverless Multi-Factor Authentication (MFA) service built with SST, supporting both app authenticator (TOTP) and email one-time password (OTP) methods.
- App Authenticator: TOTP-based MFA using apps like Google Authenticator, Authy, etc.
- Email OTP: One-time password sent via email
- API Key Authentication: Secure API access with API key validation
- Device Management: Create, list, update, and delete MFA devices
- Challenge-Response Flow: Secure verification process with expiration and attempt limits
- AWS DynamoDB: Scalable data storage with automatic TTL for expired challenges
- Email Integration: Uses the @xcelsior/email service for sending OTP codes
All API requests require authentication using an API key in the X-API-Key header.
- POST /api/mfa/devices - Create a new MFA device
- GET /api/mfa/devices/{userId} - List all devices for a user
- PUT /api/mfa/devices/{deviceId} - Update device settings
- DELETE /api/mfa/devices/{deviceId} - Delete a device
- POST /api/mfa/devices/{deviceId}/verify-setup - Verify device setup
- POST /api/mfa/challenges - Create a new MFA challenge
- POST /api/mfa/challenges/{challengeId}/verify - Verify a challenge with code
- Node.js 18+
- AWS CLI configured
- SST CLI installed
1. Install dependencies:
``bash`
npm install
2. Start development server:
`bash`
npm run dev
3. Deploy to AWS:
`bash`
npm run deploy
`bash`
curl -X POST https://api.example.com/api/mfa/devices \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"type": "app",
"name": "My Phone Authenticator"
}'
Response includes QR code and secret for setup:
`json`
{
"data": {
"deviceId": "device-uuid",
"qrCodeUrl": "data:image/png;base64,...",
"secret": "JBSWY3DPEHPK3PXP"
}
}
`bash`
curl -X POST https://api.example.com/api/mfa/devices \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"type": "email",
"name": "Work Email",
"email": "user@example.com"
}'
`bash`
curl -X POST https://api.example.com/api/mfa/devices/device-uuid/verify-setup \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"code": "123456"
}'
`bash`
curl -X POST https://api.example.com/api/mfa/challenges \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"userId": "user123",
"deviceId": "device-uuid"
}'
`bash`
curl -X POST https://api.example.com/api/mfa/challenges/challenge-uuid/verify \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"code": "123456"
}'
The service uses the following environment variables:
- POWERTOOLS_SERVICE_NAME: Service name for loggingPOWERTOOLS_METRICS_NAMESPACE
- : Metrics namespacePOWERTOOLS_LOGGER_LOG_LEVEL
- : Log level (INFO, DEBUG, etc.)AWS_REGION
- : AWS region for deployment
- Device operations: 100 requests per hour per API key
- Challenge operations: 500 requests per hour per API key
- Verification attempts: 3 attempts per challenge
- API Key Authentication: All endpoints require valid API key
- Challenge Expiration: Challenges expire after 5 minutes
- Attempt Limiting: Maximum 3 verification attempts per challenge
- Device Activation: Devices must be verified before use
- Automatic Cleanup: Expired challenges are automatically removed via DynamoDB TTL
- npm run dev - Start development servernpm run build
- - Build the projectnpm run deploy
- - Deploy to AWSnpm run remove
- - Remove from AWSnpm run console
- - Open SST consolenpm run typecheck
- - Run TypeScript checks
```
services/mfa-api/
├── packages/
│ └── functions/
│ ├── mfa/
│ │ ├── createDevice.ts
│ │ ├── verifySetup.ts
│ │ ├── listDevices.ts
│ │ ├── updateDevice.ts
│ │ ├── deleteDevice.ts
│ │ ├── createChallenge.ts
│ │ └── verifyChallenge.ts
│ ├── middleware/
│ │ └── apiKeyAuth.ts
│ ├── config.ts
│ └── types.ts
├── stacks/
│ └── MfaStack.ts
├── docs/
├── package.json
├── sst.config.ts
└── tsconfig.json
The service uses the following key dependencies:
- SST: Serverless framework
- AWS SDK: DynamoDB operations
- @xcelsior/email: Email service for OTP delivery
- @xcelsior/lambda-http: HTTP utilities and middleware
- speakeasy: TOTP generation and verification
- qrcode: QR code generation for app authenticator setup
- zod: Runtime type validation
The service includes comprehensive logging and tracing:
- AWS X-Ray tracing for request tracking
- CloudWatch metrics and logs
- Structured logging with correlation IDs
- Error tracking and alerting
This project is part of the Excelsior packages monorepo.