Stage 2 of unifying the auth flows, after the llama and paperless trial
of stage 1 was confirmed:
- Brand authentik.srv.renner.uno: flow_authentication =
sso-authentication (was NULL, i.e. the slug-first
default-authentication-flow with password + MFA). Every provider
without its own authentication_flow logs in through it, PVE and PBS
included.
- The 7 blueprint OIDC providers (Home Assistant, NetBird,
Audiobookshelf, Immich, Gitea, Grafana, Matrix MAS): authentication
flow unset (brand), authorization implicit consent.
- authentik-gate-sync: default authorization flow implicit consent, via
DEFAULT_AUTHORIZATION_FLOW on the Deployment and in the code; the
per-gate login/authorization annotations are dropped. Paperless keeps
paperless-authorization.
Every flow referenced here already exists, so the gate controller does
not hit the missing-flow removal seen in stage 1. Stage 3 removes the
passkey-only flows once nothing references them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
paperless, shelly-manager, zone-configurator, esphome, zigbee2mqtt,
alertmanager, prometheus, wiki, paperclip, navidrome, lidarr and wordpress
now gate through authentik-gate-sync: each source Ingress names its real
backend and carries the old provider's settings as annotations (group,
login-flow, authorization-flow where it was implicit consent, paperless'
skip-path).
Removed per gate: the ExternalName Service, the egress CNP in authentik,
the namespace CNP rule admitting the old outpost, and the blueprint
provider/application/binding/outpost (state: absent, outpost ->
application -> provider). Groups stay declared without users lists;
membership is managed in Authentik.
Per-gate specifics:
- paperless: the docs.renner.uno alias backends the generated
paperless-gate Service (its middleware redirects before the backend); the
auth.renner.uno/outpost.goauthentik.io route is removed, proxy outposts
take their callback on the app host.
- alertmanager / prometheus: source Ingresses renamed to alertmanager /
prometheus; the controller generates the *-gate route Ingresses.
- wordpress-admin: gains a tls block for www.renner.uno (wordpress-tls,
certificate still owned by the public Ingress), so the gate's external
host stays https.
- wiki, paperclip: only the gate peer/rule leaves their shared CNPs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Koda (Garmin Connect IQ) calls POST /auth/login during sync. Only /rest
and /share bypassed the navidrome-gate, so the gate answered 302 with an
empty body and the watch failed with -400
INVALID_HTTP_BODY_IN_NETWORK_RESPONSE ("Native login failed -400").
An IngressRoute sends /auth and /api straight to Navidrome when the
request carries no authentik_proxy_ session cookie; requests with the
cookie (the web UI) keep going through the gate, so SSO is unchanged.
X-Authentik-Username is stripped on this route as on /rest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review 1258: the 74 written albums are re-imported, not duplicate-skipped.
Fix the comment and report before/after mb_albumid per album.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two dry runs were checked; the spot check now matches original releases.
Music mount becomes writable for tag writes; move/copy/delete stay off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The first dry run (write: no) matched 78 of 560 albums; some matched
reissues (JP/RU) and would have changed year to the reissue year.
Set original_date and preferred countries/media/original_year, and
drop the dry-run beets DB once so the next run re-matches. Still write: no.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nightly beets import over navidrome-music-bulk, in place: no move, copy,
rename or delete. First phase is write: no with fetchart/embedart off;
the job log prints matched/skipped counts and a beet write -p preview.
Renovate rule for the LinuxServer -ls<n> tag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comments that pointed at other YAML as `file.yaml:N` went stale on any
edit above the cited line; three drift fixes had been merged by hand
(REN-181). The cited block now carries `# anchor: <name>` and the
comment cites `path.yaml#<name>`.
- Sweep: all 32 line-number citations in YAML comments converted.
Several were already stale at head and now point at the right block
(see PR). Vendored files (Flux gotk-components, IMC CRD) get no
anchor; those two citations name the object/schema path instead.
- Guard: scripts/ci/yaml-citations.sh in ci-manifests-test.yml; fails
on a line-number citation or a path#name whose file/anchor is gone.
Self-test in ci-scripts-test.yml.
- CONTRIBUTING.md: the convention in three lines.
Comment-only under kubernetes/: every file parses to identical objects
before and after, so Flux applies nothing and no ConfigMap data changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
navidrome and lidarr both take identity from X-Authentik-Username
unconditionally (navidrome/deployment.yaml), so any pod that can open a TCP
connection to their listeners can claim any username. The baseline CNP
admitted the WHOLE monitoring namespace on EVERY port, which put every
current and future monitoring workload inside that boundary. Only two flows
actually cross it, and both are blackbox probes.
Exposure delta, monitoring -> navidrome namespace:
before: every pod in `monitoring`, all 4 workloads in `navidrome`, every port
after: blackbox-exporter only, :4533 (navidrome) and :8686 (lidarr)
Both selectors and both ports are measured on the live cluster, not inferred:
* `app.kubernetes.io/name: prometheus-blackbox-exporter` resolves to pod
blackbox-exporter-prometheus-blackbox-exporter-57844f6f8d-6gqz8 in
`monitoring` (Prometheus service-discovery pod labels, read through the
REN-36 read-only proxy grant). Chart prometheus-blackbox-exporter-11.19.1.
* `probe_success` is 1 for both
http://navidrome.navidrome.svc.cluster.local:80/ping and
http://lidarr.navidrome.svc.cluster.local:80/ping. Those Services select
`app.kubernetes.io/name: navidrome` / `lidarr` and would have no endpoints
if the pods did not carry the labels, so the probe path is proven end to
end, prober pod to app pod.
* Service :80 -> containerPort 4533 (deployment.yaml) and 8686
(lidarr.yaml). Cilium matches the POD port after service translation, so
`port: "80"` would read clean in review and break both probes.
ICMP rule added, and it is NOT cosmetic. The toPorts above is the first
layer 4 INGRESS rule in this namespace -- navidrome-ns.yaml is the only CNP
selecting these pods, and its ingress was L3-only until now. Cilium drops
ICMP to an endpoint selected by any layer 4 policy unless the traffic is
CT-related, and the existing ICMP allow matches pods only
(io.kubernetes.pod.namespace Exists), which `host` and `remote-node` do not
carry. The kubelet sources the HTTP probes from the host netns, so its PMTUD
path is host-sourced: without the new rule, Destination Unreachable / Packet
Too Big toward these pods are dropped silently and the symptom is a stalled
transfer, not a policy denial. Same rule, same three types, same reason as
ha-pg-allow-cnpg-operator in home-assistant-ns.yaml. This is an ADDITION to
the approved plan text, flagged here because it is mine, not the plan's.
Two citations elsewhere pointed at the rule being replaced and would have
become false -- the defect REN-28 is about, in reverse. Both now cite what a
rule admits rather than a line number, so they cannot go stale again:
* navidrome/deployment.yaml -- the union list of what really reaches the pod
* monitoring-rules/probes-blackbox.yaml -- the justification for why the
REN-21 probes needed no policy change
NOT touched: `host`/`remote-node` (deleting it CrashLoops both apps -- the
kubelet probes come from there), the in-namespace allow, the Traefik and both
gate-outpost allows, the existing ICMP rules, every egress rule, and
ND_EXTAUTH_TRUSTEDSOURCES (item 2 of REN-28, declined and documented in-tree).
No workload restart: a CNP change is picked up by Cilium in seconds.
Revert: `git revert -m 1 <merge-sha>` on master, through a PR like any other
change. Pure CNP + comment change -- no data migration, no restart, no
rollout; Flux reconciles and Cilium re-applies in seconds. Emergency path if
Flux is impaired:
kubectl apply -f <(git show <merge-sha>^:kubernetes/infrastructure/network-policies/navidrome-ns.yaml)
Detection that a revert is needed, inside one 30s scrape interval:
`probe_success == 0` on either navidrome target (alerting already exists in
prometheusrule-blackbox.yaml), or either pod leaving Ready.
REN-28 item 3a, approved by the owner. Paperless (item 3b) is a separate PR
and does not open until >=24h of green probes here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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 <this commit>`; restores master 3d6c9940 exactly.
Refs REN-108, REN-28.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Reverts the image change in b858b4aa. ls11 is 3.1.0.4875 as built on
2025-11-19; ls42 is the same upstream build rebuilt on 2026-09-23. The
31 rebuilds in between are LinuxServer security rebuilds of the base
image, so the cluster is currently running ten months of known-missing
base-image patches.
Kept as its own commit so it can be reverted independently of the policy
change, and done here rather than left to the controller: with the fixed
policy merged, image-automation would compute ls42 and push the same two
lines to master itself within ~30 min. Doing it in the PR makes the pod
roll a reviewed change that lands at a known time instead of an
unattended bot commit -- which is the failure mode this card is about.
Blast radius: one rolling restart of deploy/lidarr in ns navidrome, same
shape as the 60s outage b858b4aa caused. Lidarr is a read-only
missing-album view; nothing else consumes it. No other workload moves.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Lidarr in the navidrome namespace as a "what is missing" UI: artist
discographies (Wanted -> Missing) and Spotify followed artists / saved
albums / playlists as import lists.
- Mounts navidrome-music-bulk read-write (Lidarr has no read-only root
folder mode); config on ceph-block.
- A reconcile sidecar (same image, curl+jq) reads the API key from
/config/config.xml and on every start sets renameTracks=false,
writeAudioTags=no, no recycle bin, no empty-folder deletes, no
permission changes -- then adds /music as root folder only if absent,
so the automatic library import never runs with file-mutating
settings.
- No download client or indexer.
- AuthenticationMethod=External behind a dedicated lidarr-gate outpost
restricted to a new "Music Librarians" group (k.renner).
- Image automation on the linuxserver build number.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Navidrome (Subsonic API) as the Spotify replacement for phone apps.
- Library PVC on ceph-filesystem-bulk (RWX, 300Gi, mounted read-only);
SQLite data on ceph-block (RWO).
- Web UI behind a dedicated navidrome-gate Authentik proxy outpost;
Navidrome trusts X-Authentik-Username (ExtAuth) and auto-creates the
user on first SSO login (first user = admin).
- /rest and /share routed straight to Navidrome with the identity header
stripped, so Subsonic clients use their Navidrome password.
- Namespace baseline CNP, gate egress CNP, Flux image automation,
Velero daily schedule (09:15), bootstrap wait.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>