Security
Security
This section covers additional security hardening for production deployments.
Security Overview
Zilla Platform includes Istio mTLS enabled by default for encrypted pod-to-pod communication.
For additional security hardening, consider the following features:
| Feature | Purpose | Status |
|---|---|---|
| Istio mTLS | Encrypts all pod-to-pod traffic | Enabled by default |
| Network Policies | Restricts pod communication | Optional (requires CNI support) |
| PostgreSQL SSL | Encrypts database connections | Optional (for external PostgreSQL) |
| Kafka SASL | Authenticates Kafka clients | Optional (for external Kafka) |
| Bootstrap Token Secret | Secures bootstrap credentials | Recommended |
Install Istio
Istio must be installed before deploying Zilla Platform. It is required for internal pod-to-pod mTLS.
# Add Istio Helm repository
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
# Create Istio namespace
kubectl create namespace istio-system
# Install Istio base (CRDs)
helm install istio-base istio/base -n istio-system --wait
# Install Istiod (control plane)
helm install istiod istio/istiod -n istio-system --wait
# Verify installation
kubectl get pods -n istio-systemExpected output:
NAME READY STATUS RESTARTS AGE
istiod-xxx 1/1 Running 0 1mThe umbrella chart configures Istio peer authentication via global.istio.mtls.mode, which defaults to STRICT. To change the mode, set it in values.yaml:
global:
istio:
mtls:
mode: STRICT # STRICT or PERMISSIVENote
STRICT mode enforces mTLS for all pod-to-pod traffic in the zilla-platform namespace. All Zilla Platform services support mTLS, so STRICT is the recommended setting for production deployments.
Network Policies
Network Policies are enabled by default (global.networkPolicies.enabled: true) and restrict which pods can communicate with each other.
To disable them, set the following in values.yaml:
global:
networkPolicies:
enabled: falsePrerequisites
EKS requires a CNI that supports NetworkPolicies. Install Calico:
kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/calico-operator.yaml
kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/calico-crs.yamlNote
If your cluster doesn't have a CNI that supports NetworkPolicies, the policies will be ignored (no effect) but won't cause errors.
External PostgreSQL with SSL
For production, use an external PostgreSQL database (e.g., Amazon RDS) with SSL enabled.
Create RDS PostgreSQL Instance
SG_ID=$(aws eks describe-cluster \
--name ${CLUSTER_NAME} \
--region ${AWS_REGION} \
--query 'cluster.resourcesVpcConfig.clusterSecurityGroupId' \
--output text)
aws rds create-db-instance \
--db-instance-identifier zilla-platform-db \
--db-instance-class db.t3.medium \
--engine postgres \
--master-username zilla_admin \
--master-user-password "YourSecurePassword" \
--allocated-storage 20 \
--vpc-security-group-ids ${SG_ID} \
--db-subnet-group-name your-subnet-group \
--storage-encrypted \
--enable-iam-database-authenticationCreate PostgreSQL Credentials Secret
Store the database credentials in a Kubernetes secret rather than inline in values.yaml:
kubectl create secret generic postgres-credentials \
-n zilla-platform \
--from-literal=username=zilla_admin \
--from-literal=password="YourSecurePassword"Update values.yaml
management:
db:
host: "zilla-platform-db.xxxxx.us-east-1.rds.amazonaws.com"
port: 5432
database: zilla
secretName: postgres-credentials
ssl:
enabled: true
mode: verify-full
postgres:
enabled: falseExternal Kafka with SASL
For production, use an external Kafka cluster (e.g., Amazon MSK) with SASL authentication.
Create Kafka Credentials Secret
kubectl create secret generic kafka-credentials \
-n zilla-platform \
--from-literal=username=kafka-user \
--from-literal=password=kafka-password \
--from-literal=jaas-config='org.apache.kafka.common.security.scram.ScramLoginModule required username="kafka-user" password="kafka-password";'Update values.yaml
control:
kafka:
enabled: false
security:
enabled: true
protocol: SASL_SSL
sasl:
mechanism: SCRAM-SHA-512
secretName: kafka-credentials
config:
kafkaBootstrapServers: "b-1.msk-cluster.xxxxx.kafka.us-east-1.amazonaws.com:9096"
connect:
kafkaBootstrapServers: "b-1.msk-cluster.xxxxx.kafka.us-east-1.amazonaws.com:9096"Bootstrap Token Secret
Store the bootstrap token in a Kubernetes Secret instead of passing it as a plain value.
kubectl create secret generic gateway-bootstrap-token \
-n <ENVIRONMENT_NAME> \
--from-literal=token="${BOOTSTRAP_TOKEN}"Deploy the environment referencing the secret:
helm install <ENVIRONMENT_NAME> oci://ghcr.io/aklivity/charts/zilla-platform-environment \
-n <ENVIRONMENT_NAME> \
-f environment-values.yaml \
--set bootstrapTokenSecret.name=gateway-bootstrap-token \
--set bootstrapTokenSecret.key=token \
--set platformURI="https://platform.${DOMAIN}" \
--set licenseKey="${ZILLA_PLATFORM_LICENSE_KEY}" \
--set kubernetes.distribution="eks"Production Deployment Example
Example Helm values for a production-ready Zilla Platform deployment.
values.yaml
global:
licenseKey: ""
domain: "<DOMAIN>"
jwt:
secretName: "zilla-platform-jwt"
ingress:
certificateArn: ""
kubernetes:
distribution: eks
istio:
mtls:
mode: STRICT
networkPolicies:
enabled: true
management:
db:
host: "zilla-platform-db.xxxxx.us-east-1.rds.amazonaws.com"
port: 5432
database: zilla
ssl:
enabled: true
mode: verify-full
secretName: postgres-credentials
postgres:
enabled: false
smtp:
host: "email-smtp.us-east-1.amazonaws.com"
port: "587"
fromAddress: "noreply@example.com"
control:
kafka:
enabled: false
security:
enabled: true
protocol: SASL_SSL
sasl:
mechanism: SCRAM-SHA-512
secretName: kafka-credentials
config:
kafkaBootstrapServers: "b-1.msk-cluster.xxxxx.kafka.us-east-1.amazonaws.com:9096"
connect:
kafkaBootstrapServers: "b-1.msk-cluster.xxxxx.kafka.us-east-1.amazonaws.com:9096"