Skip to main content

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 NetworkPolicy rules 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_denied verdicts.
  • 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.