Introduction
Modern SaaS commerce platforms often face a similar challenge: supporting a large number of customer-specific storefronts, each with its own custom domain, while still relying on a shared backend. When your infrastructure is built on EKS with CloudFront and an Application Load Balancer in front, and each tenant requires its own SSL certificate, scaling becomes a real architectural puzzle.
This article describes the problem we encountered, the options we evaluated, and the architecture we ultimately implemented to handle hundreds of HTTPS-enabled custom domains cleanly and reliably.
Context: The Multi-Tenant Storefront Platform
Our platform allows customers to create online shops under their own domains. Dozens or even hundreds of domains like: storeABC.com, *b…
Introduction
Modern SaaS commerce platforms often face a similar challenge: supporting a large number of customer-specific storefronts, each with its own custom domain, while still relying on a shared backend. When your infrastructure is built on EKS with CloudFront and an Application Load Balancer in front, and each tenant requires its own SSL certificate, scaling becomes a real architectural puzzle.
This article describes the problem we encountered, the options we evaluated, and the architecture we ultimately implemented to handle hundreds of HTTPS-enabled custom domains cleanly and reliably.
Context: The Multi-Tenant Storefront Platform
Our platform allows customers to create online shops under their own domains. Dozens or even hundreds of domains like: storeABC.com, brandshop.net, or my-boutique.co.uk — all point to a shared CloudFront distribution and eventually arrive at the same ALB and EKS cluster. The backend determines the tenant based on the incoming Host header.
For this to work securely, each domain needs its own HTTPS certificate. CloudFront now supports a Multi-Tenant SaaS distribution model, which makes onboarding new domains dramatically easier: certificates are created in us-east-1, automatically validated, and attached to a single shared CloudFront distribution that serves all tenants. Also AWS ssl certificate limit is 2000 per one Multi-Tenant SaaS distribution and we can have several such distributions.
This simplicity stops at CloudFront. The real challenge appears on the origin side.
The Certificate Problem on the ALB Side
CloudFront terminates HTTPS at the edge. After that, it connects to the origin — in our case, an Application Load Balancer — using HTTPS again, so ALB also needs certificates for tls handshake.
In AWS ALB has a strict quota: → 100 SSL certificates per ALB
In a system with 300+ custom domains, this limit becomes a blocker. This brings us to the architectural decision point.
Architecture Options We Considered
1. Using CloudFront VPC Origin to Avoid SSL on the ALB
One of the first ideas was to place CloudFront’s origin inside the VPC using the VPC Origin feature. Traffic would travel over AWS’s private network and could therefore be sent to the ALB over plain HTTP, eliminating the need for certificates on the ALB entirely. It’s elegant—until you discover that VPC Origin does not support WebSockets, a requirement for our application. That limitation alone ruled out this approach.
2. Splitting Tenants Across Multiple ALBs and Distributions
Another possibility involved spliting tenants across Several CloudFront SaaS distributions and Several ALBs.This bypasses the 100-cert limit by distributing certificates across multiple ALBs and CloudFront distributions.
Why we rejected it:
- Massive IaC overhead
- Requires tracking which tenant belongs to which ALB & distribution
- Complicated domain lifecycle management
- Harder observability & error tracing
- High risk of misconfiguration
- Poor maintainability at scale
Technically feasible — but operationally a nightmare.
The Solution: One ALB, One Distribution, One Internal Certificate
What ultimately made this architecture scalable was realizing that CloudFront does not require the same domain that the customer is visiting to be used as the origin domain. CloudFront only expects that the origin domain configured in the distribution has a valid certificate on the ALB—nothing more. At the same time, CloudFront is perfectly capable of forwarding the original Host header to the backend.
This allowed us to decouple tenant domains from the ALB entirely.
How It Works
We introduced a single internal domain, for example:
origin.example.com
This domain points to the ALB’s DNS name via a CNAME record. The ALB holds just one TLS certificate for this internal domain, and CloudFront uses this domain as its sole origin for all tenants.
User → https://storeABC.com
↓
CloudFront (receives request)
- TLS handshake with storeABC.com
- Decrypts request
- Forwards request to origin
↓
CloudFront → Origin (ALB via CNAME):
- New HTTPS request to https://origin.example.com
- TLS handshake with ALB (*.example.com)
- Sends HTTP request with Host: storeABC.com
↓
ALB:
- Terminates TLS
- Receives Host: storeABC.com
- Forwards to backend service/pod in EKS
With this setup, the number of tenant domains no longer affects the ALB at all. Scaling from 10 to 1,000 custom domains is simply a matter of attaching more certificates to CloudFront, which is designed for that scale.
Why This Architecture Works Well
This solution eliminates the ALB certificate quota entirely while preserving strong end-to-end encryption. It keeps the infrastructure clean: only one CloudFront distribution, one ALB, one certificate on the origin, and no complicated domain-to-origin mapping. WebSockets work because the origin is a standard HTTPS endpoint rather than a VPC-origin endpoint. And from an IaC perspective, the system becomes straightforward to automate and reason about.
Most importantly, the design uses only native AWS capabilities with no custom components or service-specific tricks, making it robust, predictable, and cloud-portable if necessary.
Conclusion
Designing a multi-tenant architecture capable of handling hundreds of custom domains is not as simple as placing CloudFront in front of an ALB. Certificate limits, WebSocket support, and management complexity all influence the final design. After evaluating several approaches, we found that introducing a single internal origin domain offers the cleanest and most scalable solution. CloudFront takes responsibility for per-tenant TLS termination, while the ALB handles only a single internal certificate. The backend receives correct tenant routing through the Host header, and the system remains simple enough to maintain and automate.