Initial commit: cleaned project structure

- 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>
This commit is contained in:
2026-01-21 06:15:04 +00:00
commit b428721b07
17 changed files with 5749 additions and 0 deletions

763
ADD-OIDC-INTEGRATIONS.md Normal file
View File

@@ -0,0 +1,763 @@
# 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:**
```bash
# 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:**
```bash
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:**
```bash
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:**
```bash
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:**
```bash
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:**
```bash
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:
```yaml
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:**
```bash
# Add to /srv/docker/guacamole/.env
cat /home/olaf/pangolin/guacamole-oidc-creds.env >> /srv/docker/guacamole/.env
```
**3. Restart Guacamole:**
```bash
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:
```yaml
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:**
```bash
cat /home/olaf/pangolin/openwebui-oidc-creds.env >> /srv/docker/openwebui/.env
```
**3. Restart OpenWebUI:**
```bash
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:**
```bash
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:
```bash
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:**
```bash
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:**
```bash
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:**
```bash
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:**
```bash
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`
```bash
#!/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`
```bash
#!/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