|
| 1 | +# Secure AKS reference (TLS + SSO) |
| 2 | + |
| 3 | +Production-shaped templates for deploying Interbox on **AKS** with the dashboard |
| 4 | +behind an **internal ingress-nginx**, **cert-manager** TLS, and **Entra ID** SSO. |
| 5 | + |
| 6 | +> **These are templates, not a verified one-command deploy.** They depend on your |
| 7 | +> Azure resources (DNS zone, Entra tenant, managed Postgres, workload identity), so |
| 8 | +> they can't be exercised end-to-end here. Fill every `<placeholder>` and validate |
| 9 | +> in a staging cluster. The **[k3d reference](../k3d/)** is the runnable, verified |
| 10 | +> version of the same architecture — start there to see it work. |
| 11 | +
|
| 12 | +Same architecture as k3d; the swaps are: internal LB, cert-manager real issuer, |
| 13 | +Entra ID (not Dex), managed Postgres. |
| 14 | + |
| 15 | +## Prerequisites |
| 16 | + |
| 17 | +- An **AKS** cluster with **workload identity** enabled. |
| 18 | +- **ingress-nginx** installed *internal* — `helm install ingress-nginx |
| 19 | + ingress-nginx/ingress-nginx -n ingress-nginx --create-namespace -f |
| 20 | + ingress-nginx.values.yaml` (gives its LB a private IP). |
| 21 | +- **cert-manager** installed (`--set crds.enabled=true`). |
| 22 | +- **Azure Database for PostgreSQL Flexible Server** reachable privately. Allowlist |
| 23 | + the extensions Interbox needs — set the server parameter |
| 24 | + **`azure.extensions = PG_TRGM,BTREE_GIST`** — *before* first boot, or the schema |
| 25 | + migration fails. |
| 26 | +- An **Entra ID app registration** for the dashboard (below). |
| 27 | +- Interbox needs **outbound** access to your workspace repo and Aidbox; for the |
| 28 | + **FHIR-poll** path, pin the cluster's **NAT-gateway egress IP** so upstreams |
| 29 | + (e.g. Epic) can allowlist it. |
| 30 | + |
| 31 | +## 1. TLS issuer — pick one |
| 32 | + |
| 33 | +- **Public DNS zone (recommended)** → `kubectl apply -f clusterissuer-dns01.yaml`. |
| 34 | + cert-manager gets auto-renewing, publicly-trusted certs via Azure DNS DNS-01 — |
| 35 | + works even when the host's A record is a private IP. Federate the cert-manager |
| 36 | + service account with a managed identity that has *DNS Zone Contributor*. |
| 37 | +- **Private-DNS-only host** → `kubectl apply -f clusterissuer-internal-ca.yaml` and |
| 38 | + set `ingress.annotations.cert-manager.io/cluster-issuer: internal-ca` in |
| 39 | + `values.yaml`. Distribute the CA to clients. |
| 40 | + |
| 41 | +## 2. Entra ID app + secret |
| 42 | + |
| 43 | +1. Entra ID → App registrations → New. Add a **Web** redirect URI: |
| 44 | + `https://<host>/oauth2/callback`. |
| 45 | +2. Certificates & secrets → new **client secret**. |
| 46 | +3. Create the secret oauth2-proxy reads: |
| 47 | + |
| 48 | + ```sh |
| 49 | + kubectl create secret generic oauth2-proxy-secret \ |
| 50 | + --from-literal=client-id=<entra-app-client-id> \ |
| 51 | + --from-literal=client-secret=<entra-client-secret> \ |
| 52 | + --from-literal=cookie-secret=$(openssl rand -hex 16) |
| 53 | + ``` |
| 54 | + |
| 55 | +## 3. Deploy the gate + Interbox |
| 56 | + |
| 57 | +```sh |
| 58 | +# fill <tenant-id> and <host> in oauth2-proxy.yaml first |
| 59 | +kubectl apply -f oauth2-proxy.yaml |
| 60 | + |
| 61 | +helm repo add healthsamurai https://healthsamurai.github.io/helm-charts |
| 62 | +helm upgrade --install interbox healthsamurai/interbox -f values.yaml # fill placeholders first |
| 63 | +``` |
| 64 | + |
| 65 | +## 4. Verify |
| 66 | + |
| 67 | +```sh |
| 68 | +# unauthenticated -> 302 to the Entra login |
| 69 | +curl -sk -o /dev/null -D - https://<host>/api/messages | grep -iE '^HTTP|^location' |
| 70 | +# cert issued + trusted (DNS-01) or CA-signed (internal CA) |
| 71 | +echo | openssl s_client -connect <host>:443 -servername <host> 2>/dev/null | openssl x509 -noout -issuer |
| 72 | +``` |
| 73 | + |
| 74 | +Then browse `https://<host>/`, authenticate with Entra ID, land on the dashboard. |
| 75 | + |
| 76 | +## Files |
| 77 | + |
| 78 | +| File | Purpose | |
| 79 | +| ---- | ------- | |
| 80 | +| `values.yaml` | Interbox chart values: internal ingress + TLS + SSO annotations + internal MLLP LB | |
| 81 | +| `ingress-nginx.values.yaml` | install ingress-nginx as an *internal* controller | |
| 82 | +| `clusterissuer-dns01.yaml` | **primary** TLS issuer (Azure DNS DNS-01) | |
| 83 | +| `clusterissuer-internal-ca.yaml` | alternative TLS issuer (private-DNS-only) | |
| 84 | +| `oauth2-proxy.yaml` | SSO gate wired to Entra ID | |
| 85 | + |
| 86 | +Concepts: the docs' **Operations → Securing Dashboard Access**. |
0 commit comments