diff --git a/kubernetes/apps/navidrome/deployment.yaml b/kubernetes/apps/navidrome/deployment.yaml index ab77fa09..9b449fa8 100644 --- a/kubernetes/apps/navidrome/deployment.yaml +++ b/kubernetes/apps/navidrome/deployment.yaml @@ -8,8 +8,27 @@ data: ND_LOGLEVEL: "info" ND_SCANNER_SCHEDULE: "0 * * * *" ND_ENABLEINSIGHTSCOLLECTOR: "false" - # Identity from the navidrome-gate outpost; the CNP admits only the outpost - # and Traefik, and Traefik strips this header on the ungated routes. + # Identity from the navidrome-gate outpost. Traefik strips this header on + # the ungated /rest and /share routes. + # + # ND_EXTAUTH_TRUSTEDSOURCES BELOW IS NOT A NARROWING. fd10:244::/48 plus + # 10.244.0.0/16 is the entire cluster pod CIDR, so navidrome's own + # reverse-proxy trust check accepts X-Authentik-Username from ANY pod. + # The CiliumNetworkPolicy is the only real boundary, and it is wider than + # "the outpost and Traefik" — default-deny-ingress in + # kubernetes/infrastructure/network-policies/navidrome-ns.yaml uses + # `endpointSelector: {}` and admits, on every port: + # - the navidrome namespace (navidrome-ns.yaml:9-11) + # - traefik (navidrome-ns.yaml:13-16) + # - the navidrome-gate outpost (navidrome-ns.yaml:17-20) + # - the lidarr-gate outpost (navidrome-ns.yaml:21-24) - reaches navidrome too + # - the monitoring namespace (navidrome-ns.yaml:25-27) + # - host / remote-node (navidrome-ns.yaml:28-30) + # The value stays at the pod CIDR ON PURPOSE - see REN-28. The address + # navidrome sees is the outpost's POD IP, which is not stable across + # reschedules, so a narrower literal here fails open-ended and silently + # the next time that pod moves. Tightening the CNP is the control that + # would actually do work. ND_EXTAUTH_USERHEADER: "X-Authentik-Username" ND_EXTAUTH_TRUSTEDSOURCES: "fd10:244::/48,10.244.0.0/16" --- diff --git a/kubernetes/apps/paperless/network-policy.yaml b/kubernetes/apps/paperless/network-policy.yaml index 169d70b9..0300270a 100644 --- a/kubernetes/apps/paperless/network-policy.yaml +++ b/kubernetes/apps/paperless/network-policy.yaml @@ -1,9 +1,23 @@ --- -# Trust boundary: paperless-gate (the dedicated Authentik proxy outpost -# in the authentik namespace). Header-based remote-user auth means -# paperless trusts whatever fills X-Authentik-Username unconditionally, -# so any pod that can talk directly to paperless's HTTP listener can -# claim any username. Lock the ingress side to the gate outpost only. +# Intended trust boundary: paperless-gate (the dedicated Authentik proxy +# outpost in the authentik namespace). Header-based remote-user auth means +# paperless trusts whatever fills X-Authentik-Username unconditionally, so +# any pod that can talk directly to paperless's HTTP listener can claim any +# username. +# +# WHAT IS ENFORCED IS WIDER THAN THIS RULE. default-deny-ingress in +# kubernetes/infrastructure/network-policies/paperless-ns.yaml uses +# `endpointSelector: {}`, so it selects this pod as well, and Cilium unions +# the allow rules of every CNP selecting an endpoint (the same mechanism +# described below). The effective ingress set is this outpost PLUS, on +# every port: +# - the paperless namespace (paperless-ns.yaml:9-11) +# - the database namespace (paperless-ns.yaml:30-32) +# - the monitoring namespace (paperless-ns.yaml:33-35) +# - host / remote-node (paperless-ns.yaml:36-38) +# So any pod in database or monitoring can reach this HTTP listener +# directly and set X-Authentik-Username to any value. Do not read this +# rule as the whole boundary. Narrowing is tracked in REN-28. # # This is a CiliumNetworkPolicy (not a standard NetworkPolicy) so it # composes additively with the cluster's baseline CNP diff --git a/kubernetes/infrastructure/network-policies/paperless-ns.yaml b/kubernetes/infrastructure/network-policies/paperless-ns.yaml index 4856b540..9fa81890 100644 --- a/kubernetes/infrastructure/network-policies/paperless-ns.yaml +++ b/kubernetes/infrastructure/network-policies/paperless-ns.yaml @@ -18,6 +18,15 @@ spec: # the trust boundary off the gate outpost — see # kubernetes/apps/paperless/network-policy.yaml for the # gate-specific ingress rule. + # + # Note: the database and monitoring allows below DO broaden the trust + # boundary in the way this note warns about, because endpointSelector + # is {} and therefore covers the paperless pod too. They are kept + # because both are load-bearing — CNPG reaches the postgres cluster + # from `database`, and the blackbox probe of + # http://paperless.paperless.svc.cluster.local:80/accounts/login/ + # (monitoring-rules/probes-blackbox.yaml:250) runs from `monitoring`. + # Scoping them to specific pods and ports is tracked in REN-28. - fromEndpoints: - matchLabels: "k8s:io.kubernetes.pod.namespace": database