app-network-policy (component)
A Kustomize component that lands a starting-set NetworkPolicy in the app's namespace. Default-deny on both ingress and egress, with the homelab's standard allow-rules for what every app needs to talk to (DNS, the platform controllers, the api-server).
Apps that need to talk to things outside the baseline (a specific external API, another internal service, an in-cluster database) add their own per-app NetworkPolicy on top.
What it composes
The baseline drops:
- Default deny ingress — only matching
NetworkPolicyrules let traffic in. - Default deny egress — only matching rules let traffic out.
- Allow CoreDNS — every pod needs DNS for service discovery.
- Allow API server — for in-cluster clients (operators, exec calls).
- Allow the platform-namespace observability scrape — Prometheus / Victoria-Metrics from the monitoring namespace.
The baseline is intentionally tight: an app that "just runs" without explicit egress to the rest of the cluster will fail closed — which is the point.
How an app uses it
# k8s/apps/talos/<app>/kustomization.yaml
components:
- ../../../components/talos/app-network-policy
Then, in the app's manifests, declare any additional allow-rules the app needs:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: <app>-allow-external-api
namespace: <app>
spec:
podSelector: {}
policyTypes: [Egress]
egress:
- to: [{namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: external-api}}}]
ports: [{protocol: TCP, port: 443}]
The app's allow-rules combine with the baseline's allow-rules — Kubernetes NetworkPolicy semantics are additive.
Why default-deny + explicit allow
- Identity-aware, not IP-aware. Cilium enforces these with eBPF, keyed on pod labels. IPs come and go; labels don't.
- Lateral-movement containment. A compromised app pod can't pivot to another app's database just because both happen to live on the cluster.
- Surfaces dependencies. When an app fails closed because the baseline didn't include a rule for its specific egress, that is the documentation. The fix is to write the rule.
Operational notes
- Cilium's Hubble UI (Platform → Cilium) is the diagnosis tool when an app's traffic is being denied unexpectedly. Look for
policy_deniedverdicts. - The baseline is intentionally minimal. Don't pad it with "things most apps need" — each pad weakens the default. Per-app explicit rules are better.
- The same component exists for the edge cluster with a tighter outbound policy (the edge cluster's apps mostly forward to production over the mesh, not to arbitrary external endpoints).
Composition source
No partial — there's no README.md in k8s/components/<cluster>/app-network-policy/ yet. The kustomize template is small enough to read directly: see k8s/components/talos/app-network-policy for the actual manifests.