CONFIGURATION
Exactly what's running, and how it's locked down
Every setting below is real, drawn from this environment's
Bicep and Kubernetes manifests — nothing hypothetical.
01TLS
| Issuer | Let's Encrypt, via cert-manager |
| Challenge type | ACME HTTP-01 (domain-ownership proof over plain HTTP) |
| Renewal | Automatic — cert-manager renews before expiry, no manual step |
| Termination point | Application Gateway (not the pod — nginx never sees the private key) |
02Identity & access
| AKS API server | Private — no public IP, no static kubeconfig cert |
| Cluster auth | Microsoft Entra ID + Azure RBAC for Kubernetes authorization |
| ACR access | AcrPull on the node's kubelet managed identity — no admin user, no stored credential |
| CI/CD auth | GitHub Actions → Azure via OIDC federated credentials |
03Pod security
| User | non-root (runAsNonRoot: true) |
| Filesystem | read-only root filesystem |
| Capabilities | all Linux capabilities dropped |
| Privilege escalation | disabled |
| Seccomp | RuntimeDefault |
04Network policy (default-deny)
- All ingress and egress denied by default in the
demo-web namespace
- Ingress allowed only from the Application Gateway subnet, on the app's container port
- Ingress allowed for the
cert-manager ACME solver pod, same source, while a certificate is being issued or renewed
- Egress allowed only for DNS — this is a static site, it needs nothing else outbound
05Scaling
| Baseline replicas | 2 |
| Autoscale range | 2 – 5 replicas |
| Scale trigger | CPU utilization > 70% |
06Observability
- AKS + ACR diagnostics flow into a shared Log Analytics Workspace
- Microsoft Defender for Containers enabled on the cluster
- Azure Policy add-on enforces platform-wide compliance policies on the node pools