Goal: Replace the auto-generated Cognito hosted UI URL
(us-west-2gpfpyjsfg.auth.us-west-2.amazoncognito.com) shown in iOS OAuth
dialogs with branded custom domains so users see:
"SherpaHealthy" Wants to Use "auth.sherpahealthy.com" to Sign In
| Env | Pool ID | Current domain | Custom domain |
|---|---|---|---|
| Dev/Staging | us-west-2_GPFPYjsFG |
us-west-2gpfpyjsfg.auth.us-west-2.amazoncognito.com |
auth.sherpahealthy-d.com |
| Production | us-west-2_rYit4QTCG |
us-west-2ryit4qtcg.auth.us-west-2.amazoncognito.com |
auth.sherpahealthy.com |
Cognito custom domains require a certificate in us-east-1 regardless of the
pool's home region. Both accounts already have a provider "aws" { alias = "us-east-1" } in their provider.tf.
Production — add to production/acm.tf:
resource "aws_acm_certificate" "cognito_auth" {
provider = aws.us-east-1
domain_name = "auth.sherpahealthy.com"
validation_method = "DNS"
lifecycle { create_before_destroy = true }
}Sandbox — new sandbox/cognito.tf:
resource "aws_acm_certificate" "cognito_auth_d" {
provider = aws.us-east-1
domain_name = "auth.sherpahealthy-d.com"
validation_method = "DNS"
lifecycle { create_before_destroy = true }
}The existing
dev_cert_2wildcard (*.sherpahealthy-d.com) lives inus-west-2(no provider alias), so a new cert is needed.
After terraform plan, add the CNAME validation records Terraform outputs to
Cloudflare for both sherpahealthy.com and sherpahealthy-d.com.
- Use DNS-only / grey cloud (no Cloudflare proxy)
- Cert validation typically takes ~5 minutes
Run after certs are validated.
Production — add to production/cognito.tf:
resource "aws_cognito_user_pool_domain" "custom" {
domain = "auth.sherpahealthy.com"
user_pool_id = module.common.cognito_user_pool_id
custom_domain_config {
certificate_arn = aws_acm_certificate.cognito_auth.arn
}
}
output "cognito_custom_domain_cloudfront" {
value = aws_cognito_user_pool_domain.custom.cloudfront_distribution
}Also add the new IdP response URL to callback_urls in
aws_cognito_user_pool_client.spa_app:
"https://auth.sherpahealthy.com/oauth2/idpresponse",Keep the old amazoncognito.com IdP response URL until Google/Apple OAuth
configs are updated (Phase 5).
Sandbox — add to sandbox/cognito.tf:
resource "aws_cognito_user_pool_domain" "custom" {
domain = "auth.sherpahealthy-d.com"
user_pool_id = aws_cognito_user_pool.users.id
custom_domain_config {
certificate_arn = aws_acm_certificate.cognito_auth_d.arn
}
}
output "cognito_custom_domain_cloudfront" {
value = aws_cognito_user_pool_domain.custom.cloudfront_distribution
}After apply, retrieve the CloudFront domain from the Terraform output and add:
| Record | Type | Value |
|---|---|---|
auth.sherpahealthy.com |
CNAME | <output>.cloudfront.net |
auth.sherpahealthy-d.com |
CNAME | <output>.cloudfront.net |
Again: DNS-only, no Cloudflare proxy.
Must be done before removing old amazoncognito.com redirect URIs.
- Google OAuth Console: add
https://auth.sherpahealthy.com/oauth2/idpresponseandhttps://auth.sherpahealthy-d.com/oauth2/idpresponseas authorized redirect URIs in the respective OAuth clients. - Apple Sign-In: update the return URL in Apple's developer portal for both environments.
Update domain constants once the new auth domains are confirmed live:
| File | Field(s) |
|---|---|
k8s/frontend-configmap-dev.yaml |
COGNITO_DOMAIN |
k8s/frontend-configmap-staging.yaml |
COGNITO_DOMAIN |
k8s/frontend-configmap-production.yaml |
COGNITO_DOMAIN |
apps/web/cognito-config.ts |
PROD_DOMAIN, DEV_STAGING_DOMAIN |
apps/web/entrypoint.sh |
Default domain fallbacks |
shared/lib/sherpaApiConfig.ts |
LEGACY_DOMAIN, PROD_COGNITO_DOMAIN |
shared/view-controllers/useLoginViewController.tsx |
COGNITO_CONFIG.domain |
apps/mobile/app/auth/login.tsx |
COGNITO_DOMAIN constant |
apps/mobile/app/auth/screenPlay.tsx |
COGNITO_DOMAIN constant |
After code is deployed and verified, remove the old amazoncognito.com IdP
response URLs from the Cognito user pool clients and from Google/Apple consoles.
Phase 1 — TF: ACM certs (implement now, no blockers)
↓
Phase 2 — Cloudflare: cert validation CNAMEs ← needs DNS access
↓
Phase 3 — TF: Cognito custom domains (after cert validates)
↓
Phase 4 — Cloudflare: auth CNAMEs ← needs DNS access + TF output
↓
Phase 5 — Google/Apple OAuth console updates ← parallel with Phase 4
↓
Phase 6 — App code changes ← deploy after Phase 4 is live
DNS access (Cloudflare) is the only external blocker. Phases 1 and 3 are pure Terraform and can be implemented immediately.