All data encrypted in transit
Every byte transferred between a user's device and Rxkhoj servers is encrypted using industry-standard TLS. There is no unencrypted HTTP fallback — all plain HTTP requests are permanently redirected to HTTPS.
No passwords. OTP-only patient login.
Rxkhoj patients authenticate exclusively via mobile OTP — there are no passwords to steal, reuse, or phish. Pharmacy staff log in with email + password where bcrypt is applied before any storage occurs.
Patient enters mobile number
The app sends the mobile number to the backend over HTTPS. No password is ever requested or stored.
Cryptographically secure OTP generated
A 6-digit OTP is generated using secrets.choice() — Python's CSPRNG — not the predictable random module. The OTP is stored in Redis with a 10-minute TTL.
OTP delivered via transactional SMS
Delivered through a DLT-registered OTP route (not promotional) ensuring reliable transactional delivery. The OTP is never logged on our servers.
Constant-time OTP comparison
OTP verification uses secrets.compare_digest() — a timing-safe comparison that prevents timing-oracle attacks where an attacker could infer character correctness from response latency.
OTP deleted after successful verification
Once verified, the OTP is immediately deleted from Redis. It cannot be replayed. Failed attempts are rate-limited and counted against a maximum attempt ceiling.
Pharmacy Staff Passwords
Short-lived JWT with rotating refresh tokens
After authentication, Rxkhoj issues a pair of tokens: a short-lived access token and a longer-lived refresh token. This architecture limits the blast radius of any compromised token.
| Token | Lifetime | Storage | Purpose |
|---|---|---|---|
| Access Token (JWT) | 15 minutes | Memory (app state) | Authorise every API request via Authorization: Bearer header |
| Refresh Token | 7 days | AsyncStorage (mobile) / httpOnly-equivalent (web) | Obtain a new access token without re-authentication |
Minimal data. Maximum protection.
Rxkhoj is designed on the principle of data minimisation — we collect only what the product absolutely requires and nothing more. Sensitive fields receive additional protection.
What Each Role Can See
| Data Field | Patient Sees | Pharmacy Sees | Admin Sees |
|---|---|---|---|
| Patient mobile number | ✓ Own only | Only after patient confirms an offer | ✓ (operational) |
| Patient full name | ✓ Own only | ✗ Never | ✗ Not collected |
| Patient exact location | ✓ Own requests | Approximate distance only (e.g., "1.2 km away") | ✗ Aggregated only |
| Medicine request details | ✓ Own requests | ✓ All in service area | ✓ Aggregated reports |
| Pharmacy contact details | Only after confirming offer | ✓ Own profile | ✓ (operational) |
| Other patients' data | ✗ Never | ✗ Never | Anonymised only |
Multi-layered API defence
Every API endpoint in Rxkhoj is protected by multiple independent layers of validation, authorisation, and injection prevention.
Retry-After header.Hardened server environment
Rxkhoj runs on a dedicated VPS with a hardened configuration. Access to the production server is strictly controlled and logged.
Privacy baked in, not bolted on
Security and privacy at Rxkhoj are architectural decisions, not afterthoughts. Every system design choice was made with privacy in mind.
getLastKnownPositionAsync() which avoids waking the GPS radio unnecessarily — fast, battery-efficient, and privacy-respecting. Location is never tracked in the background.Authenticated real-time connections
Rxkhoj uses WebSockets to push real-time notifications to both patients (when a pharmacy responds) and pharmacies (when a new request arrives). These connections are authenticated and isolated per user.
Zero PII in server logs
Server logs are essential for debugging but are a common source of accidental data exposure. Rxkhoj's logging is designed to capture operational events without recording any personally identifiable information.
| Data Type | Logged? | If Yes, What Exactly |
|---|---|---|
| Mobile phone numbers | ✗ Never | Last 4 digits only (for correlation in support cases) |
| OTP codes | ✗ Never | — |
| JWT tokens | ✗ Never | — |
| GPS coordinates | ✗ Never | — |
| Passwords / hashes | ✗ Never | — |
| API request events | ✓ Yes | HTTP method, path, status code, duration — no body content |
| Error events | ✓ Yes | Exception type, stack trace — no user data in trace |
| SMS delivery | ✓ Yes | Provider name + last 4 digits of mobile only |
Found a vulnerability? Tell us first.
We take security seriously and genuinely appreciate researchers and users who help us improve. If you've found a potential security issue, please follow responsible disclosure and give us a chance to fix it before making it public.
Please do not publicly disclose potential vulnerabilities before we've had a chance to address them. We promise to act swiftly and transparently.