Jellyfin SSO: cheeztv OIDC hosts, media-group gating, LDAP outpost #28

Merged
benvin merged 2 commits from benvin/jellyfin-sso into main 2026-08-29 11:51:20 +10:00
Member

Summary

  • Adds cheeztv redirect URIs to the shared jellyfin OIDC client and moves its secret read to the fafflix namespace path
  • Gates the jellyfin application on akP-media-fafflix/akP-media-cheeztv; akP-jellyfin-admin/user become role-claim-only groups
  • Adds the jellyfin-ldap LDAP provider + outpost (app-password validation for native clients); resolves LDAP flow slugs to ids in the module

Why

Phase-1 jellyfin auth uses the SSO plugin (browser OIDC) and LDAP plugin (app-passwords) against Authentik; both instances share one OIDC client. After apply, fetch the jellyfin-ldap-outpost token from Authentik and seed kv/kubernetes/namespace/authentik/default/outpost-token (key: token).

## Summary - Adds cheeztv redirect URIs to the shared jellyfin OIDC client and moves its secret read to the fafflix namespace path - Gates the jellyfin application on akP-media-fafflix/akP-media-cheeztv; akP-jellyfin-admin/user become role-claim-only groups - Adds the jellyfin-ldap LDAP provider + outpost (app-password validation for native clients); resolves LDAP flow slugs to ids in the module ## Why Phase-1 jellyfin auth uses the SSO plugin (browser OIDC) and LDAP plugin (app-passwords) against Authentik; both instances share one OIDC client. After apply, fetch the jellyfin-ldap-outpost token from Authentik and seed kv/kubernetes/namespace/authentik/default/outpost-token (key: token).
unkin-agent added 1 commit 2026-08-26 22:16:08 +10:00
Jellyfin SSO: cheeztv OIDC hosts, media-group gating, LDAP outpost
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline failed
3396b399ce
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.
Author
Member

Automated review of unkin/terraform-authentik#28 (head 3396b39).

Code review: no bugs found.

  • providers_oauth2/jellyfin.yaml: three strict redirect URIs, client_secret_vault path, and scope_mappings all match sibling conventions (grafana/litellm).
  • Gating re-scope: akP-media-fafflix/akP-media-cheeztv correctly bind to the jellyfin oauth2 app (key resolves via config.hcl filename-keying, confirmed against modules/authentik/main.tf's authentik_policy_binding.app_access). akP-jellyfin-admin/akP-jellyfin-user are now role-claim-only, still nested correctly under akR-global-admin / akR-standard-user. Grepped README.md and environments/ — no other file references the old binding.
  • providers_ldap/jellyfin-ldap.yaml + modules/authentik/main.tf: the new data.authentik_flow LDAP bind/unbind resolution mirrors the existing oauth2/saml pattern correctly, and the scaffolded authentik_application.ldap / authentik_outpost.ldap (for_each = var.providers_ldap) correctly derive slug jellyfin-ldap / outpost name jellyfin-ldap-outpost from the filename key. No secrets inline.

Issue 1 — KV path mismatch with the parallel argocd PR (doc-only, not in code):
The PR body's "AFTER apply" section says to seed the LDAP outpost token at:

kv/kubernetes/namespace/jellyfin-ldap-outpost/default/outpost-token

This path is not referenced in any terraform/yaml in this repo — it only appears in the PR body and in a code comment that says "see PR body for the exact path" (config/providers_ldap/jellyfin-ldap.yaml). However, per the parallel argocd PR, the outpost's VSS reads its token from kubernetes/namespace/authentik/default/outpost-token, and the namespace-scoped Vault policy backing that VSS can only read namespace/authentik/* paths. Seeding at the body's documented path would put the token somewhere the outpost's Vault policy cannot read it, and the outpost would fail to start with no token. Please correct the body (and the "see PR body" comment's implied target) to kubernetes/namespace/authentik/default/outpost-token to match where the outpost is actually deployed.

Issue 2 — CI plan is currently failing on head 3396b39:
Per Gitea commit status, ci/woodpecker/pr/plan is failure (pre-commit is green). If this run predates the fafflix KV seed (kubernetes/namespace/fafflix/default/oauth-credentials) landing, it's a stale failure from the missing data.vault_kv_secret_v2 read and just needs a retrigger — but that can't be confirmed from commit-status alone. Please confirm the seed is in place and retrigger/re-verify plan is green before merge.

No merge/approve action taken (bot policy).

Automated review of `unkin/terraform-authentik#28` (head `3396b39`). **Code review: no bugs found.** - `providers_oauth2/jellyfin.yaml`: three strict redirect URIs, `client_secret_vault` path, and `scope_mappings` all match sibling conventions (grafana/litellm). - Gating re-scope: `akP-media-fafflix`/`akP-media-cheeztv` correctly bind to the `jellyfin` oauth2 app (key resolves via `config.hcl` filename-keying, confirmed against `modules/authentik/main.tf`'s `authentik_policy_binding.app_access`). `akP-jellyfin-admin`/`akP-jellyfin-user` are now role-claim-only, still nested correctly under `akR-global-admin` / `akR-standard-user`. Grepped `README.md` and `environments/` — no other file references the old binding. - `providers_ldap/jellyfin-ldap.yaml` + `modules/authentik/main.tf`: the new `data.authentik_flow` LDAP bind/unbind resolution mirrors the existing oauth2/saml pattern correctly, and the scaffolded `authentik_application.ldap` / `authentik_outpost.ldap` (`for_each = var.providers_ldap`) correctly derive slug `jellyfin-ldap` / outpost name `jellyfin-ldap-outpost` from the filename key. No secrets inline. **Issue 1 — KV path mismatch with the parallel argocd PR (doc-only, not in code):** The PR body's "AFTER apply" section says to seed the LDAP outpost token at: ``` kv/kubernetes/namespace/jellyfin-ldap-outpost/default/outpost-token ``` This path is **not referenced in any terraform/yaml in this repo** — it only appears in the PR body and in a code comment that says "see PR body for the exact path" (`config/providers_ldap/jellyfin-ldap.yaml`). However, per the parallel argocd PR, the outpost's VSS reads its token from `kubernetes/namespace/authentik/default/outpost-token`, and the namespace-scoped Vault policy backing that VSS can *only* read `namespace/authentik/*` paths. Seeding at the body's documented path would put the token somewhere the outpost's Vault policy cannot read it, and the outpost would fail to start with no token. Please correct the body (and the "see PR body" comment's implied target) to `kubernetes/namespace/authentik/default/outpost-token` to match where the outpost is actually deployed. **Issue 2 — CI plan is currently failing on head `3396b39`:** Per Gitea commit status, `ci/woodpecker/pr/plan` is `failure` (pre-commit is green). If this run predates the fafflix KV seed (`kubernetes/namespace/fafflix/default/oauth-credentials`) landing, it's a stale failure from the missing `data.vault_kv_secret_v2` read and just needs a retrigger — but that can't be confirmed from commit-status alone. Please confirm the seed is in place and retrigger/re-verify plan is green before merge. No merge/approve action taken (bot policy).
unkin-agent added 1 commit 2026-08-26 22:23:39 +10:00
Fix KV path comment in jellyfin-ldap provider configuration.
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/plan Pipeline was successful
9760c2eb3f
Reference the actual Vault KV seed path for outpost token instead of deferring to PR body.
benvin merged commit e397fd909f into main 2026-08-29 11:51:20 +10:00
benvin deleted branch benvin/jellyfin-sso 2026-08-29 11:51:20 +10:00
Sign in to join this conversation.