Trust & Security
Security is built in, not bolted on
Resavi connects customers with service businesses across East Africa. Every layer — from the network edge to the database — is designed so that personal data stays protected, accounts stay in the right hands, and payments flow without compromise.
HTTPS
All endpoints, always
RBAC
Five-role hierarchy
AES-256
Credentials at rest
48 hr
Disclosure response SLA
Infrastructure
Hardened from the network edge inward
Traffic enters through nginx reverse proxies that terminate TLS. Beyond that boundary, all communication happens inside an isolated Docker network with no public route to any service, database, or cache.
TLS Everywhere
All public endpoints are served over HTTPS. nginx handles SSL termination and injects X-Forwarded-Proto: https so every downstream service generates correct secure URLs in its API responses.
Network Isolation
Each microservice runs in a private Docker network. There is no public route to any database, message broker, or cache — only the API gateway accepts inbound traffic, and only on the ports it needs.
Rate Limiting
A Redis-backed token bucket enforces per-IP limits at the gateway. Registration, review creation, and payment initiation carry tighter budgets than read-only endpoints.
Security Response Headers
nginx injects Strict-Transport-Security, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and Referrer-Policy: strict-origin-when-cross-origin on every response.
Identity & Access
The right person, in the right place
Authentication is delegated to Keycloak, an open-source identity server running on dedicated infrastructure. Authorisation is enforced server-side by the gateway and each individual service — never by the client.
OAuth 2.0 + OpenID Connect
Keycloak issues short-lived, signed JWTs. No passwords travel to application services — only tokens that expire automatically and can be revoked immediately if an account is compromised.
Google Social Login
Users may sign in with Google via Keycloak's Identity Provider federation. The flow is PKCE-enabled and runs entirely through Keycloak — Resavi never sees the user's Google password or access token.
Role-Based Access Control
Five roles — Customer, Business Owner, Staff, Admin, Superadmin — form a composite hierarchy in Keycloak. Every service re-validates the caller's roles from the signed token; no endpoint trusts client-supplied claims.
Service-to-Service Auth
Internal calls between microservices carry a rotating shared secret validated on receipt. No internal endpoint is exposed through the public gateway — internal routes are unreachable from outside the Docker network.
CORS Allowlist
The gateway enforces a strict origin allowlist. Only resavi.com, biz.resavi.com, and dashboard.resavi.com — and their staging equivalents — may make cross-origin requests. No wildcard origins.
Payments
Payment flows designed to be tamper-proof
Resavi processes payments through established providers. Every inbound payment event is cryptographically verified before any action is taken — a tampered or unsigned webhook is rejected with no side effects.
Webhook Signature Verification
Every inbound payment webhook is verified against an HMAC-SHA256 signature before business logic runs. Unsigned or replayed payloads are rejected at the boundary — no partial state changes occur.
No Raw Card Storage
Resavi does not store card numbers, CVCs, or expiry dates. Tokenisation and card processing are handled entirely by the payment provider. Resavi stores only the transaction reference.
Idempotent Event Processing
Payment events are processed with idempotency guards using the outbox pattern. A duplicate webhook from the provider triggers no double-charge, no duplicate fulfillment, and no phantom notifications.
Data Protection
Minimal collection. Deliberate handling.
Resavi collects what is necessary to provide the service. Third-party API keys held on behalf of businesses are encrypted with AES-256 before touching a database — the raw key and the encryption passphrase are never stored together.
Encryption at Rest
Business API credentials are encrypted with AES-256 derived from a secret passphrase held outside the database. The stored row contains only ciphertext — decryption requires both the row and the externally-held key.
Isolated Notification Delivery
SMS and email are dispatched via RabbitMQ through a single dedicated notifications service. No other service calls the SMS or email provider directly, so outbound communication has a single, auditable path.
Data Minimisation
Each service owns only the data it needs to perform its function. There are no cross-service joins or shared databases — a booking service holds booking records, not user passwords or payment tokens.
Monitoring & Response
Problems surface before customers notice
Every service reports structured errors and warnings to Sentry. Abuse events — rate-limit violations, failed auth attempts — are tagged with IP, path, and method so patterns are visible without combing through raw logs.
Structured Error Tracking
Sentry captures warnings and errors across all services in real time. Each event carries the environment, service name, and request context so engineers can triage without digging through container logs.
Abuse Visibility
Every 429 Too Many Requests response is forwarded to Sentry with the source IP, endpoint, and method as searchable tags. Repeat offenders are visible as patterns, not buried in access logs.
Health Checks
Every service exposes a health endpoint. Docker and the load balancer use these to detect degraded containers and remove them from rotation before they serve broken responses to real users.
Responsible Disclosure
Found a vulnerability?
If you believe you have found a security issue in Resavi, please let us know before disclosing it publicly. We take all reports seriously and commit to acknowledging your message within 48 hours.
Please include a clear description, reproduction steps, and your assessment of the potential impact. We ask that you avoid accessing other users' data, conducting denial-of-service tests, or running automated scanners beyond what is needed to demonstrate the issue. We do not take legal action against researchers acting in good faith.
Report to
We aim to respond within 48 hours and resolve critical issues within 7 days of confirmation.