Security Best Practices
Practical guidance for integrating with AfriRoute securely. These recommendations complement the platform's own controls described in Authentication and Encryption.
🔑 Credential Hygiene
- Never hardcode API keys. Load them from environment variables or a secret manager.
- Use separate keys per environment (
$AFRIROUTE_API_KEY*for dev/staging,$AFRIROUTE_API_KEY*for production). - Scope keys to the minimum permissions required — a notification service needs
sms:send, notadmin:full. - Rotate keys every 90 days, and immediately on suspected exposure.
- Prefer short-lived JWTs for client apps over distributing long-lived keys.
// ✅ Good
const apiKey = process.env.AFRIROUTE_API_KEY;
// ❌ Bad — committed secret
const apiKey = "$AFRIROUTE_API_KEY";
🌐 Network Controls
| Control | Recommendation |
|---|---|
| HTTPS only | All calls to https://api.afriroute.ai; HTTP is rejected |
| IP allow-listing | Restrict API keys to known egress IPs (dashboard → key settings) |
| Egress firewall | Allow only AfriRoute endpoints from your backend |
| Certificate validation | Never disable TLS verification; pin on mobile if feasible |
IP allow-listing means a leaked key is unusable from an unknown network.
🚦 Rate Limiting & Idempotency
- Respect
429responses and back off using theRetry-Afterheader. - Implement client-side rate limiting to stay under your plan's quota.
- Send an
Idempotency-Keyon writes so retries don't duplicate messages or charges.
curl -X POST https://api.afriroute.ai/api/v1/sms/send \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Idempotency-Key: 5b1f-order-9931" \
-d '{ "to": "+251911111111", "from": "MyBrand", "message": "Hi" }'
🪝 Webhook Security
flowchart LR
AFR[AfriRoute] -->|HMAC-signed POST| EP[Your endpoint]
EP --> V{Verify\nsignature?}
V -->|no| REJ[401 + log]
V -->|yes| PROC[Process once]
- Verify the HMAC signature (
X-AfriRoute-Signature) on every webhook using constant-time comparison. - Reject unsigned/invalid requests with
401and log the attempt. - Deduplicate by event ID — webhooks may be delivered more than once.
- Respond fast (2xx) and process asynchronously; long handlers cause retries.
- Keep the webhook secret confidential and rotate it if exposed.
👥 Account & Access
- Enable MFA for all dashboard users; require it for admins.
- Apply least privilege with role-based access; remove access promptly on offboarding.
- Use separate logins per person — no shared accounts.
- Review your tenant audit trail regularly for anomalous activity.
🧱 Input & Data Handling
- Validate and normalize phone numbers (E.164) before sending to reduce cost and abuse.
- Don't log message bodies, OTP codes, or PII on your side without redaction.
- Sanitize any user-generated content placed into messages to avoid injection into downstream systems.
- Treat delivery webhooks as the source of truth for status; store
message_ids for reconciliation.
🛡️ Protecting Against Common Abuse
| Threat | Mitigation |
|---|---|
| Leaked API key | Scope + IP allow-list + rotation + revocation |
| OTP pumping / SMS fraud | Velocity limits, per-number caps, geo rules |
| Webhook spoofing | HMAC verification |
| Replay attacks | Idempotency keys + event-ID dedup |
| Credential stuffing (dashboard) | MFA + lockout + monitoring |
✅ Pre-Production Checklist
- Secrets loaded from env/secret manager, none in source control
- Production keys scoped + IP allow-listed
- Webhook signature verification implemented and tested
-
429/Retry-Afterhandling and idempotency keys in place - MFA enabled for all dashboard users
- Logging redacts PII and sensitive content
- Key rotation reminder scheduled (≤ 90 days)
📞 Reporting a Vulnerability
Report security issues to [email protected]. For active incidents affecting your account, contact [email protected]. Responsible disclosure is welcomed and acknowledged.
📚 Related Documentation
Last Updated: May 2026