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

Multitenancy

skill-claude-dev-suite-claude-dev-suite-multitenancy · by claude-dev-suite

|

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

Install

$ agentstack add skill-claude-dev-suite-claude-dev-suite-multitenancy

✓ 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-claude-dev-suite-claude-dev-suite-multitenancy)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo 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 Multitenancy? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Multi-Tenant Architecture

Isolation Strategies

| Strategy | Isolation | Complexity | Cost | |----------|-----------|------------|------| | Database per tenant | Highest | High | High | | Schema per tenant | High | Medium | Medium | | Shared schema (tenant_id column) | Medium | Low | Low | | Row-level security (RLS) | Medium-High | Medium | Low |

Shared Schema with Tenant ID (most common)

// Middleware: resolve tenant from subdomain or header
function tenantMiddleware(req: Request, res: Response, next: NextFunction) {
  const host = req.hostname; // acme.myapp.com
  const subdomain = host.split('.')[0];
  const tenant = await tenantRepo.findBySubdomain(subdomain);
  if (!tenant) return res.status(404).json({ error: 'Tenant not found' });
  req.tenantId = tenant.id;
  next();
}

// Always filter by tenant
app.get('/api/products', async (req, res) => {
  const products = await db.product.findMany({
    where: { tenantId: req.tenantId },
  });
  res.json(products);
});

Prisma with Tenant Scoping

// Extension to auto-apply tenant filter
const prisma = new PrismaClient().$extends({
  query: {
    $allOperations({ args, query, operation }) {
      if (['findMany', 'findFirst', 'count', 'updateMany', 'deleteMany'].includes(operation)) {
        args.where = { ...args.where, tenantId: getCurrentTenantId() };
      }
      if (['create', 'createMany'].includes(operation)) {
        args.data = { ...args.data, tenantId: getCurrentTenantId() };
      }
      return query(args);
    },
  },
});

PostgreSQL Row-Level Security

-- Enable RLS
ALTER TABLE products ENABLE ROW LEVEL SECURITY;

-- Policy: users see only their tenant's data
CREATE POLICY tenant_isolation ON products
  USING (tenant_id = current_setting('app.tenant_id')::uuid);

-- Set tenant context per request
SET app.tenant_id = 'tenant-uuid-here';
SELECT * FROM products; -- auto-filtered
// Set tenant context on each request
pool.on('connect', async (client) => {
  // Set after getting connection from pool
});

async function withTenant(tenantId: string, fn: () => Promise): Promise {
  const client = await pool.connect();
  try {
    await client.query(`SET app.tenant_id = $1`, [tenantId]);
    return await fn();
  } finally {
    await client.query('RESET app.tenant_id');
    client.release();
  }
}

Schema-Per-Tenant

// Dynamic schema selection
function getTenantSchema(tenantId: string): string {
  return `tenant_${tenantId.replace(/-/g, '_')}`;
}

async function createTenantSchema(tenantId: string) {
  const schema = getTenantSchema(tenantId);
  await db.query(`CREATE SCHEMA IF NOT EXISTS ${schema}`);
  await db.query(`SET search_path TO ${schema}`);
  await runMigrations(); // Apply schema migrations
}

Tenant Resolution Strategies

| Strategy | Example | Best For | |----------|---------|----------| | Subdomain | acme.myapp.com | B2B SaaS | | Path prefix | myapp.com/acme/... | Simpler setup | | Custom header | X-Tenant-ID: acme | API-first | | JWT claim | { tenantId: "acme" } | Authenticated APIs |

Anti-Patterns

| Anti-Pattern | Fix | |--------------|-----| | No tenant filter on queries | Use middleware or ORM extension to auto-apply | | Tenant ID from client without validation | Derive from auth token or subdomain | | No tenant data isolation testing | Write tests that verify cross-tenant isolation | | Shared cache without tenant prefix | Prefix all cache keys with tenant ID | | No tenant-aware rate limiting | Rate limit per tenant, not globally |

Production Checklist

  • [ ] Tenant resolution middleware on all routes
  • [ ] Data isolation verified with automated tests
  • [ ] Cache keys prefixed with tenant ID
  • [ ] Rate limiting per tenant
  • [ ] Tenant-scoped background jobs
  • [ ] Tenant provisioning and deprovisioning flow
  • [ ] Cross-tenant query prevention (RLS or ORM enforcement)

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.