Tenants
0-day streakReview

Your progress

Level 1

0 XP100 XP to level 2
0day streak
0best streak
0topics started
0cards reviewed
    Review cards

    Progress is stored only in this browser. No account is required.

    Layer 4 · Full breakdown · 18 min · 5 figures

    What is a tenant?

    The customer boundary in a SaaS product: tenant versus user, account, organisation and workspace; B2B, B2C and B2B2C mappings; tenant context from a signed token to every row and log line; the tenant lifecycle; and the cross-tenant bugs interviewers probe.

    A tenant is the customer boundary in a SaaS product: a group of users, usually one organisation, that shares your product while getting its own data, configuration, plan, limits and bill. Users log in; tenants sign contracts. Almost every later decision in a multi-tenant system hangs off this one entity, so define it precisely before you draw a single box.

    Picture it first: a co-working building

    Think of a co-working building in Bengaluru. The building company runs the lifts, power, security desk and front office. Each company that leases space, say a 12-person fintech start-up, is a tenant: it gets a lockable suite, access cards for its people, its own rules for booking rooms, a plan (hot desks or a cabin), limits (at most 20 cards) and its own monthly invoice.

    People are not tenants. A freelance chartered accountant carries cards for three client companies, and her card opens different doors in each. The security desk decides which suite you may enter from the card it issued, not from what you say at the desk. And when a company moves out, it gets time to pack before the suite is cleared and the locks are reset.

    Map it back. The building is your SaaS product and the building company is you, the provider, with a shared control plane. A suite is a tenant’s data and configuration, an access card is a signed token naming the tenant, one card per company is a membership with a role, and the security desk is your API gateway. The lease is the plan and its limits, and moving out is offboarding.

    Tenant, user, account, organisation, workspace

    Five words get used loosely in SaaS. Pin them down, because the bugs come from mixing them up.

    Tenant. The unit you isolate, configure, entitle and bill. AWS’s SaaS guidance is plain: tenants are not individual users, and a tenant is likely associated with many users. Sign-up creates the tenant and its first admin, who invites everyone else.

    User. An identity that authenticates: a person, or a machine such as a CI bot. The login lives in an identity provider, yours or the customer’s via single sign-on, independent of any tenant. GitHub makes the split explicit: people sign in to user accounts, nobody can sign in to an organisation, and one user can belong to many organisations.

    Membership. The link (user, tenant, role), and the entity people forget. Priya can be an admin in one tenant and a read-only guest in another only if the role sits on the membership, not on the user.

    Organisation. The real-world company. Usually it is one tenant, but Azure’s guidance lists reasons for several: divisions with different requirements, a presence in several countries, or separate development and production instances.

    Workspace or project. A container inside a tenant: channels, boards, repositories. Whether it is a tenant depends on the product. A Slack workspace on a smaller plan stands alone; on Slack’s Enterprise plans, workspaces are migrated into one Enterprise organisation that holds org-wide settings and requires single sign-on.

    Account. The most overloaded word: a login, a billing customer or a cloud account. Say which you mean.

    Three users and two tenants. Each line is a membership carrying a role; Priya, a freelance chartered accountant, belongs to both tenants.Notice Priya has one login but two memberships: she is an admin in Bharat Traders and can only view Acme’s Finance workspace.

    Tenants also form hierarchies. GitHub’s enterprise accounts manage policy and billing for several organisations, while each organisation keeps its own repositories and members, so the isolation boundary and the billing boundary sit at different levels of one tree. Partners add another axis: a CA firm keeping the books of 40 small businesses in a Zoho-style accounting SaaS needs one login that reaches 40 tenants, while the 40 sets of books never mix. Model that with memberships and a parent_tenant_id, never by merging tenants.

    What it is Who creates or owns it What is scoped to it Typical cardinality
    Tenant The customer boundary you isolate, configure, entitle and bill Created at sign-up; run by the customer’s tenant admins Data, settings, plan, limits, keys, region, invoices, audit log One per customer contract; many users each
    User An identity that authenticates: a person or a machine Your identity provider, or the customer’s via SSO Credentials, MFA, profile Belongs to zero, one or many tenants
    Membership The link (user, tenant, role) A tenant admin’s invite, or SSO provisioning The role and permissions inside that tenant One per user per tenant
    Account An overloaded word: a login, or a billing customer Depends on the product Say which you mean Varies
    Organisation The real-world company or group Exists outside your system The contract, legal name, its own identity provider Usually one tenant; sometimes several
    Workspace or project A container inside a tenant Tenant admins or members Channels, boards, repositories, finer roles Many per tenant
    The five words, plus the membership that ties them together.

    Same word, different meaning

    Vendors use these words for their own products too. In Auth0’s documentation, your tenant is your own Auth0 instance, and your B2B customers are Organizations inside it. Map a vendor’s terms onto yours before you design anything.

    B2B, B2C and B2B2C

    Who your tenant is depends on who pays and who shares data.

    B2B. The tenant is the customer organisation; users are its employees plus invited guests. This is the clean case the rest of the module assumes.

    B2C. Azure’s guidance notes that each consumer might be a tenant, but families, clubs or friends may need to manage data together, so a music service might treat individual and family plans as different shapes of tenant. Many consumer apps have no tenant at all and key every row by user, which bites later: a family or team plan then means inserting a tenant above the user and re-keying every shared table while the app stays live.

    B2B2C. Your tenant serves its own customers: a store builder whose merchants sell to shoppers, a school ERP whose parents log in, a clinic platform whose patients book appointments. The tenant now has two user pools, staff and end customers, both inside its boundary. Decide early whether an end customer’s login is per tenant (simpler, nothing to leak) or shared across tenants (one login across many stores, but a cross-tenant identity to guard).

    How tenants map to people in B2B, B2C and B2B2C products. Teal boxes are tenants; blue boxes and grey dots are their users.Notice In B2B2C the tenant has two user pools, its own staff and its own customers, and both must stay inside its boundary.

    Model a tenant even when you don’t need one

    In a pure consumer app, still create an account entity and give each new user a “tenant of one”. It costs one table and one join today, and turns the future family or team plan into a feature instead of a migration.

    Single-tenant and multi-tenant

    Single-tenant means a deployment serves one tenant; multi-tenant means one deployment serves many, and the application tells them apart.

    AWS’s SaaS guidance avoids the first term: a stack per tenant is still multi-tenant SaaS if every stack shares onboarding, identity, billing and one release, so it calls dedicated parts silo and shared parts pool. Azure separates tenants (logical customers) from deployments (physical copies of the stack), with a mapping table so a tenant can move. How much each tenant shares is the next lesson, tenancy models: silo, pool and bridge; this one is about the tenant itself, which exists under any model.

    What hangs off a tenant

    The tenant is the unit of almost every cross-cutting concern. The control plane keeps a tenant record in a catalog, like this:

    tenant_id: 0b6f2c1e-8d4a-4f7e-9b3a-5c2d7e1f9a40  # immutable and opaque: the only key
    slug: acme-retail                # mutable label: acme-retail.example.com
    display_name: Acme Retail Pvt Ltd
    status: active                   # provisioning | trial | active | suspended | offboarding | deleted
    plan: business                   # drives entitlements and feature flags
    limits: { seats: 50, api_calls_per_min: 600, storage_gb: 200 }
    home_region: ap-south-1          # data residency
    deployment: stamp-07             # which copy of the stack holds its data
    kms_key: tenants/acme-retail     # its own encryption key
    sso: saml/acme-okta              # its identity provider, if it brings one
    parent_tenant_id: null           # set for enterprise or partner hierarchies

    Each field drives a concern scoped per tenant:

    • Isolation: its data is reachable only inside its boundary (multi-tenancy and isolation, multi-tenant data).
    • Configuration and feature flags: branding, SSO, workflow rules, and flags evaluated per tenant, so a feature can reach five friendly tenants first (feature flags).
    • Entitlements: the plan decides which features are on. Resolve them once from the tenant record, not with if plan == "pro" scattered through the code.
    • Limits and quotas: seats, API calls per minute and storage, so one tenant cannot starve the rest (noisy neighbours and fairness, rate limiting).
    • Billing and metering: tenant-tagged usage events roll up into its invoice (metering and usage-based billing).
    • Data residency and keys: the home region bounds where data and backups live, and a key per tenant lets you revoke or destroy one tenant’s data alone (encryption and key management).
    • Backup, restore, export and deletion: all per-tenant requests, and painful if data isn’t tagged.
    • Observability and support: per-tenant error rates and latency answer “is it just us?” (observability); tickets, SLAs and staff access are scoped to one tenant.

    Tenant context: from token to row

    Tenant context answers “which tenant is this request for?” and travels with the request from the edge to the database. AWS calls the binding of a user to a tenant the SaaS identity: after authentication you know who the user is and which tenant they act in, because the identity provider puts tenant claims into the token.

    1. Sign in. The user authenticates (OAuth 2.0 and OpenID Connect); a user with several tenants picks one, and the token is issued for it. Auth0’s Organizations feature, for example, adds an org_id claim to ID and access tokens.
    2. Verify at the edge. The API gateway checks signature, expiry, issuer and audience (tokens and JWTs), reads the tenant claim, and checks status and plan in a cached copy of the catalog. Client-sent tenant IDs are stripped, and a subdomain naming a different tenant gets a 403.
    3. Carry it inward. Services read the tenant from a request-scoped context, filled from the forwarded token or a header only the gateway can set. AWS’s SaaS Lens makes the performance point: with 100 microservices, each should apply tenant context from the token without a round trip to another service.
    4. Stamp everything. Everything the request writes or emits carries the tenant ID, and workers restore context from the message.
    Tenant context for one request. The gateway takes the tenant from the verified token, and everything the request touches carries the same ID, including the message a background worker picks up later.Notice The X-Tenant-Id header the client sent is stripped at the gateway: only the signed claim decides the tenant.

    In code, the edge of every service does something like this:

    function tenantContext(req: Request): TenantContext {
      const claims = verifyJwt(req.headers.authorization); // signature, expiry, issuer, audience
      const tenantId = claims.tid;                         // from the token, never from the request
      delete req.headers["x-tenant-id"];                   // a client-sent tenant never travels inward
      const tenant = tenantCatalog.getCached(tenantId);    // status, plan, region, limits
      if (!tenant || tenant.status === "deleted") throw forbidden("unknown tenant");
      const hint = subdomainOf(req.host);                  // which tenant the user meant to open
      if (hint && hint !== tenant.slug) throw forbidden("tenant mismatch"); // 403, and log it
      if (tenant.status === "suspended" && req.method !== "GET") throw suspended();
      return { tenantId, userId: claims.sub, roles: claims.roles, plan: tenant.plan };
    }

    Hints are not identity

    A subdomain, path or X-Tenant-Id header says which tenant a user wants; only the signed token says which tenant they may use. If a hint names a different tenant from the claim, return 403 and log it. Auth0’s API guidance agrees: validate org_id against organisations you know, and segment data access by it.

    The “tenant ID everywhere” rule

    • Rows and objects: a tenant_id column on every shared table, and a tenant prefix on every object path.
    • Cache keys: t_7f3a:cart:u_91, never cart:u_91 (distributed caching).
    • Messages: the tenant ID in the envelope of every queue message and event.
    • Logs and traces: a structured tenant field on every line and span.
    • Metrics, carefully: one counter labelled with 10,000 tenants × 30 endpoints × 5 status classes is 1.5 million time series. Label metrics by tier, give the largest tenants their own series, and keep full tenant IDs in logs, traces and metering events.

    Put this in shared libraries (a logger, cache client, database session and producer that add the tenant) so nobody has to remember.

    IDs, names and subdomains

    A tenant carries three identifiers, and only one is safe as a key: the tenant ID (opaque, immutable, generated by you, never reused), the slug or subdomain (acme-retail.example.com, mutable) and the display name (it changes with a rebrand). Never key data by the subdomain:

    • Renames. With an immutable ID, a rebrand is one catalog update and a redirect; with the name as the key, it is a migration of every table and object path.
    • Reuse. Subdomains are first-come and freed when a tenant leaves. Azure’s domain-name guidance walks through the attack: Fabrikam offboards but leaves a DNS record pointing at its old subdomain, an attacker signs up a new tenant named fabrikam, and inherits traffic meant for Fabrikam. Anything still keyed by the name now resolves to the newcomer.
    • Guessability. OWASP’s first example of its top API risk is a hosted e-commerce platform where swapping the shop name in /shops/{shopName}/revenue_data.json exposed the sales data of thousands of stores. OWASP recommends random, unpredictable IDs: no substitute for authorisation, but an end to trivial enumeration.

    Auth0 likewise prefers organisation IDs to names when validating tokens, and Azure’s identity guidance says to store user-to-tenant mappings against immutable identifiers. Store it compactly: a UUID is 128 bits, so 16 bytes in a native UUID column against 36 characters as text (32 hex digits and 4 hyphens). Over 1 billion rows that is 20 bytes × 1 billion ≈ 20 GB saved per copy, before indexes repeat it.

    The tenant lifecycle

    Every transition between these states is a workflow with side effects.

    A tenant lifecycle as a state machine. Each arrow is a control-plane workflow triggered by the customer, the billing system or a timer; the 30-day grace period is an example policy.Notice Suspension keeps the data and is reversible, while deletion comes only after an export window.

    Provisioning. Onboarding creates the tenant record, the first admin and membership, default roles and settings, the plan’s limits, a key and, for siloed tiers, infrastructure; AWS describes it as an orchestrator over the other core services. Steps can fail halfway, so make each idempotent and the flow resumable (multi-step workflows). The gateway rejects the tenant’s requests until provisioning completes.

    Trial. Azure lists the questions: shared infrastructure, service levels, caps, and how trial data carries over. The simple answer is an ordinary tenant on a trial plan, so buying is a plan change, not a migration.

    Plan changes. Upgrades and downgrades update entitlements and limits at once; some also move the tenant to dedicated infrastructure, as the tenancy models lesson describes. On a downgrade, make data over the new limit read-only, not deleted.

    Suspended. Payment fails or abuse is detected. Azure separates this temporary deactivation from offboarding: data is kept, logins become read-only or blocked, jobs and webhooks pause, and paying again reactivates the tenant in seconds.

    Offboarding. The customer cancels or a suspension runs out. Open an export window, then delete from every store: database, object storage, search indexes, caches, analytics copies, and logs as far as policy says. Backups are rarely rewritten, so the data disappears as they age out, or at once if you destroy the tenant’s own key. Azure asks you to set the retention period, including any legal minimum or maximum, and whether the tenant can return within it. Release the subdomain only after a cooling-off period.

    Merge and split. Acquisitions and divestments are far easier when the tenant is an ID, not part of names and paths.

    These are slow, multi-step, audited workflows across billing, identity and infrastructure, so the control plane owns them; the data plane only reads the tenant’s current status from a cache.

    Going deeper: how tenant boundaries leak

    Most cross-tenant leaks come from a few habits, and interviewers probe each.

    The same request against two versions of an invoices API. On the left, the tenant comes from a header the caller controls; on the right, from the signed token, and the query is scoped by it.Notice The attack on the left needs no stolen credentials: a valid login in tenant B and one edited header are enough.

    Tenant from user input. The API takes the tenant from a header, path or body, or fetches an object by ID without checking its owner. That is Broken Object Level Authorization, first in OWASP’s 2023 API Top 10, applied across tenants; OWASP adds that comparing the token’s user ID with an ID in the request covers only a small subset of cases. Fix it in three layers: the tenant comes from the verified token, every query is scoped by it (WHERE tenant_id = ? AND id = ?), and row-level security in the database is the backstop. Add tests that log in as tenant B, try to read tenant A’s objects, and fail the build if any succeed.

    User treated as tenant. Data keyed by user_id leaves with the employee who created it, and roles stored on the user leak: Priya, an admin at Bharat Traders, becomes an admin at Acme too. Key data by tenant, and keep roles and tenant-specific profile fields on the membership; Azure warns that what tenant A adds to a shared user’s profile must not show up for tenant B.

    Admin access that bypasses tenant checks. An internal console running as a superuser is one bug away from showing everyone’s data. AWS separates the provider’s admin users from tenant users. Give staff their own identities and let them impersonate one tenant at a time: time-boxed, tied to a ticket, ideally customer-approved, and written to that tenant’s audit log.

    Background jobs that lose context. A message with no tenant ID, a nightly “all tenants” query on a privileged connection, or a worker that keeps the last job’s tenant on a reused thread. Stamp every envelope, fan “all tenants” jobs out into one job per tenant, and set and clear the context per job, scoped to the transaction rather than the connection.

    Caches keyed without the tenant. If invoice IDs are per-tenant sequences, invoice:1042 exists in many tenants, and whoever fills the cache first wins. A CDN that caches a tenant’s page under a tenant-free URL fails the same way. Prefix keys in the cache client and mark per-tenant responses private.

    Analytics across tenants. Internal cross-tenant dashboards are normal, but customer-facing reports must filter by tenant, benchmarks against “similar businesses” need aggregation and contractual permission, and residency rules cover the warehouse too.

    In the interview

    Name the layers in one breath: “The tenant comes from the signed token, checked against the membership at the gateway. Every query, cache key and message is scoped by it, and row-level security is the backstop, so one missing WHERE clause isn’t a breach.”

    Cheat sheet

    Term Remember it as
    Tenant The customer boundary: data, config, plan, limits, keys, region, bill
    User An identity that logs in; can belong to many tenants
    Membership (user, tenant, role); roles live here, not on the user
    Organisation The real company; usually one tenant, sometimes several
    B2C A tenant of one, a household, or none; still model an account
    B2B2C The tenant’s own customers live inside its boundary
    Tenant context From the signed token claim, never from a header, path or body
    Tenant ID everywhere Rows, object keys, cache keys, messages, logs, traces, meters
    Identifiers Opaque immutable ID as the key; slug and name are labels
    Lifecycle Provisioning, trial, active, suspended, offboarding, deleted; the control plane owns it
    Biggest bug Tenant from user input, giving a cross-tenant read (BOLA)

    How to say it in the interview

    “A tenant is the customer boundary: usually a company, with its own data, settings, plan, limits and bill, and many users. Memberships link users to tenants with a role, so a consultant can reach five tenants with one login. At sign-in the token gets a tenant claim; the gateway verifies it, ignores any tenant in the request, and sets the request context. Every row, cache key, message, log line and usage event then carries an immutable tenant ID, never the subdomain, and row-level security enforces it again in the database. The control plane owns the lifecycle, from onboarding to offboarding.”

    Can one user belong to several tenants? Yes, through a membership table that holds the role. A token is issued for one tenant at a time, and switching tenants means a new token, so a request is never ambiguous.

    Why not identify the tenant by subdomain? It can be renamed, or reclaimed after a tenant leaves. Use it to choose which tenant to sign in to, check it matches the token’s claim, and store everything under the immutable ID.

    How does a background job know its tenant? From the tenant ID in the triggering message’s envelope. The worker sets the context before doing anything and clears it afterwards; an “every tenant” job fans out into one job per tenant.

    What happens when a tenant stops paying? Suspension, not deletion: data kept, logins read-only or blocked, jobs paused, instant reactivation on payment. After a grace period comes offboarding: an export window, deletion everywhere, and backups that age out or become unreadable once its key is destroyed.

    Does a consumer app need tenants? It can treat each user as a tenant of one. I’d still create an account entity on day one, because adding family or team plans later otherwise means re-keying every table.

    Where to go next

    References and further reading

    1. Azure Architecture Center: Tenancy models for a multitenant solutionlearn.microsoft.com“Define a tenant”: B2B tenants map to customer organisations (sometimes several per customer), B2C tenants may be people or families, and tenants are distinct from deployments.
    2. Azure Architecture Center: Tenant life cycle considerations in a multitenant solutionlearn.microsoft.comTrials, onboarding questions, deactivation versus offboarding, retention periods, re-onboarding, and merging or splitting tenants.
    3. Azure Architecture Center: Architectural considerations for identity in a multitenant solutionlearn.microsoft.comA tenant ID claim in the token, users who belong to several tenants and switch between them, immutable IDs for user-to-tenant mappings, and profile data leaking across tenants.
    4. Azure Architecture Center: Considerations for domain names in a multitenant solutionlearn.microsoft.comPer-tenant subdomains in a first-come namespace, and the dangling-DNS takeover that follows when an offboarded tenant’s name is claimed by someone else.
    5. AWS Well-Architected SaaS Lens: Identity and access management (SaaS SEC 1)docs.aws.amazon.comSaaS identity binds each user to a tenant; tenant claims in the JWT let 100 microservices apply tenant context without a round trip to another service.
    6. AWS SaaS Architecture Fundamentals: Core servicesdocs.aws.amazon.comTenants are not users; a tenant service holds tenant policies, attributes and state; onboarding orchestrates users, tenant, policies and resources; provider admins are separate from tenant users.
    7. OWASP API Security Top 10 (2023): API1 Broken Object Level Authorizationowasp.orgThe number-one API risk, its shop-name example on a hosted e-commerce platform, why comparing user IDs is not enough, and the advice on random IDs and authorization tests.
    8. Auth0 Docs: Work with tokens and Organizationsauth0.comAn org_id claim in ID and access tokens, validating it against known organisations, preferring IDs to names, and segmenting API data access by it.
    9. GitHub Docs: Types of GitHub accountsdocs.github.comPeople sign in to user accounts, never to organisations; a user can belong to many organisations; enterprise accounts manage policy and billing for several organisations.
    10. Slack Help Center: Enterprise organization launch guideslack.comExisting workspaces, each with its own URL and ID, are migrated into one Enterprise organisation, where single sign-on is required.