Files
gapido-grpc-auth/README.md

2.6 KiB

Gapido Backend Code Challenge

Python gRPC OTP authentication service with MongoDB, Redis, RabbitMQ, and selectable SMS providers.

Architecture

  • auth-service: async grpc.aio API for OTP login, token refresh, token revocation, and RBAC demo methods.
  • sms-worker: RabbitMQ consumer that sends OTP messages through the configured SMS provider.
  • 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. The demo UI is available at http://localhost:8080. RabbitMQ management is available at http://localhost:15672 with guest / guest.

SMS Provider

The SMS integration uses the Strategy pattern behind the SmsClient port. Select the provider with:

SMS_PROVIDER=kavenegar

Supported values:

  • kavenegar: uses KAVENEGAR_API_KEY and KAVENEGAR_LOGIN_TEMPLATE.
  • sms_ir: uses SMS_IR_API_KEY and SMS_IR_VERIFY_TEMPLATE_ID.
  • debug: local-only provider that stores the latest OTP in Redis for the demo UI.

Demo UI

demo-app is a small FastAPI backend-for-frontend, implemented as the sibling package gapido_demo, that calls auth-service over gRPC. It demonstrates how another microservice consumes the auth service.

Available browser actions:

  • Request and verify OTP.
  • Fetch the local debug OTP when DEMO_ENABLE_DEBUG_OTP=true.
  • Call public, authenticated-user, and admin-only gRPC methods.
  • Refresh and revoke tokens.

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.
  • SMS providers are hidden behind adapters and mocked in tests.