0bf7268d9ca378cc6234fafa9e3788d849ddff17
Gapido Backend Code Challenge
Python gRPC OTP authentication service with MongoDB, Redis, RabbitMQ, and a Kavenegar SMS adapter.
Architecture
auth-service: asyncgrpc.aioAPI for OTP login, token refresh, token revocation, and RBAC demo methods.sms-worker: RabbitMQ consumer that sends OTP messages through Kavenegar.- MongoDB stores users and refresh-token sessions.
- Redis stores OTP hashes, TTL, verification attempts, and OTP request rate limits.
- RabbitMQ decouples authentication from SMS delivery.
Run
cp .env.example .env
docker compose up --build
The gRPC service listens on localhost:50051. RabbitMQ management is available at http://localhost:15672 with guest / guest.
Local Development
python -m venv .venv
pip install -e ".[dev]"
python -m gapido_auth.tools.generate_proto
pytest
gRPC Methods
RequestOtp: public; creates a short-lived OTP and publishes an SMS job.VerifyOtp: public; verifies OTP and returns access and refresh tokens.RefreshToken: public; rotates refresh token and returns a new token pair.RevokeRefreshToken: authenticated; revokes a refresh token session.PublicPing: public.UserOnly: requires any authenticated active user.AdminOnly: requires an authenticated admin.
Protected calls use metadata:
authorization: Bearer <access_token>
Security Notes
- OTP codes are generated with
secrets, stored only as HMAC hashes in Redis, and expire after 120 seconds by default. - OTP requests are rate-limited per mobile number and client identity.
- Refresh tokens are opaque random values; only SHA-256 hashes are persisted.
- Refresh tokens rotate on use.
- Kavenegar is hidden behind an adapter and mocked in tests.
Description
Languages
Python
91.8%
JavaScript
3.3%
CSS
2%
HTML
2%
Dockerfile
0.5%
Other
0.4%