Building a 'SaaS-in-a-Box': The Core Components Every Dev Needs
Every SaaS product needs the same foundational pieces: authentication, multi-tenancy, billing, admin panels, and API architecture. This guide documents the reusable 'SaaS-in-a-Box' framework I built while developing ServiceCrud — so you can skip months of boilerplate.
I've built three SaaS products from scratch — ServiceCrud, InfoCrud, and internal tools for Kimaya. Every time, I rebuilt the same foundational components: authentication, authorization, multi-tenancy, billing integration, admin panels, and API architecture. By the third build, I realized I was wasting 60-80 hours per project on solved problems. So I extracted the common pieces into a reusable framework — a "SaaS-in-a-Box" that lets me go from idea to MVP in days instead of months.
Component 1: Authentication & Authorization
Every SaaS needs user registration, login, password reset, email verification, and session management. For ServiceCrud, I built a JWT-based auth system in Go Fiber with refresh token rotation, bcrypt password hashing, and role-based access control (RBAC) — support users, admin users, and tenant users with different permission levels.
The key design decision: separate authentication (who are you?) from authorization (what can you do?). Authentication is handled by middleware that validates JWT tokens on every request. Authorization is handled by a permission system that checks user roles against route-level access requirements. This separation means you can swap authentication providers (add OAuth, social login, SSO) without touching authorization logic.
The reusable pieces: JWT token generation/validation utilities, password hashing helpers, auth middleware, role-permission mapping, and registration/login/reset API endpoints. These transfer directly between projects with minimal modification.
Component 2: Multi-Tenancy Architecture
Most SaaS products serve multiple customers (tenants) from a single application instance. The architecture decision — shared database, schema-per-tenant, or database-per-tenant — has profound implications for cost, complexity, and data isolation.
For cost-sensitive solo-developer projects, I use shared database with tenant_id column isolation. Every data table includes a tenant_id foreign key, and every query is automatically scoped to the authenticated tenant. This is implemented through GORM scopes — a middleware-like pattern that appends WHERE tenant_id = ? to every query automatically. One database, one deployment, unlimited tenants, minimal cost.
The data model: a tenants table (id, name, slug, plan, settings), a tenant_users junction table (user_id, tenant_id, role), and tenant_id columns on all business data tables. Tenant resolution happens in middleware — extracting the tenant context from the JWT token and injecting it into the request context for downstream handlers.
Component 3: Admin Panel
Every SaaS needs two admin interfaces: a super-admin panel (for you, the platform operator) and a tenant admin panel (for your customers). The super-admin manages tenants, monitors usage, handles billing, and configures platform settings. The tenant admin manages their own users, data, and settings within their tenant scope.
For the frontend, I use React with Vite — a lightweight setup that builds fast and deploys as static files. The admin panel communicates with the Go backend through a RESTful API with role-based endpoint access. Reusable admin components: data tables with sorting/filtering/pagination, form builders, modal confirmations, toast notifications, and dashboard charts.
Component 4: API Architecture
RESTful API design with consistent patterns: plural resource names (/api/v1/products), proper HTTP methods (GET for reads, POST for creates, PUT for updates, DELETE for deletes), pagination via query parameters (?page=1&limit=20), and standardized error responses with error codes and human-readable messages.
API versioning through URL prefixes (/api/v1/) ensures backward compatibility as the product evolves. Rate limiting per tenant prevents any single customer from consuming disproportionate resources. Request validation middleware catches malformed requests before they reach business logic.
Component 5: Billing & Subscription Management
For Indian SaaS products, Razorpay or Cashfree handle subscription billing. The integration pattern: create a subscription plan in the payment provider, store the plan_id in your database, create subscriptions when tenants upgrade, and listen for webhook events (payment success, payment failure, subscription cancelled) to update tenant status automatically.
The webhook handler is the most critical piece — it must be idempotent (handle the same event multiple times without side effects), validate webhook signatures (verify the event came from the payment provider, not an attacker), and update tenant status atomically (upgrade/downgrade/cancel in a single transaction).
Component 6: Deployment Pipeline
The deployment stack: GitHub Actions for CI/CD, Docker for containerization, and AWS ECS (or a simple EC2 instance for early-stage projects) for hosting. The pipeline: push to main → run tests → build Docker image → push to ECR → deploy to ECS. Total deployment time: under 3 minutes from push to production.
This six-component framework is what I now start every new project with. The infrastructure is battle-tested across multiple products — ServiceCrud, InfoCrud, and Kimaya's backend all run on variations of this same architecture. When you have a proven foundation, you can focus 100% of your creative energy on the features that make your product unique rather than rebuilding solved problems.