Skip to content

Register Krautwatch as an OIDC client - #489

Open
ChrisonSimtian wants to merge 2 commits into
mainfrom
feat/krautwatch-oidc
Open

Register Krautwatch as an OIDC client#489
ChrisonSimtian wants to merge 2 commits into
mainfrom
feat/krautwatch-oidc

Conversation

@ChrisonSimtian

@ChrisonSimtian ChrisonSimtian commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Note

Self-contained as of the latest commits — the three pieces a working client needs are all here or
already done.
Recorded because the failure mode is silent-adjacent and the pieces look independent:

Piece Where Status
The client pair exists Bitwarden SM + repo Actions secrets done by the Homelab session
The runner can see it _deploy-stack.yml env added here
The container receives it Secret=…,type=env,target=… in the authentik server + worker quadlets added here

Declaring the pair in authentik.lxc.yaml only creates the podman secret. Without the quadlet
lines it is never injected, !Env resolves null, and authentik rejects the entire blueprint file
#497, whose collateral is whatever else is in that file at the time. The worker is what applies
blueprints, so it is the one that must have it; both carry it for symmetry.

Krautwatch gained OIDC support (Chrison-dev/Krautwatch#48), so its web UI can stop carrying a single-admin login of its own. This registers it, following the Pangolin entry.

What is here

  • Provider — confidential, client pair as !Env from Bitwarden Secrets Manager, include_claims_in_id_token: true (Krautwatch reads the groups claim itself), and an explicit grant_types allow-list. That last one is copied deliberately: omitted, it fails exactly as opaquely as it did for Pangolin.
  • Application krautwatch.
  • Policy bindings for Homelab Admins and Media Admins only. Krautwatch drives the download client and writes into the media library — machinery, not something Family or Guests consume. Plex is the output they want.
  • Two secrets wired through authentik.lxc.yaml, matching the Pangolin pattern.

Two redirect URIs, strict rather than regex — ASP.NET Core's handler uses one fixed callback path, so there is nothing variable to match:

http://10.10.255.254:5099/signin-oidc          # LAN, how it is reachable today
https://krautwatch.chrison.dev/signin-oidc     # for the day it gets a hostname

Registering the second now means fronting the UI later is a compose edit rather than an identity change.

Nothing switches over in this PR

krautwatch-web keeps Auth:Provider=local. Flipping it needs two things that are not mine to do:

  1. AUTHENTIK_KRAUTWATCH_CLIENT_ID / _SECRET in Bitwarden Secrets Manager, before a converge — the blueprint's !Env tags resolve to nothing otherwise, and a provider with an empty client id is a provider that rejects every request.
  2. The same pair on krautwatch-web, plus:
Environment=Auth__Provider=oidc
Environment=Auth__Oidc__Authority=https://identity.chrison.dev/application/o/krautwatch/
Environment=Auth__Oidc__RequiredGroups=Homelab Admins,Media Admins
Secret=authentik_krautwatch_client_id,type=env,target=Auth__Oidc__ClientId
Secret=authentik_krautwatch_client_secret,type=env,target=Auth__Oidc__ClientSecret

RequiredGroups duplicates the bindings above on purpose — two independent checks, so a binding lost to a careless converge does not silently open the UI.

Worth knowing while you are in there

krautwatch-web.container is pinned to :0.1.1, and the OIDC support ships in v0.7.0 — the whole Krautwatch stack there is many releases behind. Bumping it is a separate job: v0.4.0 migrates timestamp columns in place, so the Migrator does real work on that upgrade and the database wants a backup first.

@ChrisonSimtian ChrisonSimtian added enhancement New feature or request iac labels Aug 23, 2026
Krautwatch gained OIDC support (Chrison-dev/Krautwatch#48), so its web UI can
stop carrying its own single-admin login. This adds the provider, application and
policy bindings, following the Pangolin entry — including its grant_types lesson,
which fails identically and just as opaquely when omitted.

Admins only: Krautwatch drives the download client and writes the media library,
which is machinery rather than something Family or Guests consume.

Two redirect URIs, because the UI is LAN-only today and would move to a hostname
the day it is fronted; registering both now keeps that a compose edit.

Nothing switches over yet — krautwatch-web keeps its local login until the client
pair exists in Bitwarden Secrets Manager.
The blueprint entry was inert as written. authentik.lxc.yaml's `secrets:` block
creates the podman secret; injecting it as an environment variable takes a
`Secret=…,type=env,target=…` line in the server and worker quadlets, and the
worker is what applies blueprints. Without it `!Env` resolves null and authentik
rejects the entire file — #497, with the collateral being whatever else happens
to be in it.

The runner also never saw the pair: _deploy-stack.yml has no secrets.env and
falls back to process env, so every secret a stack declares has to be listed
explicitly. Same class as #446/#471/#490.

Both found in review by the Homelab session. The shape and the quadlet each
looked correct in isolation, which is exactly what made #497 hard to see.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request iac

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant