|
| 1 | +# Zero-Trust Architecture with Istio mTLS |
| 2 | + |
| 3 | +This document describes the implementation of a Zero-Trust security model using Istio service mesh with mutual TLS (mTLS) authentication for the LeaseFlow Protocol Backend. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The Zero-Trust architecture ensures that: |
| 8 | +- All pod-to-pod communication is encrypted and mutually authenticated |
| 9 | +- Network policies block all unencrypted traffic |
| 10 | +- Database connections enforce strict TLS with certificate verification |
| 11 | +- Lateral movement by attackers is structurally blocked |
| 12 | + |
| 13 | +## Architecture Components |
| 14 | + |
| 15 | +### 1. Istio Service Mesh |
| 16 | + |
| 17 | +Istio provides the foundational infrastructure for Zero-Trust: |
| 18 | +- **Sidecar Proxies**: Automatically injected into all pods to handle mTLS |
| 19 | +- **Control Plane**: Manages certificate issuance and rotation |
| 20 | +- **Ingress/Egress Gateways**: Secure entry/exit points for cluster traffic |
| 21 | + |
| 22 | +### 2. Mutual TLS (mTLS) |
| 23 | + |
| 24 | +All internal communication uses mTLS: |
| 25 | +- **Strict Mode**: All services require mTLS (no plaintext fallback) |
| 26 | +- **Automatic Certificate Management**: Istio handles cert issuance and rotation |
| 27 | +- **Service Identity**: Each service has a unique identity based on Kubernetes ServiceAccount |
| 28 | + |
| 29 | +### 3. Network Policies |
| 30 | + |
| 31 | +Kubernetes Network Policies enforce network-level restrictions: |
| 32 | +- **Default Deny**: All traffic is blocked by default |
| 33 | +- **Explicit Allow**: Only specific service-to-service paths are permitted |
| 34 | +- **Istio Sidecar Enforcement**: Traffic must flow through Istio sidecars |
| 35 | + |
| 36 | +### 4. Database Security |
| 37 | + |
| 38 | +PostgreSQL connections enforce strict TLS: |
| 39 | +- **sslmode=verify-full**: Requires valid client certificates |
| 40 | +- **Certificate Validation**: Pods must present valid certs to connect |
| 41 | +- **Encrypted Transport**: All database traffic is encrypted |
| 42 | + |
| 43 | +## Installation Steps |
| 44 | + |
| 45 | +### Prerequisites |
| 46 | + |
| 47 | +- Kubernetes cluster (v1.24+) |
| 48 | +- kubectl configured for cluster access |
| 49 | +- Helm 3.x installed |
| 50 | +- Cluster admin permissions |
| 51 | + |
| 52 | +### Step 1: Install Istio |
| 53 | + |
| 54 | +```bash |
| 55 | +# Download Istio |
| 56 | +curl -L https://istio.io/downloadIstio | sh - |
| 57 | +cd istio-* |
| 58 | + |
| 59 | +# Install Istio with custom configuration |
| 60 | +istioctl install -f k8s/istio-installation.yaml |
| 61 | + |
| 62 | +# Verify installation |
| 63 | +istioctl verify-install |
| 64 | +``` |
| 65 | + |
| 66 | +### Step 2: Enable Istio Injection |
| 67 | + |
| 68 | +The default namespace is already labeled for injection in the manifest: |
| 69 | + |
| 70 | +```bash |
| 71 | +kubectl get namespace default -o yaml |
| 72 | +# Should show: istio-injection: enabled |
| 73 | +``` |
| 74 | + |
| 75 | +### Step 3: Apply mTLS Policies |
| 76 | + |
| 77 | +```bash |
| 78 | +# Apply PeerAuthentication resources (strict mTLS) |
| 79 | +kubectl apply -f k8s/istio-mtls-policies.yaml |
| 80 | + |
| 81 | +# Apply DestinationRules for mTLS routing |
| 82 | +kubectl apply -f k8s/istio-mtls-policies.yaml |
| 83 | +``` |
| 84 | + |
| 85 | +### Step 4: Apply Network Policies |
| 86 | + |
| 87 | +```bash |
| 88 | +# Apply strict network policies |
| 89 | +kubectl apply -f k8s/network-policies.yaml |
| 90 | +``` |
| 91 | + |
| 92 | +### Step 5: Apply Authorization Policies |
| 93 | + |
| 94 | +```bash |
| 95 | +# Apply service-to-service authorization rules |
| 96 | +kubectl apply -f k8s/istio-authorization-policies.yaml |
| 97 | +``` |
| 98 | + |
| 99 | +### Step 6: Update Application Configuration |
| 100 | + |
| 101 | +Update your Helm chart values or ConfigMaps to include database TLS configuration: |
| 102 | + |
| 103 | +```yaml |
| 104 | +# In values.yaml or ConfigMap |
| 105 | +database: |
| 106 | + postgresql: |
| 107 | + sslmode: "verify-full" |
| 108 | + ssl: "true" |
| 109 | + sslca: "/etc/ssl/certs/ca.crt" |
| 110 | + sslcert: "/etc/ssl/certs/client.crt" |
| 111 | + sslkey: "/etc/ssl/certs/client.key" |
| 112 | +``` |
| 113 | +
|
| 114 | +### Step 7: Deploy Services |
| 115 | +
|
| 116 | +```bash |
| 117 | +# Deploy the application |
| 118 | +helm install leaseflow-backend ./k8s/charts/leaseflow-backend |
| 119 | + |
| 120 | +# Verify sidecar injection |
| 121 | +kubectl get pods -n default |
| 122 | +# Each pod should have 2/2 containers (app + istio-proxy) |
| 123 | +``` |
| 124 | + |
| 125 | +## Verification |
| 126 | + |
| 127 | +### Verify mTLS Status |
| 128 | + |
| 129 | +```bash |
| 130 | +# Check mesh-wide mTLS policy |
| 131 | +kubectl get peerauthentication -n istio-system |
| 132 | + |
| 133 | +# Check service-specific mTLS policies |
| 134 | +kubectl get peerauthentication -n default |
| 135 | + |
| 136 | +# Verify DestinationRules |
| 137 | +kubectl get destinationrule -n default |
| 138 | +``` |
| 139 | + |
| 140 | +### Verify Network Policies |
| 141 | + |
| 142 | +```bash |
| 143 | +# List network policies |
| 144 | +kubectl get networkpolicy -n default |
| 145 | + |
| 146 | +# Describe a specific policy |
| 147 | +kubectl describe networkpolicy leaseflow-backend-netpol -n default |
| 148 | +``` |
| 149 | + |
| 150 | +### Verify Authorization Policies |
| 151 | + |
| 152 | +```bash |
| 153 | +# List authorization policies |
| 154 | +kubectl get authorizationpolicy -n default |
| 155 | + |
| 156 | +# Check policy details |
| 157 | +kubectl describe authorizationpolicy backend-to-postgresql -n default |
| 158 | +``` |
| 159 | + |
| 160 | +### Verify Sidecar Injection |
| 161 | + |
| 162 | +```bash |
| 163 | +# Check pod containers |
| 164 | +kubectl get pods -n default -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' |
| 165 | + |
| 166 | +# Each pod should show both application container and istio-proxy |
| 167 | +``` |
| 168 | + |
| 169 | +### Test mTLS Communication |
| 170 | + |
| 171 | +```bash |
| 172 | +# Exec into a pod |
| 173 | +kubectl exec -it <pod-name> -n default -- /bin/sh |
| 174 | + |
| 175 | +# Test connection to another service (should use mTLS) |
| 176 | +curl -v http://leaseflow-backend-service:4000/health |
| 177 | + |
| 178 | +# Check Istio proxy logs |
| 179 | +kubectl logs <pod-name> -n default -c istio-proxy |
| 180 | +``` |
| 181 | + |
| 182 | +### Verify Database TLS |
| 183 | + |
| 184 | +```bash |
| 185 | +# Check database connection logs |
| 186 | +kubectl logs <backend-pod> -n default | grep -i ssl |
| 187 | + |
| 188 | +# Test connection with TLS verification |
| 189 | +kubectl exec -it <backend-pod> -n default -- psql "postgresql://user:pass@postgresql-service:5432/leaseflow?sslmode=verify-full" |
| 190 | +``` |
| 191 | + |
| 192 | +## Troubleshooting |
| 193 | + |
| 194 | +### Sidecar Not Injected |
| 195 | + |
| 196 | +**Symptom**: Pod has only 1 container instead of 2 |
| 197 | + |
| 198 | +**Solution**: |
| 199 | +```bash |
| 200 | +# Verify namespace label |
| 201 | +kubectl label namespace default istio-injection=enabled --overwrite |
| 202 | + |
| 203 | +# Restart pods |
| 204 | +kubectl rollout restart deployment/<deployment-name> |
| 205 | +``` |
| 206 | + |
| 207 | +### mTLS Connection Errors |
| 208 | + |
| 209 | +**Symptom**: 503 Service Unavailable or connection refused |
| 210 | + |
| 211 | +**Solution**: |
| 212 | +```bash |
| 213 | +# Check PeerAuthentication policies |
| 214 | +kubectl get peerauthentication -n default |
| 215 | + |
| 216 | +# Verify DestinationRules are applied |
| 217 | +kubectl get destinationrule -n default |
| 218 | + |
| 219 | +# Check Istio proxy logs |
| 220 | +kubectl logs <pod-name> -n default -c istio-proxy |
| 221 | +``` |
| 222 | + |
| 223 | +### Network Policy Blocking Traffic |
| 224 | + |
| 225 | +**Symptom**: Connection timeout or ECONNREFUSED |
| 226 | + |
| 227 | +**Solution**: |
| 228 | +```bash |
| 229 | +# Describe network policy |
| 230 | +kubectl describe networkpolicy <policy-name> -n default |
| 231 | + |
| 232 | +# Check pod labels match policy selectors |
| 233 | +kubectl get pods -n default --show-labels |
| 234 | + |
| 235 | +# Temporarily disable for debugging |
| 236 | +kubectl patch networkpolicy <policy-name> -n default -p '{"spec":{"policyTypes":["Ingress","Egress"]}}' |
| 237 | +``` |
| 238 | + |
| 239 | +### Database TLS Verification Failed |
| 240 | + |
| 241 | +**Symptom**: Connection refused or certificate verification error |
| 242 | + |
| 243 | +**Solution**: |
| 244 | +```bash |
| 245 | +# Verify certificate mounts |
| 246 | +kubectl describe pod <pod-name> -n default | grep -A 10 VolumeMounts |
| 247 | + |
| 248 | +# Check certificate paths in ConfigMap |
| 249 | +kubectl get configmap leaseflow-backend-config -n default -o yaml |
| 250 | + |
| 251 | +# Verify sslmode setting |
| 252 | +kubectl get configmap leaseflow-backend-config -n default -o yaml | grep sslmode |
| 253 | +``` |
| 254 | + |
| 255 | +## Security Best Practices |
| 256 | + |
| 257 | +### 1. Certificate Rotation |
| 258 | + |
| 259 | +Istio automatically rotates certificates every 90 days. Monitor: |
| 260 | + |
| 261 | +```bash |
| 262 | +# Check certificate expiration |
| 263 | +kubectl exec -it <pod-name> -n default -- /bin/sh |
| 264 | +istioctl proxy-config secret <pod-name>.default -o json |
| 265 | +``` |
| 266 | + |
| 267 | +### 2. Policy Auditing |
| 268 | + |
| 269 | +Regularly audit security policies: |
| 270 | + |
| 271 | +```bash |
| 272 | +# Export all policies for review |
| 273 | +kubectl get peerauthentication,authorizationpolicy,networkpolicy -n default -o yaml > security-policies.yaml |
| 274 | +``` |
| 275 | + |
| 276 | +### 3. Monitoring |
| 277 | + |
| 278 | +Enable Istio telemetry for security monitoring: |
| 279 | + |
| 280 | +```bash |
| 281 | +# Enable Prometheus metrics |
| 282 | +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.19/samples/addons/prometheus.yaml |
| 283 | + |
| 284 | +# Enable Grafana dashboards |
| 285 | +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.19/samples/addons/grafana.yaml |
| 286 | +``` |
| 287 | + |
| 288 | +### 4. Incident Response |
| 289 | + |
| 290 | +If a breach is detected: |
| 291 | + |
| 292 | +```bash |
| 293 | +# Immediately revoke compromised service identity |
| 294 | +kubectl delete serviceaccount <compromised-sa> |
| 295 | + |
| 296 | +# Restart affected pods to force new certificates |
| 297 | +kubectl rollout restart deployment/<deployment-name> |
| 298 | + |
| 299 | +# Review and tighten authorization policies |
| 300 | +kubectl edit authorizationpolicy <policy-name> -n default |
| 301 | +``` |
| 302 | + |
| 303 | +## Acceptance Criteria Verification |
| 304 | + |
| 305 | +### Acceptance 1: Zero-Trust Architectural Model |
| 306 | + |
| 307 | +**Verification**: |
| 308 | +```bash |
| 309 | +# Verify strict mTLS is enabled |
| 310 | +kubectl get peerauthentication -n istio-system -o yaml | grep mode: STRICT |
| 311 | + |
| 312 | +# Verify default-deny network policy exists |
| 313 | +kubectl get networkpolicy default-deny-all -n default |
| 314 | + |
| 315 | +# Verify all pods have sidecars |
| 316 | +kubectl get pods -n default -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' | grep istio-proxy |
| 317 | +``` |
| 318 | + |
| 319 | +### Acceptance 2: Encrypted and Authenticated Communication |
| 320 | + |
| 321 | +**Verification**: |
| 322 | +```bash |
| 323 | +# Check mTLS status between services |
| 324 | +istioctl authn tls-check <pod-name> -n default |
| 325 | + |
| 326 | +# Verify all services have PeerAuthentication |
| 327 | +kubectl get peerauthentication -n default |
| 328 | + |
| 329 | +# Verify DestinationRules enforce ISTIO_MUTUAL |
| 330 | +kubectl get destinationrule -n default -o yaml | grep mode: ISTIO_MUTUAL |
| 331 | +``` |
| 332 | + |
| 333 | +### Acceptance 3: Lateral Movement Blocked |
| 334 | + |
| 335 | +**Verification**: |
| 336 | +```bash |
| 337 | +# Verify network policies restrict traffic |
| 338 | +kubectl get networkpolicy -n default |
| 339 | + |
| 340 | +# Verify authorization policies enforce service-to-service access |
| 341 | +kubectl get authorizationpolicy -n default |
| 342 | + |
| 343 | +# Test unauthorized access (should fail) |
| 344 | +kubectl run test-pod --image=curlimages/curl -i --rm --restart=Never -- curl http://redis-service:6379 |
| 345 | +``` |
| 346 | + |
| 347 | +## References |
| 348 | + |
| 349 | +- [Istio Security Overview](https://istio.io/latest/docs/concepts/security/) |
| 350 | +- [Istio mTLS](https://istio.io/latest/docs/concepts/security/#mutual-tls-authentication) |
| 351 | +- [Kubernetes Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) |
| 352 | +- [PostgreSQL SSL Connection](https://www.postgresql.org/docs/current/libpq-ssl.html) |
| 353 | + |
| 354 | +## Support |
| 355 | + |
| 356 | +For issues or questions: |
| 357 | +1. Check Istio logs: `kubectl logs -n istio-system deployment/istiod` |
| 358 | +2. Check pod logs: `kubectl logs <pod-name> -n default -c istio-proxy` |
| 359 | +3. Review Istio dashboard: `istioctl dashboard` |
0 commit comments