SSL/TLS Certificates
Audience: Application creators deploying apps with custom domains, and platform operators managing the certificate infrastructure.
How It Works
The WBSP platform automatically provisions and renews SSL/TLS certificates for every deployed application. When you deploy an app with a custom domain, the platform:
- Detects the domain from your app's route configuration
- Requests a certificate from Let's Encrypt using the ACME protocol
- Serves your app over HTTPS with a valid, browser-trusted certificate
- Redirects all HTTP traffic to HTTPS automatically
- Renews the certificate before it expires (certificates are valid for 90 days)
You do not need to buy certificates, generate keys, or configure TLS manually.
For Application Creators
Setting Up a Custom Domain
-
Add a CNAME record for your domain pointing to the platform's endpoint:
myapp.example.com CNAME your-platform-endpoint.elb.amazonaws.com -
Configure the domain in your app's YAML:
destination: prod: type: aws tenant: acme cluster: main enclave: myapp access: public routes: prod: { domain: myapp.example.com } -
Deploy:
wbsp-app deploy --destination prod --config wbsp.yaml
The certificate is provisioned automatically during deployment. Your site will be accessible over HTTPS within approximately 1-2 minutes.
Multiple Domains
The routes map carries one entry per destination. To serve the same app on a
second domain, declare a second aws destination with its own route — each is an
independent placement and each domain gets its own certificate:
destination:
prod:
type: aws
tenant: acme
cluster: main
enclave: myapp
prod-alt:
type: aws
tenant: acme
cluster: main
enclave: myapp-alt
access: public
routes:
prod: { domain: myapp.example.com }
prod-alt: { domain: myapp.customdomain.org }What to Expect
- First visit: There may be a brief delay (up to 60 seconds) on the very first HTTPS request while the certificate is being issued.
- HTTP redirect: All HTTP requests are automatically redirected to HTTPS.
- Renewal: Certificates renew automatically approximately 30 days before expiration. No action required.
- Removal: When you remove an app or change its domain, the old certificate is cleaned up automatically.
Troubleshooting
Certificate not issued after deployment?
- Verify your CNAME record is propagated:
dig myapp.example.com CNAME - The CNAME must resolve to the platform's load balancer before a certificate can be issued.
- If DNS hasn't propagated yet, the platform will retry automatically.
Browser shows "Not Secure" warning?
- If you're using a staging environment, this is expected. Staging certificates are issued by an untrusted test CA.
- Check with your platform operator to confirm whether staging or production certificates are configured.
For Platform Operators
Staging vs Production Certificates
The platform supports two Let's Encrypt environments:
| Environment | ACME Server | Browser Trusted | Rate Limits |
|---|---|---|---|
| Staging | https://acme-staging-v02.api.letsencrypt.org/directory | No | Very high (for testing) |
| Production | https://acme-v02.api.letsencrypt.org/directory | Yes | Strict (see below) |
Always use staging during development and testing. Switch to production only for live deployments serving real users.
The ACME server URL is configured in the Traefik Helm values during platform provisioning.
Let's Encrypt Rate Limits
Production rate limits to be aware of:
| Limit | Value | Notes |
|---|---|---|
| Certificates per registered domain | 50 per week | e.g., 50 certs for *.example.com subdomains per week |
| Duplicate certificates | 5 per week | Same exact domain set re-issued |
| New orders per account | 300 per 3 hours | Across all domains |
| Failed validations | 5 per hour per domain | CNAME must be correct before issuance |
Under normal operation (fewer than 50 new unique domains per week), these limits are not a concern. The staging environment has much higher limits and should be used for all testing.
Certificate Storage
Certificates and the ACME account key are stored on a Kubernetes PersistentVolumeClaim mounted into the Traefik pod. This ensures:
- Certificates survive pod restarts and rescheduling
- Certificates are not re-requested from Let's Encrypt after a restart
- The ACME account identity is preserved
Certificate Cleanup
When an application is removed via wbsp-app remove, the platform:
- Deletes the IngressRoute for the domain
- Traefik's ACME client stops tracking the domain for renewal
Orphaned certificates in Traefik's ACME storage are not automatically pruned, but they consume negligible space and do not affect operation.
Architecture
Browser → NLB (port 443, TCP passthrough) → Traefik (TLS termination + ACME) → App Container
Browser → NLB (port 80) → Traefik (HTTP → HTTPS redirect)- The NLB passes TLS traffic through to Traefik on port 443 without terminating it
- Traefik handles TLS termination, certificate selection via SNI, and the ACME challenge
- HTTP-01 challenge is used: Let's Encrypt connects to your domain over port 80, and Traefik responds with the verification token
- DNS-01 challenge is not used because the platform does not control external domains' DNS zones
Limitations
- Wildcard certificates are not supported for the
aws/aws.on-demandtargets. Their HTTP-01 challenge cannot issue wildcard certs; each domain gets its own certificate. (Theaws.demotarget is different — see below.) - Domain must CNAME to the platform before deployment. If the CNAME is not propagated, certificate issuance will fail (and retry automatically).
- Local development remains HTTP-only. TLS is only configured for AWS targets.
Demo instances (aws.demo) — shared wildcard certificate
Ephemeral demo instances are short-lived and created in volume, so issuing a per-instance certificate does not scale (Let's Encrypt throttles at ~50 certs/registered-domain/week). The demo target therefore works differently:
- One wildcard certificate
*.‹demo-base-domain›(e.g.*.wbsp-demo.com) secures every demo instance. No per-instance certificate is ever issued. - Hostnames are a single label:
‹app›-‹token›.‹demo-base-domain›(e.g.studytomigrate-a1b2c3.wbsp-demo.com). The app name is visible; the random token makes the URL unguessable. A single label is required because a wildcard certificate and a wildcard DNS record each cover only one label level. - Issued via the DNS-01 (Route 53) challenge, so the wildcard can be pre-provisioned before any demo exists and a new demo serves trusted HTTPS on its first request (no issuance latency).
- Credentials via IRSA — Traefik assumes an IAM role scoped to only the demo hosted zone (no static keys; least privilege).
- Separate registered domain from production (
wbsp.ai) so demo certificate churn and HSTS never affect production certificate issuance/renewal. - Fail-fast: deploying a demo destination (
type: aws, mode: demo) is refused with a clear error if the wildcard certificate is not in place — no instance is started that cannot serve trusted TLS.
Operators: roll out on the Let's Encrypt staging CA first
(acme_staging=true), verify with openssl s_client, then switch to the
production CA. The full provisioning and validation steps — DNS-01 solver
configuration, the acme_staging toggle, and openssl s_client verification —
are covered by the demo-wildcard TLS sections of this guide and the
Platform Operator Guide.