Tenant isolation in a serverless SaaS
PayTrack Africa keeps many small businesses apart in one backend. Here is how isolation works when there is no cluster to hide behind.
PayTrack Africa is a multitenant invoicing product for Ghanaian SMEs. Every business shares the same serverless backend, which raises the question that matters more than any feature: how does one account ever see another account's invoices? In a container world you might answer that with a database per tenant. Serverless removes that option, so isolation has to be built into the data and the identity layer instead.
Identity carries the tenant
Cognito issues every user a token, and the tenant identifier travels inside that token. The API never trusts a tenant id that arrives in a request body. It reads the tenant from the verified token and scopes every operation to it. That single rule removes a whole class of bugs: a caller cannot ask for data outside the tenant they authenticated as, because there is no field to tamper with.
Partition keys do the rest
In DynamoDB, the tenant identifier is part of the partition key on every table. Reads are always scoped by tenant by construction, and there is no query shape that spans tenants by accident. The cost of a query is also predictable, which matters when the whole point is to run cheaply for a lot of small accounts.
Idle should be free
The economic bet behind the product is that most tenants are doing nothing most of the time. That only works if doing nothing is free. Lambda scales to zero, DynamoDB bills per request, and there is no always-on identity server to pay for. The infrastructure figure tracks usage instead of headcount.
Collections, without the awkward part
Chasing an unpaid invoice is the task owners put off. The Gemini API drafts a reminder from the invoice context and the customer's history, and the owner reviews it before it goes out. The draft is what saves the time; the review is what keeps it honest. Automating the send without that step would have traded a small chore for a real risk.
- Tenant id always comes from the token, never from the payload.
- Partition keys are tenant-scoped so cross-tenant reads are not expressible.
- If idle is not free, the unit economics of the product do not work.