--- # Default-deny baseline (R-NET-01): deny all ingress + egress, allow only DNS. `runbooks` is a # PLATFORM namespace (no app-namespace label) so Kyverno does not auto-generate this — it is shipped # explicitly, defence in depth, same shape as the Kyverno-generated app baseline and as # platform/homepage/networkpolicy.yaml. Cilium enforces the UNION of this NetworkPolicy and the # CiliumNetworkPolicy below (allow if ANY policy allows). apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: runbooks labels: homelab.keithjackson.dev/baseline: default-deny spec: podSelector: {} policyTypes: - Ingress - Egress ingress: [] egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - protocol: UDP port: 53 - protocol: TCP port: 53 --- # Gateway ingress allow (R-NET-01/02): only the shared Gateway (the Cilium `ingress` entity) may # reach the runbook server, on container port 8080. The server makes NO outbound calls whatsoever — # every byte it serves comes from a ConfigMap projected by the kubelet — so the baseline's DNS-only # egress is already more than it needs and no egress CNP is added. # # CONSEQUENCE WORTH STATING: because egress is DNS-only, these pages cannot pull a stylesheet, a # font or a markdown renderer from anywhere. That is why the content is served as text/plain # (serving/nginx-config.yaml) rather than as HTML with a CDN dependency, and it is a feature: the # runbooks render with zero network beyond the request that fetched them. apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: runbooks-allow-gateway-ingress namespace: runbooks labels: app.kubernetes.io/name: runbooks spec: endpointSelector: matchLabels: app.kubernetes.io/name: runbooks ingress: - fromEntities: - ingress toPorts: - ports: - port: "8080" protocol: TCP