Authentication
How AfriRoute authenticates and authorizes every request to the platform. This page covers the security model behind API keys, JWTs, and service-to-service auth. For integration code samples, see the developer authentication guide.
🔐 Authentication Model
AfriRoute enforces authentication at the API Gateway before any request reaches a service. Three credential types exist, each for a different actor:
| Credential | Actor | Transport |
|---|---|---|
| API Key | Server-to-server integrations | Authorization header |
| JWT (access token) | End-user / SPA / mobile | Authorization: Bearer |
| mTLS client cert | Internal services | gRPC mutual TLS |
🗝️ API Keys
- Keys are shown once at creation and stored only as a salted hash (Argon2id) — AfriRoute cannot recover a lost key.
- Format encodes environment and a non-secret prefix used for fast lookup:
$AFRIROUTE_API_KEY<prefix>_<secret>. - Each key carries scopes (e.g.
sms:send,billing:read) enforced per request. - Keys support expiry and immediate revocation (propagated via the Redis revocation list).
flowchart LR
REQ[Request + Authorization] --> GW[Gateway]
GW --> H[Hash + prefix lookup]
H --> CHK{Valid?\nNot revoked?\nNot expired?}
CHK -->|no| R401[401 Unauthorized]
CHK -->|yes| SC{Scope allows route?}
SC -->|no| R403[403 Forbidden]
SC -->|yes| FWD[Forward to service]
🪪 JWT Authentication
JWTs are issued by the Auth Service after login and are used by browser/mobile clients.
- Algorithm: RS256 (asymmetric) — services verify with the public key; only Auth holds the private key.
- Claims:
sub(user),tenant,scopes,iat,exp. - Access token TTL: 1 hour. Refresh token TTL: 30 days, rotated on use.
- Revocation: token IDs (
jti) can be denylisted in Redis for immediate invalidation.
Clock skew tolerance is 60 seconds; expired or future-dated tokens are rejected.
🤝 Service-to-Service Authentication
Internal gRPC calls require mutual TLS — both caller and callee present certificates issued by the internal CA and rotated automatically by the service mesh. There are no shared internal API keys. Each call also carries the propagated tenant_id so downstream services re-verify tenant scope (defense in depth).
🧱 Multi-Tenant Authorization
Authentication establishes who; authorization establishes what they may touch:
- The gateway resolves
tenant_idfrom the credential. - Scopes/roles gate the action (
sms:send,admin:full, …). - PostgreSQL row-level security gates the data — even a bug in service code cannot read another tenant's rows.
This layered model means a single missed check does not become a cross-tenant breach.
🔁 Webhook Authentication
Outbound webhooks are signed with HMAC-SHA256 over the raw body, sent in X-AfriRoute-Signature. Integrators must verify the signature using their webhook secret and constant-time comparison. A replayed or tampered payload fails verification. See the developer guide for sample code.
🛡️ Brute-Force & Abuse Controls
- Failed auth attempts are rate-limited per IP and per credential.
- Repeated failures trigger temporary lockout and a security audit event.
- Login supports optional MFA (TOTP) for dashboard users; required for admin roles.
- All auth events (success, failure, revocation) are written to the tenant audit trail for review and compliance.
✅ Recommendations
- Use API keys for backend, JWTs for clients — never embed a live API key in a mobile or browser app.
- Scope keys to the minimum permissions needed.
- Rotate keys every 90 days and immediately on suspected compromise.
- Store secrets in a vault/secret manager, never in source control.
📚 Related Documentation
Last Updated: May 2026