Custom Hostnames & Certificates
← Back to Ingress Configuration Tutorial
This guide covers two related concerns that almost always travel together:
- Custom hostnames: exposing your application on a domain you own (e.g.
app.example.com) instead of the platform-generated hostname. - TLS certificates: bringing your existing certificate into the platform so the gateway can terminate HTTPS for that custom hostname.
This guide focuses on the last mile, getting a certificate that your organization has already issued into the platform and wired up to a PlatformApplication. It does not cover how to obtain or generate the certificate itself; your organization likely already has a process for that (e.g. corporate CA, public CA like DigiCert, ACM).
When You Need This
The default platform-generated hostname (e.g. myapp.eks.us-east-2.aws.dev.ybor-studio.p6m.run) is served by a wildcard certificate that the platform manages for you. You only need this guide when:
- You want users to reach the app at a custom domain you own (
api.example.com,auth.example.com, etc.). - Compliance or business requirements force you to use a certificate issued by a specific CA.
- You're migrating an existing application onto the platform and need to preserve its public hostname/cert.
If none of those apply, stop here and stick with the default. The platform handles DNS and TLS automatically.
Prerequisites
Before you start, you should have:
- A
PlatformApplicationthat already deploys successfully with default ingress (see Adding Ingress). - A certificate and private key issued for the hostname(s) you want to use. The platform supports two formats:
- PEM: text-encoded
tls.crtandtls.key(most common). - PKCS#12: a single binary
.p12/.pfxfile containing the cert chain and key (common in enterprise / Windows shops).
- PEM: text-encoded
- A cloud secret store containing the certificate. Either AWS Secrets Manager or Azure Key Vault. Your platform admin has typically already configured the ExternalSecrets
SecretStoreresource that points at it. - DNS control for the hostname you must be able to create a CNAME (or A/AAAA) record pointing your custom hostname at the gateway's load balancer.
How It Fits Together
┌──────────────────────┐ references ┌──────────────────────┐
│ PlatformApplication │ ─────────────────▶│ Cloud Secret Store │
│ spec.networking. │ │ (Azure Key Vault) │
│ ingress.certificate │ │ via a pre-existing │
│ │ │ ESO SecretStore │
└──────────────────────┘ └──────────────────────┘
│ │
│ operator generates │ ESO pulls secret
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ ExternalSecret │ ─── creates ────▶ │ Kubernetes Secret │
│ │ │ (tls.crt / tls.key) │
└──────────────────────┘ └──────────────────────┘
│
│ bound to
▼
┌──────────────────────┐
│ Gateway listener │
│ (Gateway API) │
└──────────────────────┘
The operator creates the ExternalSecret and configures the Gateway listener to bind the resulting Kubernetes Secret. The SecretStore is not created by the operator — your platform admin sets it up once, and many PlatformApplications reference it. You supply the source secret in your cloud secret store and the PlatformApplication config.
Step 1: Store the Certificate in Your Cloud Secret Store
Place the certificate in your cloud secret store under a name you'll reference from the PlatformApplication.
- Azure Key Vault
- AWS Secrets Manager
Upload the certificate directly into the Key Vault's Certificates section using your preferred tool (Azure Portal, az keyvault certificate import, Terraform, etc.). Key Vault accepts the cert in its native form, so no JSON wrapping or manual key/cert splitting is required:
- PEM bundle (
.pem/.crtcontaining both certificate chain and private key) — uploaded as-is. - PKCS#12 (
.p12/.pfx) — uploaded as-is. If the bundle is passphrase-protected, supply the password at import time so Key Vault stores the cert in an accessible form.
The SecretStore your admin configured for the namespace knows how to pull this certificate object and present it to ExternalSecrets in the format you request (pem or pkcs12) on the PlatformApplication.
The bring-your-own-certificate path via AWS Secrets Manager has not been validated by the platform team. If you're targeting an AWS cluster and need a custom certificate, coordinate with your platform admin before going further — the recommended approach and any helper tooling are still being defined.
For broader guidance on storing secrets in your cloud provider, see External Secrets Configuration.
Step 2: Reference the Certificate from PlatformApplication
Add spec.networking.ingress.hostnames[] and spec.networking.ingress.certificate to your PlatformApplication:
apiVersion: meta.p6m.dev/v1alpha1
kind: PlatformApplication
metadata:
name: demo-http-echo
namespace: demo-http-echo
spec:
deployment:
image: mendhak/http-https-echo:31
ports:
- port: 8080
protocol: http
networking:
ingress:
enabled: true
gateway: public-open
hostnames:
- app.example.com # NEW: custom hostname
certificate: # NEW: where to find the cert
externalSecret:
secretStore: corp-secrets # name of an existing SecretStore in the cluster
secretName: app-example-com-tls
format: pem
Field reference:
| Field | Purpose |
|---|---|
hostnames[] | FQDNs to register on the gateway. The default platform-generated hostname is replaced when this is set. |
certificate.externalSecret.secretStore | Name of an existing ExternalSecrets SecretStore (your admin sets these up — one per cloud account / region). |
certificate.externalSecret.secretName | Name of the secret inside the cloud provider (Secrets Manager / Key Vault). |
certificate.externalSecret.format | pem or pkcs12 — must match how the secret was stored. |
If the certificate already lives in a Kubernetes Secret in the cluster (typically only when another tool manages it), use secretRef instead of externalSecret:
certificate:
secretRef:
name: app-example-com-tls
# namespace: defaults to the application's namespace
For complete schema, see PlatformApplication Reference → certificate.
Example Scenarios
Single domain
The simplest case one application, one custom hostname, one certificate covering that hostname:
networking:
ingress:
enabled: true
gateway: public-open
hostnames:
- api.example.com
certificate:
externalSecret:
secretStore: corp-secrets
secretName: api-example-com-tls
format: pem
The certificate's subjectAltName (SAN) must include api.example.com.
Wildcard certificate
Use a wildcard when several applications under the same parent domain share one cert (e.g. *.example.com):
networking:
ingress:
enabled: true
gateway: public-open
hostnames:
- billing.example.com
certificate:
externalSecret:
secretStore: corp-secrets
secretName: wildcard-example-com-tls
format: pem
The same wildcard-example-com-tls secret can be referenced by any PlatformApplication whose hostnames[] falls under *.example.com. The certificate's SAN must include *.example.com.
Multiple hostnames (multi-SAN certificate)
A single application reachable at multiple hostnames, for example a primary domain plus its alias needs one certificate with all hostnames in its SAN list:
networking:
ingress:
enabled: true
gateway: public-open
hostnames:
- auth.example.com
- login.example.com
certificate:
externalSecret:
secretStore: corp-secrets
secretName: auth-example-com-tls
format: pem
The certificate's SAN must include every entry in hostnames[]. If any hostname isn't covered, browsers will show a TLS mismatch error when reaching the app on that name.
Internal-only hostname
For applications that should resolve and serve traffic only inside the corporate network, combine hostnames[] with internal: true and a non-public gateway:
networking:
ingress:
enabled: true
gateway: internal-open
internal: true
hostnames:
- admin.internal.example.com
certificate:
externalSecret:
secretStore: corp-secrets
secretName: admin-internal-example-com-tls
format: pem
Step 3: Point DNS at the Gateway
Once the manifest is applied and the resources reconcile:
- Find the gateway's external address.
kubectl get gateway -A
# or, for the load balancer service backing the gateway:
kubectl get svc -n istio-ingress - Create a CNAME (or A/AAAA) record at your DNS provider pointing your custom hostname at the gateway's hostname/IP.
The platform does not create DNS records for custom hostnames automatically, only for the default platform-generated hostname. This is intentional: DNS for your domain lives in your zone, not the platform's.
Verifying
After DNS has propagated:
# Confirm the secret has been pulled into the namespace
kubectl get externalsecret,secret -n demo-http-echo
# Confirm the HTTPRoute lists your custom hostname
kubectl get httproute -n demo-http-echo -o jsonpath='{.items[*].spec.hostnames}'
# Test TLS end-to-end and verify the cert chain
curl -v https://app.example.com 2>&1 | grep -E 'subject:|issuer:|SSL connection'
Common Pitfalls
- Hostname not in the cert's SAN. Browsers and
curlwill reject the connection with a name-mismatch error. Fix by reissuing the certificate to include the hostname, or use a wildcard cert. - Wrong
format. A PKCS#12 secret withformat: pem(or vice versa) leaves the gateway without a usable certificate,kubectl describe externalsecretshows the parse failure. SecretStorenot in the application namespace.externalSecret.secretStoremust reference aSecretStore(orClusterSecretStore) that the application's namespace can reach. If unsure which one to use, ask your platform admin.- DNS pointing somewhere else. A CNAME left over from a previous host will silently serve the wrong app or fail TLS. Verify with
dig +short app.example.com. - Forgetting to renew. The platform consumes whatever is in the secret store. If your CA rotates the cert, you (or your automation) must update the secret in Secrets Manager / Key Vault — the platform will pick up the new value within the ExternalSecrets sync interval.
Related Documentation
- Ingress Configuration Tutorial — the walkthrough lesson this guide extends
- Ingress - Details — gateway selection, path routing, advanced ingress options
- External Secrets Configuration — creating secrets in your cloud provider
- PlatformApplication Reference → certificate — full CRD schema
- cert-manager Documentation — background on Kubernetes certificate management