A SaaS with one tenant per customer
TeselaDB
TeselaDB team
30 minAdvanced
Put each customer in its own tenant of the same cluster, with its users and its databases, without any of them seeing the others.
A SaaS with many small customers does not need a cluster per customer, because in TeselaDB each customer can be a tenant of the same cluster. Each user belongs to one tenant. Authentication sets the tenant of the connection from its user and authorization keeps it out of another tenant's databases.
What you will build
Two tenants, acme and globex, each with a user for its application and its own shop database. Both use the same
database name and each application only sees the databases of its tenant.
Requirements
- A TeselaDB cluster with users and access to
teseladb admin. - A tenant 0 user allowed to create users, such as
root.
1. Create the tenants
teseladb admin --node node-01:27200 tenant create acme
teseladb admin --node node-01:27200 tenant create globex2. Create a user in each tenant
From a tenant 0 connection, the $tenant argument makes the command work in another tenant. The user name is unique
across the cluster, so each tenant has its own:
for (const tenant of ["acme", "globex"]) {
db.getSiblingDB("admin").runCommand({
createUser: `${tenant}-api`,
pwd: passwordPrompt(),
roles: [{ role: "readWrite", db: "shop" }],
$tenant: tenant,
});
}3. Connect each application with its user
Each customer's application uses the string with its user. The tenant comes from authentication:
export TESELADB_URI="mongodb://acme-api:<password>@node-01:27017,node-02:27017/shop?tls=true&tlsCAFile=./ca.pem"Try it
Connected as acme-api with the string of step 3, write an order in the orders collection of shop and then list the
databases of the cluster to see which ones the application of acme can reach:
db.orders.insertOne({ customer: "Ana", total: 30 });
db.adminCommand({ listDatabases: 1, nameOnly: true });listDatabases shows only shop, the one of acme. Connected as globex-api, the orders collection of its shop
database is empty, and on the cluster it only has listDatabases, bypassDefaultMaxTimeMS and useUUID.
Clean up
Drop the databases and the users of each tenant from tenant 0 and then the tenants. tenant drop fails while the
tenant still has databases or users:
teseladb admin --node node-01:27200 tenant drop acme
teseladb admin --node node-01:27200 tenant drop globexNext steps
- Several tenants in one cluster, with the steps for a single tenant.
- Users and roles, to give each user only what it needs.