Files
auth/Brain.md
Kroonk 8a4beb879a Initial commit: Keycloak SSO for MischLabs
Keycloak 26.1 + PostgreSQL 16 Docker stack with pre-configured
realm containing 10 OIDC clients for all MischLabs services.
Includes integration guides for Tier 1-3 services.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 20:42:59 +02:00

7.5 KiB

Brain.md - Projekt auth.mischlabs.de (Keycloak SSO)

Projektziel

Zentrales Single Sign-On (SSO) fuer alle MischLabs-Dienste ueber Keycloak. Laeuft als Docker-Container-Stack (Keycloak + PostgreSQL) auf MischNAS und ist ueber Cloudflare Tunnel erreichbar.

Status

  • Git-Repo initialisiert und Remote verbunden (https://git.mischlabs.de/MrDiderot/auth.git)
  • docker-compose.yml mit Keycloak + PostgreSQL erstellt
  • Realm-Konfiguration als JSON (mischlabs-realm.json) mit 10 Clients
  • .env.example und .gitignore erstellt
  • .env mit echten Passwoertern auf der NAS anlegen
  • Erster Push zum Remote (Git-Auth-Fehler, muss manuell gepusht werden)
  • Deployment auf MischNAS (docker compose up -d)
  • Cloudflare Tunnel Route fuer auth.mischlabs.de -> localhost:8180
  • Client Secrets aus Keycloak Admin-Console holen
  • Tier-1-Dienste anbinden (Gitea, Nextcloud, Mealie, Docs)
  • Tier-2-Dienste anbinden (Audiobookshelf, Vaultwarden, PocketBase)
  • Tier-3-Dienste via Cloudflare Access (Jellyfin, MiChess)

Dienste-Integration (9 + Cloudflare Access)

# Client ID Subdomain Tier Status
1 gitea git.mischlabs.de 1 - Nativ OIDC Offen
2 nextcloud drive.mischlabs.de 1 - Nativ OIDC Offen
3 mealie foodlabs.mischlabs.de 1 - Nativ OIDC Offen
4 docs docs.mischlabs.de 1 - Nativ OIDC Offen
5 audiobookshelf audiobook.mischlabs.de 2 - Teilweise Offen
6 vaultwarden password.mischlabs.de 2 - Teilweise Offen
7 pocketbase tom.mischlabs.de 2 - Teilweise Offen
8 jellyfin movies.mischlabs.de 3 - CF Access Offen
9 michess michess.mischlabs.de 3 - CF Access Offen
10 cloudflare-access Cloudflare Zero Trust Proxy-Auth Offen

Integrations-Anleitungen pro Dienst

Tier 1: Native OIDC

Gitea (git.mischlabs.de)

  • Admin > Authentication Sources > Add > OAuth2 > OpenID Connect
  • Client ID: gitea, Secret: aus Keycloak
  • Discovery URL: https://auth.mischlabs.de/realms/mischlabs/.well-known/openid-configuration

Nextcloud (drive.mischlabs.de)

  • App oidc_login installieren, config.php:
    'oidc_login_provider_url' => 'https://auth.mischlabs.de/realms/mischlabs',
    'oidc_login_client_id' => 'nextcloud',
    'oidc_login_client_secret' => '<aus-keycloak>',
    'oidc_login_auto_redirect' => false,
    'oidc_login_button_text' => 'MischLabs SSO',
    

Mealie (foodlabs.mischlabs.de)

  • Environment Variables:
    OIDC_AUTH_ENABLED=true
    OIDC_CONFIGURATION_URL=https://auth.mischlabs.de/realms/mischlabs/.well-known/openid-configuration
    OIDC_CLIENT_ID=mealie
    OIDC_CLIENT_SECRET=<aus-keycloak>
    OIDC_AUTO_REDIRECT=false
    OIDC_PROVIDER_NAME=MischLabs SSO
    OIDC_USER_GROUP=user
    OIDC_ADMIN_GROUP=admin
    

Docs (docs.mischlabs.de) - BookStack Beispiel:

AUTH_METHOD=oidc
OIDC_NAME=MischLabs SSO
OIDC_CLIENT_ID=docs
OIDC_CLIENT_SECRET=<aus-keycloak>
OIDC_ISSUER=https://auth.mischlabs.de/realms/mischlabs
OIDC_ISSUER_DISCOVER=true

Tier 2: Teilweise OIDC

Audiobookshelf (audiobook.mischlabs.de)

  • Settings > Authentication > OpenID Connect
  • Issuer URL: https://auth.mischlabs.de/realms/mischlabs
  • WICHTIG: In Keycloak Admin > audiobookshelf Client > Advanced > User Info Signed Response Algorithm auf leer/none setzen
  • Notfall-Login: https://audiobook.mischlabs.de/login/?autoLaunch=0

Vaultwarden (password.mischlabs.de)

  • Environment Variables:
    SSO_ENABLED=true
    SSO_PKCE=true
    SSO_AUTHORITY=https://auth.mischlabs.de/realms/mischlabs
    SSO_CLIENT_ID=vaultwarden
    SSO_CLIENT_SECRET=<aus-keycloak>
    
  • HINWEIS: Master-Passwort bleibt weiterhin noetig!

PocketBase (tom.mischlabs.de)

  • Admin > Settings > Auth Providers > OIDC konfigurieren
  • Erstellt eigene User-Records, verlinkt mit OAuth2-Identitaet

Tier 3: Cloudflare Access

Jellyfin + MiChess - Kein natives OIDC

  1. In Cloudflare Zero Trust > Settings > Authentication > Add OpenID Connect:
    • App ID: cloudflare-access, Secret: aus Keycloak
    • Auth URL: https://auth.mischlabs.de/realms/mischlabs/protocol/openid-connect/auth
    • Token URL: https://auth.mischlabs.de/realms/mischlabs/protocol/openid-connect/token
    • Certificate URL: https://auth.mischlabs.de/realms/mischlabs/protocol/openid-connect/certs
  2. Access > Applications > Self-hosted > movies.mischlabs.de / michess.mischlabs.de
  3. Policy: Allow > Emails oder Gruppen definieren

Technische Entscheidungen

  • Keycloak 26.1 (quay.io/keycloak/keycloak:26.1) - aktuelles stabiles Release
  • PostgreSQL 16-alpine als Datenbank - leichtgewichtig, bewaehrt
  • Realm-Import via JSON (--import-realm) - versionskontrolliert, reproduzierbar
  • start (nicht start-dev) - Produktionsmodus mit sicheren Defaults
  • KC_PROXY_HEADERS=xforwarded - fuer Cloudflare Tunnel
  • KC_HOSTNAME=https://auth.mischlabs.de - volle URL inkl. Schema
  • KC_HTTP_ENABLED=true - SSL wird von Cloudflare terminiert
  • Port 8180 - vermeidet Konflikte mit bestehenden Diensten
  • PostgreSQL nicht exponiert - nur ueber Docker-Netzwerk erreichbar
  • Client Secrets nicht im JSON - werden von Keycloak auto-generiert

Docker-Setup

  • Container-Namen: auth (Keycloak), auth-db (PostgreSQL)
  • Images: quay.io/keycloak/keycloak:26.1, postgres:16-alpine
  • Port-Mapping: 8180:8080 (Keycloak HTTP), 9000:9000 (Health/Metrics, nur lokal!)
  • Volumes: auth_pgdata (PostgreSQL-Daten), ./realm (Realm-Import, read-only)
  • Netzwerk: auth-network (Bridge, nur intern)
  • Health-Checks: PostgreSQL via pg_isready, Keycloak via /health/ready (Port 9000)

Dateistruktur

auth/
  docker-compose.yml          - Keycloak + PostgreSQL Stack
  .env.example                - Vorlage fuer Secrets (in Git)
  .env                        - Echte Secrets (NICHT in Git!)
  realm/
    mischlabs-realm.json      - Realm mit allen 10 Clients
  Brain.md                    - Dieses Dokument (KI-Uebergabe)
  .gitignore                  - Schliesst .env und .claude/ aus

Deployment-Workflow

  1. Repo auf Gitea erstellen: auth
  2. Code pushen: git push -u origin master
  3. Auf MischNAS:
    cd /volume2/docker
    git clone https://git.mischlabs.de/MrDiderot/auth.git
    cd auth
    cp .env.example .env
    nano .env  # Echte Passwoerter eintragen (openssl rand -base64 32)
    docker compose up -d
    
  4. Cloudflare Tunnel: Route auth.mischlabs.de -> http://localhost:8180
  5. Admin-Console: https://auth.mischlabs.de/admin/mischlabs/console/
  6. Client Secrets holen und in Dienste konfigurieren

Wichtige URLs

Erkenntnisse & Notizen

  • KC_BOOTSTRAP_ADMIN_* wird nur beim allerersten Start verarbeitet
  • Client Secrets muessen nach dem Start aus der Admin-Console geholt werden
  • Audiobookshelf hat bekannte Bugs mit Keycloak (UserInfo Signing Algorithm)
  • Vaultwarden SSO ersetzt NICHT das Master-Passwort (nur Authentifizierung)
  • Jellyfin hat kein natives OIDC - Community-Plugin oder Cloudflare Access
  • Port 9000 NICHT ueber Cloudflare Tunnel exponieren (nur Health/Metrics)
  • Bei Realm-Import: --import-realm ueberspringt bereits existierende Realms
  • Git-Push schlug fehl (Auth-Fehler) - muss manuell mit frischem Token gepusht werden
  • Verwandtes Projekt: mischlabs Landing Page (d:\Vibecoding\Website\mischlabs)