Thesis: Ship a branded hostname such as api.example.com. Wire API Gateway’s custom domain (regional ACM + mapping), point DNS at the custom domain target hostname, then flip the SPA env and CSP. Do not CNAME at the API ID hostname or TLS will present the wrong certificate.
What leaks when you skip branding
Network panels, CSP reports, and curious buyers all see the same string: a regional execute-api host. For a security consultancy or any multi-tenant SaaS, that is unnecessary disclosure. It also forces your CSP to allow that host forever — or to use wildcards that are worse.
The same lesson applies to Function URL hosts on marketing forms (see note 01). Browsers should call names you own.
The cutover sequence that avoids downtime
- Request an ACM certificate for api.example.com in the API’s region (regional custom domains are not the CloudFront us-east-1 special case).
- Validate DNS, wait until the certificate is issued.
- Create the API Gateway domain name + API mapping to your stage.
- Add the public CNAME only after you know the target from the domain-name resource.
- Point the SPA API_BASE_URL (or equivalent) and CSP connect-src at https://api.example.com.
- Redeploy the UI so baked config and headers match.
Keep a feature flag or Terraform variable for “cutover” so the mapping can exist in state before DNS and Amplify (or your static host) flip. Creating the mapping early is fine; telling browsers to use the branded host before DNS is ready is not.
The TLS CNAME trap
API Gateway exposes two different hostnames that look related:
- The default API endpoint tied to the API ID.
- The target domain name on the custom domain configuration (often another *.execute-api… name, but not the API ID).
If you CNAME api.example.com at the API ID hostname, TLS often presents a certificate for the shared execute-api name — not your ACM cert for api.example.com. Browsers reject the connection. The fix is mechanical: CNAME to the custom-domain target from the domain-name resource, then confirm the peer certificate’s SAN lists your brand.
# Expect CN/SAN = api.example.com after DNS is correct curl -vI https://api.example.com/health
Headers that live outside the buildspec
Static hosts sometimes ignore buildspec-declared CSP when you deploy by zip or when the platform normalizes headers on the app resource. Put the CSP you care about on the hosting app configuration as well as in the build file, and re-check live response headers after cutover — not only the repo YAML.
Checklist
- Branded host in SPA config and CSP connect-src.
- CNAME target = custom domain target, not the API ID endpoint.
- Verify TLS SAN before flipping production traffic.
- Keep the raw execute-api URL for ops scripts if you must — not for browsers.
Next: why authenticated downloads lose file extensions.
Engineering commentary only — not audit, legal, or certification advice.