- Consolidated documentation from Ralph Loop iterations - Archived 20+ outdated/superseded files to .archive/ - Kept essential docs: OIDC integration, mobile setup, quick start - Added operational scripts for health monitoring and backup - Research artifacts preserved in .tasks/artifacts/ Current state: - 3 VPS sites (fry, proton, photon) ONLINE in Pangolin - brn-home site pending for local services (Jellyfin, etc.) - Mobile access configuration pending Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
16 KiB
OIDC Integration Guide - Complete Reference
Created: 2026-01-20 21:27:00+00:00 Purpose: Step-by-step guide to add SSO to all deployed platforms
Prerequisites:
- ✅ Authentik admin account created
- ✅ Pangolin admin account created
- ✅ Guacamole password changed
Step-by-Step Integration Process
Phase 1: Create OIDC Providers in Authentik
Login to Authentik Admin: https://sso.obr.sh/if/admin
Provider 1: Pangolin Control Plane
Navigation: Admin → Applications → Providers → Create
Configuration:
Provider Type: OAuth2/OpenID Provider
Name: Pangolin Control Plane
Client Configuration:
Client Type: Confidential
Client ID: (auto-generated - COPY THIS)
Client Secret: (click Show - COPY THIS)
Redirect URIs:
https://tunnel.obr.sh/api/v1/auth/callback
Scopes: (select these)
✓ openid
✓ profile
✓ email
✓ groups
Advanced Protocol Settings:
Token validity: 720 minutes (12 hours)
Signing Key: authentik Self-signed Certificate
Subject mode: Based on User's hashed ID
Click Create
Then create Application:
Name: Pangolin
Provider: (select Pangolin Control Plane provider)
Save Client ID and Secret for later:
# Save to file
cat > /home/olaf/pangolin/pangolin-oidc-creds.env << 'EOF'
PANGOLIN_OIDC_CLIENT_ID=paste_here
PANGOLIN_OIDC_CLIENT_SECRET=paste_here
EOF
chmod 600 /home/olaf/pangolin/pangolin-oidc-creds.env
Provider 2: Guacamole RDP Gateway
Navigation: Admin → Applications → Providers → Create
Configuration:
Provider Type: OAuth2/OpenID Provider
Name: Guacamole RDP Gateway
Client Configuration:
Client Type: Confidential
Client ID: (auto-generated - COPY THIS)
Client Secret: (click Show - COPY THIS)
Redirect URIs:
https://remote.obr.sh/guacamole/
Scopes:
✓ openid
✓ profile
✓ email
Advanced Protocol Settings:
Token validity: 300 minutes (5 hours - Guacamole maximum)
Signing Key: authentik Self-signed Certificate
Click Create
Then create Application:
Name: Guacamole
Provider: (select Guacamole RDP Gateway provider)
Optional: Create MFA Policy:
Admin → Policies → Create
Type: Expression Policy
Name: Require TOTP for Guacamole
Expression: return True # Require MFA for all Guacamole users
Bindings:
Go to Applications → Guacamole → Policy Bindings
Add Binding → Select "Require TOTP for Guacamole"
Save credentials:
cat > /home/olaf/pangolin/guacamole-oidc-creds.env << 'EOF'
GUAC_OIDC_CLIENT_ID=paste_here
GUAC_OIDC_CLIENT_SECRET=paste_here
EOF
chmod 600 /home/olaf/pangolin/guacamole-oidc-creds.env
Provider 3: Jellyfin Media Server
Configuration:
Provider Type: OAuth2/OpenID Provider
Name: Jellyfin Media Server
Client Configuration:
Client Type: Confidential
Client Authentication: client_secret_post (CRITICAL!)
Redirect URIs:
https://video.obnh.io/sso/OID/redirect/Authentik
Scopes:
✓ openid
✓ profile
✓ email
✓ groups
Create Groups for Jellyfin:
Admin → Directory → Groups → Create
Name: jellyfin-admins
Name: jellyfin-users
Save credentials to file:
cat > /home/olaf/pangolin/jellyfin-oidc-creds.env << 'EOF'
JELLYFIN_OIDC_CLIENT_ID=paste_here
JELLYFIN_OIDC_CLIENT_SECRET=paste_here
EOF
Provider 4: OpenWebUI
Configuration:
Provider Type: OAuth2/OpenID Provider
Name: OpenWebUI
Redirect URIs:
https://ll.obr.sh/oauth/oidc/callback
Scopes:
✓ openid
✓ profile
✓ email
✓ groups
Create Groups:
Admin → Directory → Groups → Create
Name: openwebui-admins
Name: openwebui-users
Save credentials:
cat > /home/olaf/pangolin/openwebui-oidc-creds.env << 'EOF'
OPENWEBUI_OIDC_CLIENT_ID=paste_here
OPENWEBUI_OIDC_CLIENT_SECRET=paste_here
EOF
Provider 5: Gitea (fry.obr.sh)
Configuration:
Provider Type: OAuth2/OpenID Provider
Name: Gitea (fry)
Redirect URIs:
https://git.obnh.io/user/oauth2/authentik/callback
Scopes:
✓ openid
✓ profile
✓ email
Save credentials:
cat > /home/olaf/pangolin/gitea-fry-oidc-creds.env << 'EOF'
GITEA_FRY_CLIENT_ID=paste_here
GITEA_FRY_CLIENT_SECRET=paste_here
EOF
Provider 6: Gitea (proton.obr.sh)
Configuration:
Provider Type: OAuth2/OpenID Provider
Name: Gitea (proton)
Redirect URIs:
https://git.proton.obr.sh/user/oauth2/authentik/callback
Scopes:
✓ openid
✓ profile
✓ email
Save credentials:
cat > /home/olaf/pangolin/gitea-proton-oidc-creds.env << 'EOF'
GITEA_PROTON_CLIENT_ID=paste_here
GITEA_PROTON_CLIENT_SECRET=paste_here
EOF
Phase 2: Add OIDC to Deployed Platforms
Pangolin OIDC Integration
After creating Provider 1 in Authentik:
1. Login to Pangolin: https://tunnel.obr.sh
2. Navigate to: Settings → Identity Providers → Add Provider
3. Select: Generic OAuth2/OIDC
4. Configure:
Provider Name: Authentik SSO
Provider Type: Generic OIDC
Discovery URL:
https://sso.obr.sh/application/o/pangolin/.well-known/openid-configuration
Client ID: (from pangolin-oidc-creds.env)
Client Secret: (from pangolin-oidc-creds.env)
Scopes: openid profile email groups
5. Save and Test:
- Logout of Pangolin
- Click "Login with Authentik"
- Should redirect to Authentik
- Login with Authentik credentials
- Should return to Pangolin dashboard
Guacamole OIDC Integration
After creating Provider 2 in Authentik:
1. Update docker-compose.yml:
Add these environment variables to the guacamole service:
environment:
# Existing variables...
GUACD_HOSTNAME: guacd
POSTGRESQL_HOSTNAME: postgres
# ... etc
# Add OIDC configuration:
OPENID_AUTHORIZATION_ENDPOINT: https://sso.obr.sh/application/o/authorize/
OPENID_JWKS_ENDPOINT: https://sso.obr.sh/application/o/guacamole/jwks/
OPENID_ISSUER: https://sso.obr.sh/application/o/guacamole/
OPENID_CLIENT_ID: ${GUAC_OIDC_CLIENT_ID}
OPENID_REDIRECT_URI: https://remote.obr.sh/guacamole/
OPENID_USERNAME_CLAIM_TYPE: preferred_username
OPENID_SCOPE: openid profile email
EXTENSION_PRIORITY: openid
2. Update .env file:
# Add to /srv/docker/guacamole/.env
cat /home/olaf/pangolin/guacamole-oidc-creds.env >> /srv/docker/guacamole/.env
3. Restart Guacamole:
cd /srv/docker/guacamole
sudo docker compose up -d
4. Test SSO Login:
- Go to https://remote.obr.sh/guacamole/
- Should see "Login with SSO" option
- Click it
- Should redirect to Authentik
- Login with Authentik credentials
- Should return to Guacamole dashboard
Phase 3: Service SSO Integrations
Jellyfin SSO Plugin
After creating Provider 3 in Authentik:
1. Install SSO-Auth Plugin:
- Login to Jellyfin: https://video.obnh.io
- Navigate to: Dashboard → Plugins → Catalog
- Find "SSO-Auth" plugin
- Click Install
- Restart Jellyfin when prompted
2. Configure Plugin:
- Dashboard → Plugins → SSO-Auth → Settings
Provider: Generic OpenID
Provider Name: Authentik
OID Endpoint: https://sso.obr.sh/application/o/jellyfin/
Client ID: (from jellyfin-oidc-creds.env)
Client Secret: (from jellyfin-oidc-creds.env)
OID Client Authentication Method: client_secret_post
Enable Authorization by Plugin Default: Yes
Enable All Folders: Yes
Admin Role: jellyfin-admins
User Role: jellyfin-users
Role Claim: groups
3. Test:
- Logout of Jellyfin
- Should see "Sign in with Authentik" button
- Click it
- Login with Authentik
- Should return to Jellyfin
4. Mobile Apps:
- Use Quick Connect (6-digit code pairing)
- OR generate API tokens in Jellyfin dashboard
OpenWebUI OIDC Configuration
After creating Provider 4 in Authentik:
1. Edit OpenWebUI docker-compose.yml:
Add environment variables:
environment:
# Existing variables...
# Add OIDC configuration:
ENABLE_OAUTH_SIGNUP: "true"
OAUTH_MERGE_ACCOUNTS_BY_EMAIL: "true"
OAUTH_CLIENT_ID: ${OPENWEBUI_OIDC_CLIENT_ID}
OAUTH_CLIENT_SECRET: ${OPENWEBUI_OIDC_CLIENT_SECRET}
OPENID_PROVIDER_URL: https://sso.obr.sh/application/o/openwebui/.well-known/openid-configuration
OAUTH_SCOPES: openid profile email groups
# Role management:
ENABLE_OAUTH_ROLE_MANAGEMENT: "true"
OAUTH_ROLES_CLAIM: groups
OAUTH_ADMIN_ROLES: openwebui-admins
2. Update .env:
cat /home/olaf/pangolin/openwebui-oidc-creds.env >> /srv/docker/openwebui/.env
3. Restart OpenWebUI:
cd /srv/docker/openwebui
sudo docker compose restart
4. Test:
- Go to https://ll.obr.sh
- Click "Sign in with SSO"
- Login with Authentik
- Should have admin role if in openwebui-admins group
Gitea OAuth2 Configuration (Both Instances)
After creating Providers 5 & 6 in Authentik:
For Gitea on fry.obr.sh:
1. SSH to fry:
ssh fry.obr.sh
2. Login to Gitea admin:
- URL: https://git.obnh.io
- Login as admin
3. Add Authentication Source:
- Navigate to: Site Administration → Authentication Sources → Add Source
- Type: OAuth2
- Provider: OpenID Connect
Configuration:
Name: Authentik SSO
Provider: OpenID Connect
Client ID: (from gitea-fry-oidc-creds.env)
Client Secret: (from gitea-fry-oidc-creds.env)
Auto Discovery URL:
https://sso.obr.sh/application/o/gitea-fry/.well-known/openid-configuration
Additional Scopes: groups
Required Claim Name: (leave blank)
Group Claim Name: groups
Admin Group: gitea-admins
Restricted Group: (leave blank)
This Source is Activated: ✓
4. Test:
- Logout of Gitea
- Should see "Sign in with Authentik SSO"
- Click and login
- Should create/login user account
Repeat for Gitea on proton.obr.sh with gitea-proton credentials
Phase 4: Configure Pangolin Sites
After Pangolin admin setup complete:
Login to Pangolin Dashboard: https://tunnel.obr.sh
Create Site: brn-home
1. Navigate to: Sites → Create Site
2. Configuration:
Site Name: brn-home
Description: Home LAN services (Jellyfin, OpenWebUI, Transmission, Pi-hole)
Type: Newt Site
3. Deploy Newt Client:
The dashboard will show a connection command like:
docker run -d --name newt --cap-add NET_ADMIN \
-e SITE_TOKEN="<generated_token>" \
-e PANGOLIN_URL="https://tunnel.obr.sh" \
fosrl/newt:latest
Run this on brn to connect local services
Create Resources for brn-home Site
After Newt connected:
Resource 1: Jellyfin
Type: Public Resource (HTTPS)
Name: Jellyfin Media Server
Public Domain: video.obnh.io
Backend Address: jellyfin:8096
Protocol: HTTP
Site: brn-home
Access Control: Authenticated Users
Resource 2: OpenWebUI
Type: Public Resource (HTTPS)
Name: OpenWebUI AI Chat
Public Domain: ll.obr.sh
Backend Address: openwebui:8080
Protocol: HTTP
Site: brn-home
Access Control: Authenticated Users
Resource 3: Transmission
Type: Public Resource (HTTPS)
Name: Transmission
Public Domain: tor.obnh.network
Backend Address: transmission:9091
Protocol: HTTP
Site: brn-home
Access Control: Authenticated Users
Resource 4: Pi-hole
Type: Public Resource (HTTPS)
Name: Pi-hole Admin
Public Domain: dns.obnh.io
Backend Address: host.docker.internal:8080
Protocol: HTTP
Site: brn-home
Access Control: Authenticated Users
Phase 5: Deploy Newt to VPS Hosts
fry.obr.sh (Gitea)
SSH to fry:
ssh fry.obr.sh
Create site in Pangolin dashboard:
Site Name: fry-vps
Description: Gitea hosting
Get Newt connection command from Pangolin
Run on fry:
docker run -d --name newt --restart unless-stopped \
--cap-add NET_ADMIN \
-e SITE_TOKEN="<from_pangolin>" \
-e PANGOLIN_URL="https://tunnel.obr.sh" \
fosrl/newt:latest
Add Resource in Pangolin:
Name: Gitea (fry)
Domain: git.obnh.io
Backend: gitea:3000
Site: fry-vps
Repeat for proton.obr.sh and photon.obr.sh
Phase 6: Restrict Public WAN Access (Final Step)
ONLY after verifying all services work through Pangolin:
Backup Traefik config:
sudo cp /srv/docker/traefik/traefik_dynamic.yaml \
/srv/docker/traefik/traefik_dynamic.yaml.backup-$(date +%Y%m%d)
Edit traefik_dynamic.yaml:
Remove or comment out public routes for:
- video.obnh.io (Jellyfin)
- ll.obr.sh (OpenWebUI)
- tor.obnh.network (Transmission)
Keep public routes for:
- sso.obr.sh (Authentik - must be public for auth)
- tunnel.obr.sh (Pangolin - must be public for tunnels)
- remote.obr.sh (Guacamole - accessible via Pangolin)
- bern.social (Mastodon - public federated)
- git.obnh.io, git.proton.obr.sh (Gitea - public with SSO)
- dns.obnh.io (Pi-hole - for VPS DNS queries)
Reload Traefik:
sudo docker exec traefik kill -SIGHUP 1
# Or: docker compose restart (brief downtime)
Test:
- From internet: Jellyfin/OpenWebUI should be unreachable
- From Pangolin tunnel: Should work normally
Automated Integration Scripts
Script 1: Add OIDC to Pangolin
File: /home/olaf/pangolin/scripts/integrate-pangolin-oidc.sh
#!/bin/bash
# Read credentials
source /home/olaf/pangolin/pangolin-oidc-creds.env
# Update Pangolin config.yml
cat >> /srv/docker/pangolin/config/config.yml << EOF
# OIDC Integration added: $(date -Iseconds)
identity_providers:
- type: oidc
name: Authentik SSO
discovery_url: https://sso.obr.sh/application/o/pangolin/.well-known/openid-configuration
client_id: ${PANGOLIN_OIDC_CLIENT_ID}
client_secret: ${PANGOLIN_OIDC_CLIENT_SECRET}
scopes:
- openid
- profile
- email
- groups
EOF
# Restart Pangolin
cd /srv/docker/pangolin
sudo docker compose restart pangolin
echo "✅ Pangolin OIDC integration added"
echo "Test at: https://tunnel.obr.sh"
Script 2: Add OIDC to Guacamole
File: /home/olaf/pangolin/scripts/integrate-guacamole-oidc.sh
#!/bin/bash
# Read credentials
source /home/olaf/pangolin/guacamole-oidc-creds.env
# Add to environment file
cat >> /srv/docker/guacamole/.env << EOF
# OIDC Integration added: $(date -Iseconds)
GUAC_OIDC_CLIENT_ID=${GUAC_OIDC_CLIENT_ID}
EOF
# Update docker-compose.yml (manual edit needed)
echo "⚠️ Manual step required:"
echo "Edit /srv/docker/guacamole/docker-compose.yml"
echo "Add OPENID_ environment variables"
echo "See: /home/olaf/pangolin/ADD-OIDC-INTEGRATIONS.md Phase 2"
echo "Then run:"
echo "cd /srv/docker/guacamole && sudo docker compose up -d"
Verification Checklist
After completing all integrations:
- Pangolin SSO login works
- Guacamole SSO login works (MFA if configured)
- Jellyfin web SSO works
- Jellyfin mobile Quick Connect works
- OpenWebUI SSO works with admin role
- Gitea fry SSO works
- Gitea proton SSO works
- Services unreachable from public WAN (if restricted)
- Services accessible via Pangolin tunnel
- LAN access still works for all services
- WAN internet routing still works
Troubleshooting
OIDC Login Fails
Check:
- Redirect URI matches exactly in Authentik provider
- Client ID and Secret are correct
- Discovery URL is accessible:
curl https://sso.obr.sh/application/o/<app>/.well-known/openid-configuration - Scopes include at minimum: openid, profile, email
Services Not Accessible
Through Pangolin:
- Check Newt client connected in Pangolin dashboard
- Verify resource backend address correct
- Check site is online
From LAN:
- Should still work (direct access)
- Check Traefik dynamic config not removed
Mobile Apps
Jellyfin:
- Use Quick Connect (web login + 6-digit code)
- OR API tokens (Settings → API Keys)
Pangolin:
- Install Pangolin mobile app
- Connect to tunnel.obr.sh
- Login with Authentik credentials
Summary
This guide provides:
- Complete OIDC provider creation steps (6 providers)
- Platform integration configurations (Pangolin, Guacamole)
- Service integration steps (Jellyfin, OpenWebUI, Gitea)
- Pangolin site/resource configuration
- Newt client deployment
- Traefik restriction procedure
- Verification checklist
- Troubleshooting guidance
Use this after completing platform setup wizards.
File: /home/olaf/pangolin/ADD-OIDC-INTEGRATIONS.md
Ready for: After admin accounts created on all platforms