SoXara
Security

13 rules. No exceptions.

Money is boring on purpose. These are the constraints every line of code is held to — not aspirations, not guidelines, not ideals. Hard stops.

01auth.users · no password_hash

No password column

Identity is your phone number. Session is OTP or biometric. Authorization is your PIN. No password_hash column exists — there is no password to steal, reset, or compromise.

Password-based auth is the single largest source of account takeovers. We eliminated it entirely. You authenticate with a one-time code to your registered number, then authorize sensitive actions with a PIN. Biometric unlock replaces both on mobile.

02card.* · PCI-handled by issuer

Card details never touch us

Raw card numbers, CVVs, and full PANs are tokenised by our card issuer before we ever see them. We store only the last four digits and a Stripe-issued token.

We operate under Stripe's PCI-DSS Level 1 umbrella. Raw PANs never traverse our network. If our database were fully exfiltrated, no complete card number would be recoverable.

03BEGIN; debit; credit; COMMIT;

Atomic ledger — every time

Every wallet debit and credit sits inside a single database transaction. There is no code path where money leaves one wallet without arriving in another. The ledger is always balanced.

We use PostgreSQL serialisable isolation on all balance mutations. If the transaction fails for any reason — network drop, application crash, database timeout — it rolls back entirely. Partial transfers are impossible by construction.

04Idempotency-Key: SX-T9K2-MQ04

Idempotent payments

Every payment path is keyed on a client-supplied reference. Replaying an identical request returns the original result — no double-charge, no double-credit, regardless of retries.

Mobile networks drop connections. Users tap twice. Our idempotency layer stores the outcome of every payment operation keyed by the reference. Duplicate requests are deduplicated at the gateway before they reach the ledger.

05HMAC-SHA256 · constant-time compare

Signed webhooks at the edge

Inbound webhooks from card networks, mobile money providers, and messaging platforms are HMAC-SHA256 verified at the gateway before they reach any service. Unsigned or tampered payloads never enter the system.

We use constant-time comparison to prevent timing attacks. Each provider has a dedicated signing secret, rotated on schedule. Any payload that fails verification is rejected with no processing and no state change.

06kyc.events · auto-provision · reason_code

KYC you can explain

Liberian national ID and passport reads go through an explainable AI pipeline. Every approval is a documented decision with a confidence score and a reason code. There is no black box.

Our KYC pipeline surfaces the specific fields it evaluated and the rules it applied. A declined application includes the reason in plain language. Manual review queues are available. No AI decision is irreversible.

07WhatsApp Flows · PIN · secure-link only

No SMS OTP on WhatsApp

The WhatsApp channel uses WhatsApp Flows for PIN entry and confirmation prompts — never SMS OTP. SMS-based auth on a messaging channel is a phishing vector. We don't open it.

WhatsApp Flows are end-to-end encrypted forms that live inside the conversation. The user never leaves WhatsApp to enter a sensitive value. SIM-swap attacks that intercept SMS cannot affect a session that never used SMS.

08service-A → API → service-B · no cross-DB

Microservice data isolation

Services do not directly query other services' databases. Each service owns its data. Inter-service communication goes through defined API contracts — never raw SQL across a network boundary.

This eliminates lateral-movement attacks where a compromised service escalates by querying other databases. It also enforces schema ownership: the identity service is the sole authority on user records.

09429 · Retry-After · no exemptions

Rate limiting without exceptions

Every payment endpoint is rate-limited. Every authentication endpoint is rate-limited. No bypass headers, no internal IPs that skip the check, no admin paths that are exempt.

Credential-stuffing and payment-fuzzing attacks depend on volume. We apply sliding-window rate limits at the gateway and at the service layer. Exceeding the limit returns 429 with a Retry-After header — not a silent discard.

10process.env · no git secrets

Secrets via environment only

No hardcoded credentials, keys, or tokens anywhere in the codebase. All secrets are injected at runtime via environment variables. The repository contains no live keys — not even in git history.

We run automated secret scanning on every commit. Any file pattern matching a known key format fails the build. AWS, Stripe, and Twilio credentials rotate on schedule.

11zod · schema-first · 422 on fail

Input validation at every boundary

Every API endpoint validates input before processing begins. Validation happens at the schema level, not in business logic. Malformed requests are rejected before they can affect state.

We use Zod schemas at all service entry points. Requests that fail schema validation return 422 with a structured error before any business logic executes. There is no 'validate later' path.

12logs: event + trace_id · no PII · no amounts

No sensitive data in logs

Wallet balances, transaction amounts, phone numbers, OTPs, PINs, and ID data are never written to logs. Structured logging includes correlation IDs and event types — not personal financial data.

Log aggregation is a common exfiltration path. We apply log scrubbing middleware at every service boundary. Fields matching PII patterns are replaced with a redacted marker before writing to any log sink.

13CI · no merge without payment test

Payment flows are always tested

No payment flow ships without tests. Every debit, credit, payout, and refund path has an integration test that runs against a real test-mode environment. Untested payment code does not merge.

Our CI runs payment flow tests against a live test-mode Stripe environment and a local Postgres instance that mirrors production schema. The pipeline blocks merges that remove payment test coverage.

Transparency

Questions about our security posture?

We're open to responsible disclosure, compliance questions, and security partnerships.