Skip to content

Commit 9ff3b69

Browse files
feat: enhance WAF deployment with private backend access, update ingress configurations, and improve deployment documentation
1 parent 7d44cb9 commit 9ff3b69

7 files changed

Lines changed: 72 additions & 76 deletions

File tree

App/frontend-app/src/components/documentViewer/iFrameComponent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function IFrameComponent({ className, metadata, urlWithSasToken, iframeKe
3636
);
3737
}
3838
case "application/pdf": {
39-
const url = new URL(urlWithSasToken);
39+
const url = new URL(urlWithSasToken, window.location.origin);
4040
url.searchParams.append("embed", "True");
4141

4242
return <iframe title="PDF Viewer" key={iframeKey} src={url.toString()} width="100%" height="100%" />;

App/frontend-app/vite.config.ts

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
1-
import { defineConfig } from "vite";
1+
import { defineConfig, loadEnv } from "vite";
22
import react from "@vitejs/plugin-react";
33
import postcss from "./postcss.config.js";
44

5-
export default defineConfig({
6-
plugins: [react()],
7-
css: {
8-
postcss,
9-
},
10-
server: {
11-
watch: {
12-
usePolling: true,
5+
export default defineConfig(({ mode }) => {
6+
const env = loadEnv(mode, process.cwd(), '');
7+
const backendTarget = env.BACKEND_PROXY_TARGET || 'http://aiservice-service:80';
8+
9+
return {
10+
plugins: [react()],
11+
css: {
12+
postcss,
13+
},
14+
server: {
15+
watch: {
16+
usePolling: true,
17+
},
18+
host: true,
19+
strictPort: true,
20+
port: 5900,
21+
allowedHosts: true,
22+
proxy: {
23+
'/backend': {
24+
target: backendTarget,
25+
changeOrigin: true,
26+
rewrite: (path: string) => path.replace(/^\/backend/, ''),
27+
},
28+
'/api': {
29+
target: backendTarget,
30+
changeOrigin: true,
31+
},
32+
},
1333
},
14-
host: true,
15-
strictPort: true,
16-
port : 5900,
17-
allowedHosts: true
18-
}
34+
};
1935
});

Deployment/kubernetes/deploy.ingress.internal.yaml.template

Lines changed: 0 additions & 26 deletions
This file was deleted.

Deployment/kubernetes/deploy.ingress.waf.yaml.template

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@ spec:
2424
- host: {{ fqdn }}
2525
http:
2626
paths:
27-
- path: /backend(/|$)(.*)
28-
pathType: Prefix
29-
backend:
30-
service:
31-
name: aiservice-service
32-
port:
33-
number: 9001
3427
- path: /()(.*)
3528
pathType: Prefix
3629
backend:

Deployment/kubernetes/deploy.networkpolicy.yaml.template

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# NetworkPolicy to restrict backend services (aiservice, kernelmemory) to only
2-
# accept traffic from within the cluster — frontend pods and internal ingress.
3-
# This ensures backend APIs are not directly accessible from the public internet
4-
# when WAF deployment mode is enabled.
2+
# accept traffic from authorized pods within the cluster.
3+
# Frontend (frontapp) and aiservice can reach backend; external traffic is blocked.
4+
# Applied automatically in WAF deployment mode.
55
---
66
apiVersion: networking.k8s.io/v1
77
kind: NetworkPolicy
@@ -19,16 +19,18 @@ spec:
1919
policyTypes:
2020
- Ingress
2121
ingress:
22-
# Allow traffic from frontend pods in the same namespace
22+
# Allow traffic from frontend pods (Vite proxy forwards API calls to aiservice)
2323
- from:
2424
- podSelector:
2525
matchLabels:
2626
app: frontapp
27+
# Allow traffic from aiservice to kernelmemory (inter-service communication)
28+
- from:
29+
- podSelector:
30+
matchLabels:
31+
app: aiservice
2732
# Allow traffic from ingress controller namespace (app-routing-system)
2833
- from:
2934
- namespaceSelector:
3035
matchLabels:
3136
kubernetes.io/metadata.name: app-routing-system
32-
# Allow traffic from within the ns-km namespace (inter-service communication)
33-
- from:
34-
- podSelector: {}

Deployment/resourcedeployment.ps1

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -964,8 +964,16 @@ try {
964964
# Front App
965965
###############################
966966

967-
$frontAppConfigServicePlaceholders = @{
968-
'{{ backend-fqdn }}' = "https://${fqdn}/backend"
967+
# WAF mode: use relative path so browser calls go through frontend Vite proxy (backend stays private)
968+
# Standard mode: use absolute URL (backend is on public ingress)
969+
if ($isWafDeployment) {
970+
$frontAppConfigServicePlaceholders = @{
971+
'{{ backend-fqdn }}' = "/backend"
972+
}
973+
} else {
974+
$frontAppConfigServicePlaceholders = @{
975+
'{{ backend-fqdn }}' = "https://${fqdn}/backend"
976+
}
969977
}
970978

971979
## Load and update the front app configuration template
@@ -1025,19 +1033,17 @@ try {
10251033
kubectl apply -f "./kubernetes/deploy.service.yaml" -n $kubenamespace
10261034

10271035
# 5.5. Deploy Ingress Controller in Kubernetes for external access
1028-
kubectl apply -f "./kubernetes/deploy.ingress.yaml" -n $kubenamespace
1029-
1030-
# 5.6. WAF Mode: Deploy internal backend ingress and network policies
10311036
if ($isWafDeployment) {
1032-
Write-Host "Applying WAF-specific configurations: internal backend ingress and network policies..." -ForegroundColor Cyan
1033-
1034-
# Deploy internal ingress for backend services (no public exposure)
1035-
kubectl apply -f "./kubernetes/deploy.ingress.internal.yaml.template" -n $kubenamespace
1037+
# WAF mode: use WAF ingress (no public backend route — backend traffic proxied through frontend)
1038+
Write-Host "Applying WAF-specific ingress (backend is private, proxied through frontend)..." -ForegroundColor Cyan
1039+
kubectl apply -f "./kubernetes/deploy.ingress.yaml" -n $kubenamespace
10361040

1037-
# Deploy network policies to restrict backend traffic to internal only
1041+
# Deploy network policies to restrict direct backend pod access
10381042
kubectl apply -f "./kubernetes/deploy.networkpolicy.yaml.template" -n $kubenamespace
1039-
1040-
Write-Host "WAF network policies and internal backend ingress applied successfully." -ForegroundColor Green
1043+
Write-Host "WAF ingress and network policies applied successfully." -ForegroundColor Green
1044+
} else {
1045+
# Standard mode: public ingress with backend route
1046+
kubectl apply -f "./kubernetes/deploy.ingress.yaml" -n $kubenamespace
10411047
}
10421048

10431049
# #####################################################################

docs/DeploymentGuide.md

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,24 @@ azd env set AZURE_ENV_VM_ADMIN_PASSWORD <your-password>
150150
151151
When deploying with WAF configuration (`enablePrivateNetworking: true`), the following security measures are applied:
152152

153-
- **AKS Private Cluster**: The AKS API server is configured as a private cluster, not accessible from the public internet.
154-
- **Frontend-Only Public Ingress**: Only the frontend web application is exposed publicly through the WAF/Application Gateway ingress. The `/backend` API route is removed from the public ingress.
155-
- **Internal Backend Ingress**: Backend API services (`aiservice`, `kernelmemory`) are accessible only through an internal ingress that is not exposed to the public internet.
156-
- **Kubernetes Network Policies**: NetworkPolicy resources enforce traffic isolation — backend pods only accept traffic from frontend pods and the internal ingress controller within the cluster.
153+
- **Public Ingress (Frontend Only)**: Only the frontend web application is exposed through the public nginx ingress. **No backend API routes are on the public ingress** — backend services are completely private.
154+
- **Server-Side Proxy**: The frontend container (Vite) acts as a reverse proxy. Browser API calls to `/backend` are intercepted by the frontend server and forwarded internally to the backend service via ClusterIP DNS — the request never leaves the cluster.
155+
- **ClusterIP Services**: Backend services (`aiservice`, `kernelmemory`) use ClusterIP services for internal communication only. They have no public IP or external load balancer.
156+
- **Kubernetes Network Policies**: NetworkPolicy resources enforce traffic isolation — backend pods only accept traffic from frontend pods and the ingress controller within the cluster.
157157
- **Private Endpoints**: All Azure PaaS services (Cosmos DB, Storage, Search, OpenAI, etc.) use private endpoints and are not accessible from the public internet.
158158

159159
**Traffic Flow (WAF mode):**
160160
```
161-
Internet → WAF/Application Gateway → Public Ingress → Frontend (frontapp)
162-
↓ (internal)
163-
Backend (aiservice) → Azure PaaS (via Private Endpoints)
164-
↓ (internal)
165-
Kernel Memory Service → Azure PaaS (via Private Endpoints)
161+
Internet → Public Ingress (nginx) → / → Frontend (frontapp:5900)
162+
163+
Vite Proxy (server-side)
164+
/backend → aiservice (ClusterIP, internal only)
165+
/api → aiservice (ClusterIP, internal only)
166+
167+
Azure PaaS (via Private Endpoints)
168+
169+
Backend API from internet → NOT ROUTABLE (no public ingress route exists)
170+
Direct access to backend pods → BLOCKED by NetworkPolicy
166171
```
167172

168173
### 3.4 Advanced Configuration (Optional)

0 commit comments

Comments
 (0)