AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Saas Multi Tenancy

skill-05-deepak-patidar-claude-skills-saas-multi-tenancy · by 05-deepak-patidar

Tenant isolation and lifecycle for multi-tenant SaaS — data scoping that fails closed, tenant context propagation, noisy neighbors, per-tenant operations. Use when building B2B/B2C SaaS with multiple customers on shared infrastructure, adding tenant-scoped tables or features, debugging cross-tenant data leaks, or when the user says "multi-tenant", "tenant isolation", "SaaS", "workspace", "organiz…

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add skill-05-deepak-patidar-claude-skills-saas-multi-tenancy

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-05-deepak-patidar-claude-skills-saas-multi-tenancy)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Saas Multi Tenancy? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

SaaS Multi-Tenancy

In a multi-tenant system, the worst bug class isn't downtime — it's tenant A seeing tenant B's data. One leaked invoice ends the customer relationship and possibly the company. Design so that isolation failures are structurally impossible, not just carefully avoided, because "carefully" doesn't survive the 400th endpoint.

Choosing the isolation model (decide once, explicitly)

  • Shared schema + tenant_id column — the default. Cheapest to operate, easiest to migrate, scales to thousands of tenants. Requires the discipline below.
  • Schema-per-tenant / database-per-tenant — buy isolation with operational pain (N× migrations, connection management, cost). Justified by: hard compliance walls, wildly divergent tenant sizes, or contractual "your data is physically separate". Don't drift here for comfort.
  • Hybrid (big tenants carved out) is legitimate — but only after the shared model measurably strains.

The rest of this skill assumes shared-schema, where the discipline matters most.

Gate 1: Scoping that fails CLOSED

The core principle: a forgotten WHERE clause must return nothing, not everything.

  • Two layers, always: application-level scoping (every query goes through a tenant-scoped session/repository that injects tenant_id — never hand-written per query) AND database-level enforcement (Postgres RLS with FORCE, policies keyed off a per-request setting, app connecting as a role that cannot bypass RLS — superusers silently bypass it; verify the role, and boot-guard against misconfiguration).
  • tenant_id NOT NULL on every tenant table + FK to the tenants table + composite indexes leading with it (database-design). New tenant-scoped table = added to the RLS/policy list in the same migration, enforced by convention and a test that scans the schema for unpoliced tables.
  • The tenant comes from the authenticated principal, never from the request — no ?account_id= params, no tenant in the POST body, no trusting a JWT claim you didn't issue (threat-model-security Gate 1).

Gate 2: Context propagation — where leaks actually happen

Request handlers are the easy part. Cross-tenant leaks live in the places that don't have a request:

  • Background jobs: every enqueued job carries its tenant_id explicitly, and the worker re-establishes tenant context before touching data. A worker processing a loop of tenants must reset context per iteration — context bleeding between loop iterations is the classic leak.
  • Caches: every cache key of tenant-scoped data includes the tenant (system-design). Query caches cleared on login/logout — stale cross-account data in an SPA is this bug wearing a frontend costume.
  • Scheduled/cron jobs, exports, report generators, search indexes, LLM/RAG retrieval (ai-engineering): each is a query path; each gets the same scoping audit as an endpoint.
  • Logs and error trackers: tag entries with tenant (great for debugging) but treat aggregated views as cross-tenant data needing admin-level access.

Gate 3: The two-tenant test — the cheapest breach prevention that exists

In your test suite, permanently: seed tenant A and tenant B, then as A's user attempt to read, update, delete, and list B's objects on every resource type — expecting 404/empty, never data. Add the list-endpoint case explicitly (unscoped lists leak in bulk). Run it in CI; every new resource joins it. Before any launch, run it live against production-like data (release-readiness Gate 2). This one fixture catches the bug class that code review misses.

Gate 4: Tenant lifecycle is a feature set, not an afterthought

Design these before the first real customer, because retrofitting them is surgery:

  • Provisioning: idempotent tenant creation (seed data, defaults, numbering sequences) — one function, tested.
  • Suspension (unpaid/abusive): a blocked/suspended flag checked at auth time, gating the whole app — data preserved, access stopped, reversible.
  • Export: a tenant can get their data out (their invoices, parties, ledgers) in a usable format. Contractually expected; also your data-privacy-compliance obligation.
  • Purge: hard deletion of a departed tenant — everywhere: rows, files/objects, search indexes, caches, backups-policy documented. An orphaned tenant's data is pure liability. Purge is destructive: confirm, audit, and stage it (soft-delete window → hard purge).

Gate 5: Tenants are not the same size — plan for the whale

  • Noisy neighbor: per-tenant rate limits on expensive endpoints, caps/pagination on unbounded queries (that one tenant with 500k products will find your missing LIMIT), and background-job queues that can't be monopolized by one tenant's bulk import (fair scheduling or per-tenant concurrency caps).
  • Observe per-tenant: your metrics need a tenant dimension on the hot paths — "the API is slow" vs "tenant 4 is running 80% of load" are different incidents (observability-readiness).
  • Per-tenant configuration (features, limits, branding) lives in a tenants/settings table read at runtime — never in code branches naming specific customers.

Cross-tenant admin operations

Your own admin/support panel is deliberately cross-tenant — which makes it the highest-privilege attack surface you own: separate principal type and stronger auth, every cross-tenant read/write written to an append-only audit log (who viewed which tenant's what, when), and impersonation (log-in-as-tenant), if built, is time-boxed, visibly flagged in the UI, and audited. Support convenience is how breaches get built with good intentions.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.