diff --git a/README.md b/README.md index 3e352e8..f858692 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,7 @@ AUTH_PROVIDER=oidc OIDC_AUTHORITY=https://identity.example.com/application/o/krautwatch/ OIDC_CLIENT_ID=… OIDC_CLIENT_SECRET=… # may be env:/file: -OIDC_REQUIRED_GROUPS=Homelab Admins,Media Admins # optional second check; empty admits anyone +OIDC_REQUIRED_GROUPS=krautwatch-users # optional second check; empty admits anyone ``` Register `https:///signin-oidc` as the redirect URI and request `openid profile email`. Setting @@ -282,6 +282,10 @@ Register `https:///signin-oidc` as the redirect URI and request `openid pr independent checks mean neither has to be the only thing that is right. Sign-out is federated, and `/setup` stops asking for an administrator — your provider owns identity. +Group names must match **exactly what your provider emits** in the claim (case aside). The list is +split on commas only, so a name may contain spaces — but plenty of other consumers split on +whitespace too, so hyphenated names travel better between them. + **First run (local provider):** there is no administrator yet, so the `web` host logs a one-time setup link. Fetch it from the logs and open it: diff --git a/docs/plans/2026-08-23 - oidc authentication.md b/docs/plans/2026-08-23 - oidc authentication.md index 0974633..2bdabd5 100644 --- a/docs/plans/2026-08-23 - oidc authentication.md +++ b/docs/plans/2026-08-23 - oidc authentication.md @@ -41,7 +41,7 @@ Auth:Provider = none → AnonymousAccess middleware (unchanged) "ClientId": "…", "ClientSecret": "…", // may be a secret reference (env:/file:) "Scopes": ["openid", "profile", "email"], - "RequiredGroups": ["Homelab Admins", "Media Admins"], + "RequiredGroups": ["homelab-admins", "media-admins"], "GroupsClaim": "groups" } } @@ -57,7 +57,8 @@ The homelab's identity blueprint states the principle already: *authenticated mu authorised*, because the Plex source auto-enrols friends. This adopts it rather than restating it: 1. **Authentik** decides who may obtain a token for Krautwatch at all — application policy bindings - for `Homelab Admins` and `Media Admins`. + for `homelab-admins` and `media-admins` (renamed from the spaced forms by Homelab #497 — + the claim value is what Krautwatch matches, so the two have to stay in step). 2. **Krautwatch** re-checks the `groups` claim against `RequiredGroups` on sign-in, and refuses otherwise. diff --git a/docs/self-hosting.md b/docs/self-hosting.md index 8cd895d..192b1d1 100644 --- a/docs/self-hosting.md +++ b/docs/self-hosting.md @@ -136,7 +136,7 @@ AUTH_PROVIDER=oidc OIDC_AUTHORITY=https://identity.example.com/application/o/krautwatch/ OIDC_CLIENT_ID= OIDC_CLIENT_SECRET= # may be env:/file: like any stored credential -OIDC_REQUIRED_GROUPS=Homelab Admins,Media Admins # optional; empty admits anyone it authenticates +OIDC_REQUIRED_GROUPS=krautwatch-users # optional; empty admits anyone it authenticates ``` The redirect URI to register is **`https:///signin-oidc`**, and the sign-out @@ -148,6 +148,11 @@ token.** Two independent checks means a policy deleted by a careless change on e silently open the UI. Leave it empty if your provider has no group model — Krautwatch then admits whoever completes the flow. +The names must be the ones your provider actually puts in the claim, matched case-insensitively. +Krautwatch splits the list on commas only, so `Some Group,Another` works — but a group name is a +value every consumer re-parses with its own rules, and some split on whitespace as well, so +hyphenated names are the safer convention if anything else reads the same claim. + `/setup` stops asking for an administrator under `oidc`: your provider owns identity and no local account is ever created. The rest of the wizard — downloads, egress, `*arr` — still applies. diff --git a/src/Domain/Options/OidcOptions.cs b/src/Domain/Options/OidcOptions.cs index 6d948d2..32434d7 100644 --- a/src/Domain/Options/OidcOptions.cs +++ b/src/Domain/Options/OidcOptions.cs @@ -46,7 +46,7 @@ public sealed class OidcOptions /// /// /// Configuration binds a list from indexed keys (…RequiredGroups__0), which a compose - /// .env has no comfortable way to express. Accepting "Homelab Admins,Media Admins" + /// .env has no comfortable way to express. Accepting "admins,media-users" /// as well means the setting can be written the way every other one in that file is. /// public static List ParseGroups(string? commaSeparated) =>