From a557eea7bb8a2411c8eb7ef57e04710df846687e Mon Sep 17 00:00:00 2001 From: atlas-bot Date: Sat, 26 Sep 2026 00:25:56 +0000 Subject: [PATCH] docs(netpol): correct three comments that assert a boundary Cilium does not enforce (REN-108) Comments only. No `spec` change, no pod template change, no rendered manifest change. Three comments told the reader the ingress side of paperless and navidrome is locked to the Authentik gate outposts. It is not. `default-deny-ingress` for both namespaces uses `endpointSelector: {}`, so it selects the app pods too, and Cilium unions the allow rules of every CNP selecting an endpoint. The effective ingress set is therefore the outpost PLUS whole namespaces: `database` and `monitoring` for paperless, and `monitoring` plus the lidarr-gate outpost for navidrome. Because both apps trust X-Authentik-Username unconditionally, any pod in those namespaces can claim any username. - kubernetes/apps/paperless/network-policy.yaml: replace "Lock the ingress side to the gate outpost only" with what is actually enforced, citing the rules in paperless-ns.yaml. - kubernetes/infrastructure/network-policies/paperless-ns.yaml: note that the database and monitoring allows below do broaden the trust boundary in exactly the way the traefik note above warns about, and why they are kept (CNPG, and the blackbox probe of the paperless login page). - kubernetes/apps/navidrome/deployment.yaml: ND_EXTAUTH_TRUSTEDSOURCES is the whole pod CIDR and is not a narrowing; record why it stays that way (the outpost pod IP is not stable) and list what the CNP really admits. Verification: `kubectl kustomize` (v1.31.0 / kustomize v5.4.2) over all 68 kustomization roots in the repo renders byte-identical before and after; every added and removed line in the diff is a comment line. Revert: `git revert `; restores master 3d6c9940 exactly. Refs REN-108, REN-28. Co-Authored-By: Claude Opus 5 Co-Authored-By: Paperclip --- kubernetes/apps/navidrome/deployment.yaml | 23 ++++++++++++++++-- kubernetes/apps/paperless/network-policy.yaml | 24 +++++++++++++++---- .../network-policies/paperless-ns.yaml | 9 +++++++ 3 files changed, 49 insertions(+), 7 deletions(-) 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 -- 2.54.0