From 3aa2cf7616189bb9f74e11fc9ac336c7faa30a34 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Fri, 30 Oct 2026 11:40:45 +0100 Subject: [PATCH] feat(paperless): Syncthing UI behind the Authentik gate Serve the UI at syncthing.paperless.renner.uno for Paperless Admins. That hostname was the sync LoadBalancer's DNS name, so the LoadBalancer moves to sync.paperless.renner.uno and the DNS probe follows it. Co-Authored-By: Claude Opus 5.5 --- .../apps/authentik/blueprints-configmap.yaml | 10 +++++ .../apps/monitoring-rules/probes-dns.yaml | 2 +- .../helmrelease-blackbox-exporter.yaml | 2 +- kubernetes/apps/paperless/kumamonitors.yaml | 22 ++++++++++ kubernetes/apps/paperless/syncthing.yaml | 43 ++++++++++++++----- .../network-policies/paperless-ns.yaml | 4 +- 6 files changed, 69 insertions(+), 14 deletions(-) diff --git a/kubernetes/apps/authentik/blueprints-configmap.yaml b/kubernetes/apps/authentik/blueprints-configmap.yaml index 9fdef09b..684f6b43 100644 --- a/kubernetes/apps/authentik/blueprints-configmap.yaml +++ b/kubernetes/apps/authentik/blueprints-configmap.yaml @@ -103,6 +103,16 @@ data: slug: paperless-proxy state: absent + # syncthing.paperless.renner.uno is gated by authentik-gate-sync + # (kubernetes/apps/paperless/syncthing.yaml), which admits this group. + # Members are managed in Authentik. + - model: authentik_core.group + identifiers: + name: Paperless Admins + state: present + attrs: + is_superuser: false + # vscode.home.renner.uno is gated by authentik-gate-sync # (kubernetes/apps/home-assistant/vscode-ingress.yaml), which admits this # group. Members are managed in Authentik. diff --git a/kubernetes/apps/monitoring-rules/probes-dns.yaml b/kubernetes/apps/monitoring-rules/probes-dns.yaml index 13a316bc..0ea94d8a 100644 --- a/kubernetes/apps/monitoring-rules/probes-dns.yaml +++ b/kubernetes/apps/monitoring-rules/probes-dns.yaml @@ -142,4 +142,4 @@ spec: - "[fd02:47::1]:53" - "10.2.47.1:53" labels: - dns_name: syncthing.paperless.renner.uno + dns_name: sync.paperless.renner.uno diff --git a/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml b/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml index efafa406..c33b1548 100644 --- a/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml +++ b/kubernetes/apps/monitoring/helmrelease-blackbox-exporter.yaml @@ -136,7 +136,7 @@ spec: prober: dns timeout: 5s dns: - query_name: syncthing.paperless.renner.uno + query_name: sync.paperless.renner.uno query_type: A valid_rcodes: [NOERROR] validate_answer_rrs: diff --git a/kubernetes/apps/paperless/kumamonitors.yaml b/kubernetes/apps/paperless/kumamonitors.yaml index a78ce801..dc87bbea 100644 --- a/kubernetes/apps/paperless/kumamonitors.yaml +++ b/kubernetes/apps/paperless/kumamonitors.yaml @@ -138,3 +138,25 @@ spec: expiryNotification: true keyword: keyword: "authentik" +--- +apiVersion: uptime.renner.uno/v1alpha1 +kind: KumaMonitor +metadata: + name: syncthing-ui-gate + namespace: paperless +spec: + type: keyword + displayName: Syncthing Login + parentRef: + name: docs + interval: 60 + retryInterval: 60 + maxRetries: 1 + timeout: 20 + http: + # behind the Authentik gate; asserts the login page the redirect chain ends on + url: https://syncthing.paperless.renner.uno/ + acceptedStatusCodes: ["200-299"] + expiryNotification: true + keyword: + keyword: "authentik" diff --git a/kubernetes/apps/paperless/syncthing.yaml b/kubernetes/apps/paperless/syncthing.yaml index 08c30e98..a518f2c2 100644 --- a/kubernetes/apps/paperless/syncthing.yaml +++ b/kubernetes/apps/paperless/syncthing.yaml @@ -52,11 +52,8 @@ spec: - name: syncthing image: syncthing/syncthing:2.1.7@sha256:2b71da7c0d0a91a6ae5285ad079226fecc0a365d08b27720e1f7037b018f7546 env: - # UI bind: any-interface so the ClusterIP Service can reach - # it. Network exposure is gated by the absence of an Ingress - # and the namespace default-deny CNP — set a UI password in - # the Syncthing UI on first port-forward access before - # publishing it. + # UI bind: any-interface so the ClusterIP Service can reach it. + # External access goes through the syncthing-ui Ingress only. - name: STGUIADDRESS value: "0.0.0.0:8384" - name: PUID @@ -115,10 +112,6 @@ spec: persistentVolumeClaim: claimName: paperless-consume --- -# UI Service — ClusterIP only. Access via `kubectl -n paperless -# port-forward svc/syncthing-ui 8384:8384` for first-time setup -# (set admin password). Future Ingress + Authentik gate is a -# separate change once auth is configured. apiVersion: v1 kind: Service metadata: @@ -132,6 +125,36 @@ spec: port: 8384 targetPort: ui --- +# LAN-only UI: Paperless Admins through the Authentik gate. +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: syncthing-ui + namespace: paperless + labels: + dns.renner.uno/internal: "true" + annotations: + traefik.ingress.kubernetes.io/router.middlewares: authentik-gate@kubernetescrd + cert-manager.io/cluster-issuer: letsencrypt-cluster + auth.renner.uno/group: Paperless Admins +spec: + ingressClassName: traefik + rules: + - host: syncthing.paperless.renner.uno + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: syncthing-ui + port: + number: 8384 + tls: + - secretName: syncthing-ui-tls + hosts: + - syncthing.paperless.renner.uno +--- # Sync ports — LAN-reachable LoadBalancer. Peers (phones, laptops) # connect here for the dropbox sync. external-dns publishes the # hostname into UniFi DNS only (no cloudflare label); off-LAN peers @@ -146,7 +169,7 @@ metadata: dns.renner.uno/internal: "true" annotations: io.cilium/lb-ipam-ips: "10.2.99.85,fd99::85" - external-dns.kubernetes.io/hostname: syncthing.paperless.renner.uno + external-dns.kubernetes.io/hostname: sync.paperless.renner.uno spec: type: LoadBalancer externalTrafficPolicy: Local diff --git a/kubernetes/infrastructure/network-policies/paperless-ns.yaml b/kubernetes/infrastructure/network-policies/paperless-ns.yaml index 31b5b94b..7cde08a4 100644 --- a/kubernetes/infrastructure/network-policies/paperless-ns.yaml +++ b/kubernetes/infrastructure/network-policies/paperless-ns.yaml @@ -145,8 +145,8 @@ spec: # Allow Syncthing peer-to-peer sync from the LAN/world. # - 22000 TCP+QUIC: actual sync traffic between peers. # - 21027 UDP: local-discovery broadcast packets from peers on the LAN. -# UI (8384) is intentionally NOT listed — accessed via port-forward -# until an Ingress + Authentik gate is added. +# UI (8384) is intentionally NOT listed — authentik-gate-sync generates the +# CNP syncthing-ui-gate that admits traefik. apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: -- 2.54.0