Goal
Bind postkit.singletonsd.com as the public HTTPS hostname for production Function App ssd-postkit-api-prod-ae, so consumers call a stable branded API URL instead of *.azurewebsites.net.
Context
- Subscription
SSD Post Kit / 9b6fc2b1-064a-4eb2-81fe-0aa8c7c751b5, RG rg-postkit-prod-ae
- App is Linux Consumption (Y1) Node 22 today — custom domains are CNAME-based; managed cert support can be flaky on classic Consumption. Prefer completing on current plan; if Azure blocks managed TLS, document the blocker and the smallest plan change (e.g. Flex Consumption) as a follow-up issue rather than silently abandoning the hostname.
- DNS for
singletonsd.com is Route53 hosted zone Z2PHDBJIVYBXRT. Use skill engineering/route53-subdomains (load company.secrets.env; never invent zone IDs).
- Custom domain verification ID (for
asuid TXT): obtain via az functionapp show --query customDomainVerificationId (do not hardcode stale values).
Scope
- DNS (Route53):
asuid.postkit.singletonsd.com TXT = Function App customDomainVerificationId
postkit.singletonsd.com CNAME → ssd-postkit-api-prod-ae.azurewebsites.net
- Azure: bind hostname + HTTPS (App Service Managed Certificate / SNI if supported on this plan).
- App Configuration
ssd-postkit-appcs-prod-ae: set live key app:api:publicBaseUrl to https://postkit.singletonsd.com (this key is consumer-facing; Function App does not need it as an app setting).
- Repo: update
infra/appconfig-seed.json and docs that still teach the azurewebsites public base URL as source of truth (docs/integrations/inkads-marketing.md, infra/README.md / SETUP.md only if they state the public URL).
- Smoke:
curl -fsS https://postkit.singletonsd.com/health returns ok; TLS valid.
Out of scope
- Do not edit
infra/function-app.bicep CORS (cors.allowedOrigins) — owned by the sibling CORS/consumer-onboarding issue.
- Do not change contact delivery / email provider behaviour.
- Do not migrate the plan unless required for TLS; if required, stop after hostname/DNS and open a follow-up issue.
Constraints
- Public repo: no secrets in issues/PRs/commits.
- Worktree from
origin/main via ./scripts/add-worktree.sh --issue <N> --type feat --slug postkit-custom-domain.
- Claim by opening a PR with
Closes #<N>; abort if an open linked PR already exists.
Acceptance criteria
Agent notes
Read docs/github-source-of-truth.md, AGENTS.md, and engineering/route53-subdomains. Keep azurewebsites hostname working as fallback.
Goal
Bind
postkit.singletonsd.comas the public HTTPS hostname for production Function Appssd-postkit-api-prod-ae, so consumers call a stable branded API URL instead of*.azurewebsites.net.Context
SSD Post Kit/9b6fc2b1-064a-4eb2-81fe-0aa8c7c751b5, RGrg-postkit-prod-aesingletonsd.comis Route53 hosted zoneZ2PHDBJIVYBXRT. Use skillengineering/route53-subdomains(loadcompany.secrets.env; never invent zone IDs).asuidTXT): obtain viaaz functionapp show --query customDomainVerificationId(do not hardcode stale values).Scope
asuid.postkit.singletonsd.comTXT = Function AppcustomDomainVerificationIdpostkit.singletonsd.comCNAME →ssd-postkit-api-prod-ae.azurewebsites.netssd-postkit-appcs-prod-ae: set live keyapp:api:publicBaseUrltohttps://postkit.singletonsd.com(this key is consumer-facing; Function App does not need it as an app setting).infra/appconfig-seed.jsonand docs that still teach the azurewebsites public base URL as source of truth (docs/integrations/inkads-marketing.md,infra/README.md/SETUP.mdonly if they state the public URL).curl -fsS https://postkit.singletonsd.com/healthreturns ok; TLS valid.Out of scope
infra/function-app.bicepCORS (cors.allowedOrigins) — owned by the sibling CORS/consumer-onboarding issue.Constraints
origin/mainvia./scripts/add-worktree.sh --issue <N> --type feat --slug postkit-custom-domain.Closes #<N>; abort if an open linked PR already exists.Acceptance criteria
postkit.singletonsd.comresolves (CNAME) to the Function AppGET https://postkit.singletonsd.com/healthsucceedsapp:api:publicBaseUrlishttps://postkit.singletonsd.comCloses #<N>Agent notes
Read
docs/github-source-of-truth.md,AGENTS.md, andengineering/route53-subdomains. Keep azurewebsites hostname working as fallback.