Jellyfin SSO: cheeztv OIDC hosts, media-group gating, LDAP outpost
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline failed

Completes the Authentik-side plumbing for Jellyfin SSO across both media
instances -- fafflix (adults, jellyfin.k8s.syd1.au.unkin.net) and cheeztv
(kids, cheeztv.unkin.net + cheeztv.k8s.syd1.au.unkin.net) -- and adds an
LDAP outpost so native clients can authenticate with app passwords.

Why: the previously-merged jellyfin OIDC provider only covered the fafflix
host and gated on the generic jellyfin permission groups. cheeztv needs SSO
too, access should be limited to media users, and native (non-browser)
clients need a password-based path.

How:
- providers_oauth2/jellyfin.yaml: one shared confidential client now lists
  strict redirect URIs for all three hosts using the verified
  jellyfin-plugin-sso callback path /sso/OID/redirect/authentik. Client
  secret moved to kv kubernetes/namespace/fafflix/default/oauth-credentials.
- Access is gated to media users only: akP-media-fafflix and akP-media-cheeztv
  now carry `application: jellyfin` and bind to the app; akP-jellyfin-admin /
  akP-jellyfin-user are demoted to pure role-claim groups (no app binding),
  still mapped by the plugin for admin/user rights. Per-instance authz
  (adults -> both, kids -> cheeztv only) stays with the media proxy.
- providers_ldap/jellyfin-ldap.yaml: new LDAP provider (base_dn
  DC=ldap,DC=goauthentik,DC=io, direct bind/search) + application
  (jellyfin-ldap) + outpost (jellyfin-ldap-outpost) via the existing module.
- modules/authentik/main.tf: resolve LDAP bind/unbind flow slugs to ids via
  data.authentik_flow, matching the oauth2/saml convention.
This commit is contained in:
2026-08-26 22:15:28 +10:00
parent 77adee64aa
commit 3396b399ce
7 changed files with 92 additions and 31 deletions
+14 -2
View File
@@ -169,12 +169,24 @@ resource "authentik_provider_oauth2" "this" {
grant_types = each.value.grant_types
}
# Resolve LDAP bind/unbind flows by slug (mirrors the oauth2/saml handling) so
# configs reference human-readable flow slugs instead of Authentik UUIDs.
data "authentik_flow" "ldap_bind" {
for_each = var.providers_ldap
slug = each.value.bind_flow
}
data "authentik_flow" "ldap_unbind" {
for_each = var.providers_ldap
slug = each.value.unbind_flow
}
resource "authentik_provider_ldap" "this" {
for_each = var.providers_ldap
name = each.value.name
bind_flow = each.value.bind_flow
unbind_flow = each.value.unbind_flow
bind_flow = data.authentik_flow.ldap_bind[each.key].id
unbind_flow = data.authentik_flow.ldap_unbind[each.key].id
base_dn = each.value.base_dn
certificate = each.value.certificate
tls_server_name = each.value.tls_server_name