Tools
Tools: We Built One Platform That Powers 30+ Brands — The White-Label SaaS Playbook
2026-02-13
0 views
admin
Why White-Label? ## The Architecture ## Multi-Tenancy: The Foundation ## Theming Engine ## Feature Flags Per Tenant ## Real-World Examples ## Delivery Management ## Fintech Dashboards ## Healthcare Portals ## Education LMS ## The Technical Challenges We Solved ## 1. Data Isolation is Non-Negotiable ## 2. Performance at Scale ## 3. Deployment Without Downtime ## 4. Custom Domain Routing ## The Business Model ## Lessons Learned Three years ago, a client came to us with a problem: they had built a successful delivery management platform for their own logistics company, and three of their partners wanted the same system — but branded as their own. "Can you just copy the code and change the logo?" they asked. The answer was no. But the question led us to build something far more valuable: a multi-tenant, white-label SaaS architecture that now powers 30+ brands from a single codebase. At Mind Group Technologies, this project became one of our most technically interesting and commercially successful. Here's what we learned building it. The SaaS market globally is worth over $200 billion. In Latin America, it's growing at 35-40% year-over-year. But here's the insight most SaaS founders miss: you don't always need to build a brand to build a business. White-label SaaS lets you build one platform and sell it as many products. Your clients get a fully branded solution. You get recurring revenue from a single codebase. The economics are compelling: instead of acquiring end-users one by one, you acquire business clients who bring their entire user base with them. Every white-label platform needs a robust multi-tenancy model. We chose a shared database with tenant isolation approach: Why shared database? For white-label with 30+ tenants, maintaining separate databases per tenant becomes an operational nightmare. Shared database with row-level security (using PostgreSQL RLS) gives us data isolation without the infrastructure overhead. The key implementation details: Each brand needs to look completely different. We built a theming engine that handles: Not every brand gets every feature. We use a feature flag system tied to the tenant's subscription tier: Our original use case: a delivery platform white-labeled for logistics companies. Each company sees their own brand, their own data, their own customer portal. But under the hood, it's one platform. Results: 30+ brands, 60-70% infrastructure savings compared to individual deployments. One bug fix benefits all clients simultaneously. We extended the pattern to financial dashboards. Banks and fintechs get a fully branded analytics platform for their customers. Each bank's branding, each bank's compliance requirements, one shared platform. At Mind Group Technologies, we built the compliance layer once (LGPD, BCB regulations) and every tenant benefits. That's the power of shared infrastructure. Patient portals for clinic networks. Each clinic has their own branded portal where patients schedule appointments, view results, and communicate with providers. The multi-tenant architecture means adding a new clinic takes hours, not weeks. Learning management systems for training companies. Each company gets their own branded LMS with courses, certifications, and progress tracking. Content is shared or isolated depending on the licensing agreement. In healthcare and fintech white-label products, data leakage between tenants is catastrophic. We use PostgreSQL Row-Level Security (RLS) as the last line of defense: Even if application code has a bug, the database itself prevents cross-tenant data access. With 30+ tenants sharing a database, query performance matters: All tenants share the same codebase, so deployments affect everyone. We use: Each tenant can use their own domain. The routing layer maps incoming requests to the correct tenant configuration: We handle SSL certificates automatically using Let's Encrypt with DNS validation. White-label SaaS typically follows a B2B2C model: Start with one use case, then generalize. Our delivery platform became white-label because a real client needed it. We didn't build "a white-label platform" — we made an existing product configurable. Invest in admin tooling early. The internal dashboard for managing tenants, configurations, and deployments saves more time than any customer-facing feature. Test with the ugliest theme. If your platform looks good with neon green and comic sans, it'll look good with anything. We literally test with absurd themes to catch layout issues. Plan for the exception. Every client will want "just one small custom feature." Build your architecture to handle this without forking the codebase. José Gonçalves is the Founder & CEO of Mind Group Technologies, a software development company in Sorocaba, Brazil. We specialize in white-label SaaS platforms, multi-tenant architectures, and custom software for startups and enterprises. If you're considering building a white-label product, we'd love to share our experience — reach out at mindconsulting.com.br. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK:
┌─────────────────────────────────────────┐
│ Application Layer │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Brand A│ │Brand B│ │Brand C│ │
│ └──┬───┘ └──┬───┘ └──┬───┘ │
│ │ │ │ │
│ ┌──▼─────────▼─────────▼──┐ │
│ │ Tenant Router │ │
│ └──────────┬──────────────┘ │
│ │ │
│ ┌──────────▼──────────────┐ │
│ │ Shared Database │ │
│ │ (Row-Level Security) │ │
│ └─────────────────────────┘ │
└─────────────────────────────────────────┘ Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
┌─────────────────────────────────────────┐
│ Application Layer │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Brand A│ │Brand B│ │Brand C│ │
│ └──┬───┘ └──┬───┘ └──┬───┘ │
│ │ │ │ │
│ ┌──▼─────────▼─────────▼──┐ │
│ │ Tenant Router │ │
│ └──────────┬──────────────┘ │
│ │ │
│ ┌──────────▼──────────────┐ │
│ │ Shared Database │ │
│ │ (Row-Level Security) │ │
│ └─────────────────────────┘ │
└─────────────────────────────────────────┘ CODE_BLOCK:
┌─────────────────────────────────────────┐
│ Application Layer │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │Brand A│ │Brand B│ │Brand C│ │
│ └──┬───┘ └──┬───┘ └──┬───┘ │
│ │ │ │ │
│ ┌──▼─────────▼─────────▼──┐ │
│ │ Tenant Router │ │
│ └──────────┬──────────────┘ │
│ │ │
│ ┌──────────▼──────────────┐ │
│ │ Shared Database │ │
│ │ (Row-Level Security) │ │
│ └─────────────────────────┘ │
└─────────────────────────────────────────┘ COMMAND_BLOCK:
// Tenant middleware - runs on every request
const tenantMiddleware = async (req, res, next) => { const tenantId = extractTenantFromDomain(req.hostname); const tenant = await getTenantConfig(tenantId); if (!tenant) return res.status(404).send('Unknown tenant'); req.tenant = tenant; req.db = createTenantContext(tenantId); // Sets RLS context next();
}; Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
// Tenant middleware - runs on every request
const tenantMiddleware = async (req, res, next) => { const tenantId = extractTenantFromDomain(req.hostname); const tenant = await getTenantConfig(tenantId); if (!tenant) return res.status(404).send('Unknown tenant'); req.tenant = tenant; req.db = createTenantContext(tenantId); // Sets RLS context next();
}; COMMAND_BLOCK:
// Tenant middleware - runs on every request
const tenantMiddleware = async (req, res, next) => { const tenantId = extractTenantFromDomain(req.hostname); const tenant = await getTenantConfig(tenantId); if (!tenant) return res.status(404).send('Unknown tenant'); req.tenant = tenant; req.db = createTenantContext(tenantId); // Sets RLS context next();
}; CODE_BLOCK:
// Theme configuration per tenant
const themeConfig = { brandA: { primaryColor: '#1a73e8', fontFamily: 'Inter, sans-serif', logoUrl: '/assets/brandA/logo.svg', layout: 'sidebar', customCSS: '.header { border-bottom: 3px solid #1a73e8; }' }, brandB: { primaryColor: '#e53935', fontFamily: 'Roboto, sans-serif', logoUrl: '/assets/brandB/logo.svg', layout: 'topnav', customCSS: '' }
}; Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
// Theme configuration per tenant
const themeConfig = { brandA: { primaryColor: '#1a73e8', fontFamily: 'Inter, sans-serif', logoUrl: '/assets/brandA/logo.svg', layout: 'sidebar', customCSS: '.header { border-bottom: 3px solid #1a73e8; }' }, brandB: { primaryColor: '#e53935', fontFamily: 'Roboto, sans-serif', logoUrl: '/assets/brandB/logo.svg', layout: 'topnav', customCSS: '' }
}; CODE_BLOCK:
// Theme configuration per tenant
const themeConfig = { brandA: { primaryColor: '#1a73e8', fontFamily: 'Inter, sans-serif', logoUrl: '/assets/brandA/logo.svg', layout: 'sidebar', customCSS: '.header { border-bottom: 3px solid #1a73e8; }' }, brandB: { primaryColor: '#e53935', fontFamily: 'Roboto, sans-serif', logoUrl: '/assets/brandB/logo.svg', layout: 'topnav', customCSS: '' }
}; COMMAND_BLOCK:
const canAccessFeature = (tenant, feature) => { const tierFeatures = { basic: ['dashboard', 'orders', 'reports'], pro: ['dashboard', 'orders', 'reports', 'analytics', 'api'], enterprise: ['dashboard', 'orders', 'reports', 'analytics', 'api', 'whitelabel-emails', 'custom-domain'] }; return tierFeatures[tenant.tier]?.includes(feature) ?? false;
}; Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK:
const canAccessFeature = (tenant, feature) => { const tierFeatures = { basic: ['dashboard', 'orders', 'reports'], pro: ['dashboard', 'orders', 'reports', 'analytics', 'api'], enterprise: ['dashboard', 'orders', 'reports', 'analytics', 'api', 'whitelabel-emails', 'custom-domain'] }; return tierFeatures[tenant.tier]?.includes(feature) ?? false;
}; COMMAND_BLOCK:
const canAccessFeature = (tenant, feature) => { const tierFeatures = { basic: ['dashboard', 'orders', 'reports'], pro: ['dashboard', 'orders', 'reports', 'analytics', 'api'], enterprise: ['dashboard', 'orders', 'reports', 'analytics', 'api', 'whitelabel-emails', 'custom-domain'] }; return tierFeatures[tenant.tier]?.includes(feature) ?? false;
}; CODE_BLOCK:
-- Enable RLS on the orders table
ALTER TABLE orders ENABLE ROW LEVEL SECURITY; -- Create policy for tenant isolation
CREATE POLICY tenant_isolation ON orders USING (tenant_id = current_setting('app.current_tenant')::uuid); Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
-- Enable RLS on the orders table
ALTER TABLE orders ENABLE ROW LEVEL SECURITY; -- Create policy for tenant isolation
CREATE POLICY tenant_isolation ON orders USING (tenant_id = current_setting('app.current_tenant')::uuid); CODE_BLOCK:
-- Enable RLS on the orders table
ALTER TABLE orders ENABLE ROW LEVEL SECURITY; -- Create policy for tenant isolation
CREATE POLICY tenant_isolation ON orders USING (tenant_id = current_setting('app.current_tenant')::uuid); CODE_BLOCK:
app.brandA.com → Tenant A config
logistics.brandB.io → Tenant B config
portal.brandC.com.br → Tenant C config Enter fullscreen mode Exit fullscreen mode CODE_BLOCK:
app.brandA.com → Tenant A config
logistics.brandB.io → Tenant B config
portal.brandC.com.br → Tenant C config CODE_BLOCK:
app.brandA.com → Tenant A config
logistics.brandB.io → Tenant B config
portal.brandC.com.br → Tenant C config - Colors — Primary, secondary, accent, backgrounds
- Typography — Font families, sizes, weights
- Logo and imagery — Header, footer, favicon, email templates
- Layout variations — Some brands want sidebar nav, others want top nav
- Custom CSS — For clients who want pixel-perfect customization - Tenant-partitioned indexes on all frequently queried tables
- Connection pooling with PgBouncer configured per-tenant
- Caching layer (Redis) with tenant-prefixed keys
- Read replicas for analytics-heavy tenants - Blue-green deployments for zero-downtime releases
- Feature flags to gradually roll out changes
- Canary releases — new features go to one tenant first
- Instant rollback capability if issues are detected - You build and maintain the platform
- Your clients (businesses) brand and sell it
- Their customers (end-users) use the product - Monthly SaaS fees per tenant (tiered by features/users)
- Setup fees for onboarding and customization
- Revenue share on transactions processed through the platform
- Professional services for custom integrations
how-totutorialguidedev.toainetworkdnsroutingrouterpostgresqlssldatabase