--- title: "Enabling HTTPS for PAA Services" slug: "enabling-https-for-paa-services" updated: 2026-08-23T16:07:47Z published: 2026-08-23T16:07:47Z canonical: "docs.plainid.io/enabling-https-for-paa-services" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.plainid.io/llms.txt > Use this file to discover all available pages before exploring further. # Enabling HTTPS for PAA Services This guide covers how to secure the connections between the services running in your PAA, Agent, Platform Internal Information Point (PIIP), Runtime, Secret Management, and the IDP webhook, with native HTTPS. It's divided into the following sections: - **How HTTPS works between your PAA services** - What gets encrypted when you turn this on, and how certificates get to each service. - **Enabling HTTPS in Kubernetes** - The three ways to supply certificates: chart-generated, your own PKI, or cert-manager. - **Enabling HTTPS in ECS** - The single flag that turns on HTTPS pack-wide, and how to bring your own certificates instead. - **What HTTPS doesn't cover** - The two connections this setting doesn't encrypt, and what to do if you need them encrypted too. ## How HTTPS works between your PAA services By default, the services in your PAA, Agent, PIIP, Runtime, Secret Management, and the IDP webhook call each other over plain HTTP inside your cluster or VPC. Enabling HTTPS puts TLS directly on each service's own port. There's no proxy, sidecar, or mesh in between: each service terminates TLS itself, using a certificate issued to it and a shared CA that every service trusts. Because it's in-cluster or in-VPC traffic, everything runs on your existing service discovery, Kubernetes Service DNS or ECS Cloud Map, with no public endpoint involved. So, you don't need a load balancer, a public certificate, or a DNS zone for this. All certificates trace back to one internal CA shared by every service. How that CA and the individual service certificates get created is the one part that differs between Kubernetes and ECS, which is covered below. ## Enabling HTTPS in Kubernetes Each service has its own `ssl.enabled` flag in your Helm values, so you can enable HTTPS for the whole PAA or just the services you deploy. See the HTTPS subsection on each service's page for the exact key. You choose how certificates get created: - **Chart-generated (development).** Set `ssl.generate: true` alongside `ssl.enabled: true`. The chart mints a shared self-signed CA and a leaf certificate per service, and creates the Kubernetes Secrets for you. Nothing else to set up. Certificates persist across `helm upgrade`, so they don't rotate on every release. > **This mode isn't intended for production.** - **Your own certificates (BYO PKI).** Set `ssl.enabled: true` and create the Secrets yourself: a `kubernetes.io/tls` Secret per service (`tls.crt` + `tls.key`) and a shared CA Secret (`ca.crt`) that every service trusts via `caSecret`. Each service certificate needs the in-cluster DNS SANs for that service. Use `ssl.existingSecret` to point at a Secret name of your choosing. - **cert-manager.** If cert-manager is already running in your cluster, it can issue and rotate every certificate automatically, including a Job that syncs the CA into the shared CA Secret, in a single `helm install`. > **This is the recommended production path if you run cert-manager.** Whichever mode you use, the chart handles the certificate mounts, truststore setup, health probe scheme, and inter-service URLs on its own. You only ever set `ssl.enabled` (and, depending on mode, `ssl.generate` or `ssl.existingSecret`/`caSecret`). ## Enabling HTTPS in ECS ECS uses a single pack-wide flag: ``` enable_https = true ``` This turns on HTTPS across every service in your PAA simultaneously. There's no per-service flag on ECS. The pack generates an internal CA and a certificate per service, stages them into each task, and switches inter-service URLs to `https://` over Cloud Map. To bring your own certificates instead of the pack-generated ones, set `tls.mode = "byo_certs"` and supply your certificate, key, and CA. Run `terraform output tls_required_sans` first to get the exact SANs each certificate needs. Use the `*_ssm_arn` inputs to keep private keys out of Terraform state. If your organization has other internal CAs that PAA services need to trust alongside the PlainID-issued ones, `tls.extra_trust_ca_pems` adds them to every service's truststore, in either mode. ## Enabling HTTPS in Standalone Standalone deployments use a single environment variable: ``` export PLAINID_TLS_ENABLED=true start_plainid_paa ``` On startup, `start_plainid_paa` generates a self-signed CA and a certificate per covered service under `/opt/plainid/security/tls`, unless certificates already exist there. Certificates are reused across restarts. They aren't rotated automatically. It then points each service at its certificate and keystore, adds the CA to the JVM truststore for outbound calls, and switches the affected inter-service URLs to `https://`. Two environment variables let you override the defaults: - `PLAINID_TLS_DIR`: where certificates are read from and written to (default `/opt/plainid/security/tls`). - `PLAINID_TLS_KEYSTORE_PW`: the PKCS12 keystore password. To use your own PKI instead of the generated self-signed certs, place your CA and per-service keys under `PLAINID_TLS_DIR` in the same layout the generator produces before starting. The generator only fills in what's missing, so it won't overwrite certificates that are already there. ## What HTTPS doesn't cover Two connections stay outside this setting: - **Redis**, when running in-cluster (the default). The in-cluster Redis instance isn't reachable from outside your cluster or VPC, so it's not exposed the way service-to-service traffic is. If you need Redis traffic itself encrypted, move to an external Redis (`redis_mode = "external"` on ECS) and enable TLS there. - **Runtime's JDBC connection to PIP**, on port 31350. This leg isn't encrypted by `enable_https` or `ssl.enabled`. If you need it encrypted, terminate TLS at the data source instead. *Note: this capability provides one-way TLS only. It does not provide mutual TLS (mTLS).*