Acceptance table¶
Status values: PASS / FAIL (executed, with actual evidence) and NOT RUN (not executed yet).
Fill in "Actual evidence" with what you observed. Paste the path of the evidence file in out/
when a script saved one. A PASS is runtime evidence only, not proof of Microsoft support.
Rows marked 2026-09-30 were executed while the lab was authored: offline or read-only only, and no Azure resources were created.
Lab-file validation and read-only checks (executed)¶
| ID | Requirement | Command | Expected evidence | Actual evidence | Status | Rollback |
|---|---|---|---|---|---|---|
| V-1 | Shell scripts are syntactically valid and lint-clean | scripts/validate-lab-files.sh |
bash -n OK; shellcheck -S style clean |
2026-09-30: all scripts pass bash -n (bash 3.2.57); shellcheck 0.11.0 clean at style level |
PASS | n/a |
| V-2 | Every manifest renders with no unresolved placeholder | same | "41 manifests rendered" | 2026-09-30: 41 files rendered | PASS | n/a |
| V-3 | YAML is well formed | same | yamllint clean | 2026-09-30: yamllint 1.38.0 clean | PASS | n/a |
| V-4 | Manifests match Kubernetes, Istio and Gateway API schemas | same (kubeconform + CRD catalog) | 0 invalid, 0 skipped | 2026-09-30: 73 resources found in 41 files - Valid: 73, Invalid: 0, Errors: 0, Skipped: 0 |
PASS | n/a |
| V-5 | CLI flags used exist | az <cmd> --help, istioctl <cmd> --help |
Every flag used appears in help | 2026-09-30: az 2.86.0 + appnet-preview 1.0.0b4; istioctl 1.30.5, all flags found | PASS | n/a |
| V-6 | Local tools check works | scripts/00-check-local-tools.sh |
Lists tools; fails if something is missing | 2026-09-30 (author machine): all tools found; correctly failed because appnet-preview isn't installed in the default CLI |
PASS (behaved as designed) | n/a |
| V-7 | Preflight is read-only and complete | scripts/01-preflight-azure.sh |
Region, CIDR, feature state, AKS versions, SKU, quota, roles | 2026-09-30: passed with 2 warnings (feature NotRegistered; list-versions skipped). eastus2 in both lists; K8s 1.35 GA; D4as_v7 available; quota 0/100; role Owner | PASS | n/a |
| V-8 | CIDR checker rejects bad plans | CIDR logic with seeded overlaps | Every seeded fault reported | 2026-09-30: detected pod/VNet overlap, reserved 172.30/16, oversized Service CIDR, subnet outside VNet | PASS | n/a |
Runtime acceptance (NOT RUN until you execute)¶
| ID | Requirement | Command | Expected evidence | Actual evidence | Status | Rollback |
|---|---|---|---|---|---|---|
| M1-1 | Preview registered with approval | 02-register-preview.sh (G1) |
Feature + provider Registered; list-versions table |
NOT RUN | Intentionally not undone | |
| M1-2 | Live AppNet ↔ AKS compatibility | 01-preflight-azure.sh after G1 |
Non-empty list-versions --kubernetes-version 1.35 |
NOT RUN | n/a | |
| M2-1 | VNets + bidirectional peering | 03-create-network.sh |
Both peerings Connected/FullyInSync |
NOT RUN | cleanup-2-azure.sh |
|
| M2-2 | Least-privilege cluster identities | 04-create-identities.sh |
Network Contributor scoped to subnet only | NOT RUN | cleanup-2-azure.sh |
|
| M2-3 | Clusters are CNI Overlay + Cilium, Entra ID, OIDC, Gateway API, public, no Istio add-on | 07-verify-clusters.sh |
All [ OK ]; no kube-proxy; CRDs managed-by: aks |
NOT RUN | recreate | |
| M2-4 | Cilium ambient-relevant settings recorded | 07-verify-clusters.sh |
out/cilium-ambient-compat.txt |
NOT RUN | n/a | |
| M3-1 | Baseline connectivity | ex03 baseline |
Both clients OK_2XX, body = backend pod name |
NOT RUN | ex03 reset |
|
| M3-2 | Default deny (negative) + proof it's policy | ex03 deny |
TIMEOUT; endpoints ready; backend Ready; connect-timeout text |
NOT RUN | ex03 reset |
|
| M3-3 | Selective allow | ex03 allow |
allowed OK_2XX, denied TIMEOUT |
NOT RUN | ex03 reset |
|
| M3-4 | DNS preserved under egress control | ex03 egress-deny, egress-allow |
DNS_TIMEOUT/FAILURE, then OK_2XX |
NOT RUN | ex03 reset |
|
| M4-0 | Experimental combination explicitly accepted | ex04 acknowledge (G4) |
Line in out/approvals.log |
NOT RUN | n/a | |
| M4-1 | Application Network + 2 members | ex04 create, join (G5) |
Members Succeeded, east-west Internal |
NOT RUN | cleanup-2-azure.sh |
|
| M4-2 | Managed components ready | ex04 verify |
ztunnel/istio-cni ready; Istio CRDs; east-west LB Service | NOT RUN | n/a | |
| M4-3 | East-west underlay reachability | ex04 underlay |
TCP connect both directions | NOT RUN | n/a | |
| M4-4 | Only intended namespace enrolled, no sidecars | ex04 enroll, no-sidecars |
Only bookinfo (later l4-lab) enrolled; no istio-proxy |
NOT RUN | remove label | |
| M5-1 | Global services merged | ex05 discovery |
Two VIPs (10.110.x and 10.120.x) per global service | NOT RUN | n/a | |
| M5-2 | Remote-only destination proven by identity | ex05 remote-only |
0 local endpoints; 5/5 clustername=cluster-2 with v2/v3 pod names |
NOT RUN | n/a | |
| M5-3 | Mixed global routing observed | ex05 global-mix |
Counts per cluster recorded | NOT RUN | n/a | |
| M6-1 | Shared trust root | ex06 identity |
Same root SHA-256 fingerprint in both clusters | NOT RUN | n/a | |
| M6-2 | Permissive accepts plaintext | ex06 permissive |
Outside client OK_2XX |
NOT RUN | n/a | |
| M6-3 | STRICT: mesh OK in-cluster + cross-cluster | ex06 test-strict |
OK_2XX; cross-cluster served by cluster-2 |
NOT RUN | ex06 reset |
|
| M6-4 | STRICT rejects plaintext, reachability intact | ex06 test-strict |
Outside → productpage CONN_RESET; outside → plain-echo OK_2XX |
NOT RUN | ex06 reset |
|
| M7-1 | Ingress restricted to your IP | ex07 deploy, nsg-evidence |
NSG rule source = ALLOWED_CLIENT_CIDR |
NOT RUN | ex07 teardown |
|
| M7-2 | Ingress → local backend | ex07 test-http |
/lab/local → cluster-1 |
NOT RUN | n/a | |
| M7-3 | Ingress → remote backend (experiment G-9) | ex07 test-http |
/lab/remote → cluster-2, or recorded failure |
NOT RUN | n/a | |
| M7-4 | HTTPS client-to-gateway | ex07 https, test-https |
OK_2XX with CA; TLS_ERROR without |
NOT RUN | ex07 teardown |
|
| M8-1 | L4: allowed identity accepted | ex08 l4lab-policy |
client-allowed OK_2XX |
NOT RUN | ex08 reset |
|
| M8-2 | L4: other identity rejected, network open | ex08 l4lab-policy |
client-denied CONN_RESET; no NetworkPolicy present |
NOT RUN | ex08 reset |
|
| M8-3 | Doc L4 policy; waypoint nuance explained | ex08 doc-policy |
ingress OK_2XX; service path UPSTREAM_RESET; pod-IP CONN_RESET |
NOT RUN | ex08 reset |
|
| M8-4 | Identity has no cluster component | ex08 cross-cluster |
cluster-2 client-allowed allowed (observation) | NOT RUN | n/a | |
| M9-1 | L7 allow GET / deny DELETE / deny identity | ex09 test-direct |
OK_2XX, RBAC_DENIED, RBAC_DENIED |
NOT RUN | ex09 reset |
|
| M9-2 | Waypoint bypass blocked at L4 | ex09 test-direct |
pod-IP CONN_RESET |
NOT RUN | ex09 reset |
|
| M9-3 | Ingress gap demonstrated then closed | ex09 ingress-gap, close-gap |
App status (not RBAC), then RBAC_DENIED |
NOT RUN | ex09 reset |
|
| M10-1 | Scoped default deny breaks traffic (and probes?) | ex10 deny |
UPSTREAM_CONNECT_TIMEOUT/TIMEOUT; echo NotReady (runtime check) |
NOT RUN | ex10 reset |
|
| M10-2 | Probe SNAT allowance | ex10 probes |
echo Ready; traffic still blocked | NOT RUN | ex10 reset |
|
| M10-3 | Scoped mesh allowances | ex10 allow |
Positive paths OK; client-denied TIMEOUT; bypass dropped |
NOT RUN | ex10 reset |
|
| M10-4 | Network ≠ identity (impostor) | ex10 impostor |
impostor CONN_RESET |
NOT RUN | ex10 reset |
|
| M10-5 | Cross-cluster requires the local east-west source | ex10 remote |
blocked, then OK_2XX after rule |
NOT RUN | ex10 reset |
|
| M10-6 | Cluster 2 layered policies | ex10 cluster2 |
cross-cluster OK; ratings bypass dropped | NOT RUN | ex10 reset |
|
| M11-1 | JWT validation vs routing | ex11 jwt-test |
404 / 401 / 404 / 200 | NOT RUN | ex11 jwt-reset |
|
| M11-2 | Token required | ex11 jwt-require |
403 / 401 / 404 / 200 | NOT RUN | ex11 jwt-reset |
|
| M11-3 | Weighted cross-cluster routing | ex11 shift |
~8/32 of 40, both > 0 | NOT RUN | ex11 shift-reset |
|
| M11-4 | Delay injection | ex11 fault-delay-7s, fault-delay-1s |
~7s with header, fast without; page error, then recovery | NOT RUN | ex11 fault-reset |
|
| M11-5 | Abort injection | ex11 fault-abort |
FAULT_ABORT; ratings unavailable on page |
NOT RUN | ex11 fault-reset |
|
| M11-6 | No faults left | ex11 fault-reset |
No VirtualServices in either cluster | NOT RUN | n/a | |
| M12-1 | Waypoint request metrics | ex12 waypoint-stats |
istio_requests_total by service/code |
NOT RUN | n/a | |
| M12-2 | Access logs | ex12 access-logs |
Envoy log lines in waypoint logs | NOT RUN | ex12 reset |
|
| M12-3 | Managed Prometheus (G7) | ex12 enable-metrics + queries |
Series visible in workspace | NOT RUN | ex12 monitoring-disable |
|
| M12-4 | Logs + istiod logs (G7) | ex12 enable-logs + queries |
ContainerLogV2, MeshControlPlane rows |
NOT RUN | ex12 monitoring-disable |
|
| M12-5 | Lifecycle understood | ex12 lifecycle |
Versions, modes, AKS upgrades, maintenance configs listed | NOT RUN | n/a | |
| M13-1 | Remote backends removed and restored safely | ex13 remove-remote, restore-remote |
5xx for remote-only; global served by c1; restored OK | NOT RUN | ex13 restore |
|
| M13-2 | Local backend removed and restored safely | ex13 remove-local, restore-local |
Global served by c2; restored OK | NOT RUN | ex13 restore |
|
| M14-1 | Un-enroll + K8s cleanup | cleanup-1-kubernetes.sh (G9) |
No enrolled namespaces; lab namespaces gone | NOT RUN | n/a | |
| M14-2 | Azure cleanup in documented order | cleanup-2-azure.sh (G9) |
Members removed → AppNet deleted → RGs deleted | NOT RUN | n/a | |
| M14-3 | No leftovers | cleanup-3-leftovers.sh |
"No lab leftovers found" | NOT RUN | n/a |