Add comprehensive documentation for VPS setup and configuration including: - Project instructions - VPS1 starting point configuration - VPS1 current state documentation - VPS1 todo list Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
20 KiB
SSO Integration Plan: Gitea & Immich with Netbird Zitadel
Date: 2026-01-25 Status: Planning Phase Identity Provider: Netbird Zitadel (https://nb.phiiiil.de)
Executive Summary
This plan details the integration of Gitea and Immich with the existing Netbird Zitadel Identity Provider for centralized Single Sign-On (SSO) authentication.
Benefits:
- Unified authentication across all services
- Centralized user management via Netbird dashboard
- No need to remember multiple passwords
- Secure OAuth2/OIDC flow with PKCE
- Easy user provisioning and deprovisioning
Prerequisites
Infrastructure ✅
- Netbird running with Zitadel at https://nb.phiiiil.de
- Gitea deployed at https://git.phiiiil.de (OAuth2 already enabled)
- Immich deployed at https://immich.phiiiil.de
- DNS records configured and SSL certificates active
- OIDC discovery endpoint accessible: https://nb.phiiiil.de/.well-known/openid-configuration
Access Required
- Netbird admin credentials (to access Zitadel console)
- Gitea admin credentials (user:
phil, password:j8bKvIl3AtIp5aTG) - Immich admin credentials
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ User Browser │
└────────────────────┬────────────────────────────────────────┘
│
│ 1. Click "Login with SSO"
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Gitea/Immich (Application) │
│ - Redirects to Zitadel │
│ - Client ID & Client Secret │
└────────────────────┬────────────────────────────────────────┘
│
│ 2. OAuth2 Authorization Request
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Netbird Zitadel (Identity Provider) │
│ - Authenticates user │
│ - Issues authorization code │
│ - Returns to application with code │
└────────────────────┬────────────────────────────────────────┘
│
│ 3. Exchange code for tokens
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Application validates tokens & creates user session │
└─────────────────────────────────────────────────────────────┘
Phase 1: Zitadel Configuration
Step 1.1: Access Zitadel Console
- Navigate to https://nb.phiiiil.de
- Login with Netbird admin credentials
- Access Zitadel console via https://nb.phiiiil.de/ui
Note: The first access may require setting up the Zitadel admin account if not already done.
Step 1.2: Create Gitea OIDC Application
1.2.1 Create Project
- Go to Projects → New Project
- Configure:
- Name:
Gitea - Project Role: Select/create appropriate role
- Name:
- Click Create
- Note the Project ID for reference
1.2.2 Create Application
- Navigate to the new Gitea project
- Go to Applications → New
- Configure:
- Application Name:
gitea - Application Type: Web Application
- Redirect URIs:
https://git.phiiiil.de/user/oauth2/zitadel/callback
- Post Logout URIs:
https://git.phiiiil.de/
- Authentication Method: PKCE (recommended)
- Scopes:
openid profile email
- Application Name:
- Click Continue
1.2.3 Save Credentials
After creating, save the following in a secure location:
- Client ID: (will be displayed)
- Client Secret: (click "Reveal" to copy)
Store these securely - they will be needed for Gitea configuration.
Step 1.3: Create Immich OIDC Application
1.3.1 Create Project
- Go to Projects → New Project
- Configure:
- Name:
Immich - Project Role: Select/create appropriate role
- Name:
- Click Create
- Note the Project ID for reference
1.3.2 Create Application
- Navigate to the new Immich project
- Go to Applications → New
- Configure:
- Application Name:
immich - Application Type: Web Application
- Redirect URIs:
https://immich.phiiiil.de/auth/loginhttps://immich.phiiiil.de/user-settings
- Post Logout URIs:
https://immich.phiiiil.de/
- Authentication Method: PKCE
- Scopes:
openid profile email
- Application Name:
- Click Continue
1.3.3 Save Credentials
- Client ID: (will be displayed)
- Client Secret: (click "Reveal" to copy)
Phase 2: Gitea Configuration
Step 2.1: Access Gitea Admin Panel
- Navigate to https://git.phiiiil.de
- Login with admin credentials:
- Username:
phil - Password:
j8bKvIl3AtIp5aTG
- Username:
Step 2.2: Configure OAuth2 Authentication
Via Web UI:
- Go to Administration (gear icon → Authentication Sources)
- Click Add Authentication Source → OAuth2
- Configure:
Authentication Name: Netbird Zitadel OAuth2 Provider: OpenID Connect Client ID: [from Zitadel Step 1.2.3] Client Secret: [from Zitadel Step 1.2.3] OpenID Connect Discovery Endpoint: https://nb.phiiiil.de/.well-known/openid-configuration Auto-discover Email Address: ✅ Enabled Scopes: openid profile email Email Authentication Field: Email Update Avatar: ✅ Enabled Group Claims: (optional, leave empty) - Click Create Authentication Source
Step 2.3: Configure User Settings
Via Web UI:
- Go to Site Administration → Authentication
- Enable:
- Show "Sign In" button on login page
- Automatically create users for OAuth2
- Hide login form if only OAuth2 is available (optional)
- Click Save
Verify Configuration:
# Check Gitea logs for any OAuth errors
docker logs gitea | grep -i oauth
Step 2.4: Test Gitea SSO
- Logout of Gitea
- Go to https://git.phiiiil.de
- Click Sign In with Netbird Zitadel
- You should be redirected to Zitadel login
- Authenticate with Netbird credentials
- Should be redirected back to Gitea, logged in
Expected Result:
- User is created automatically in Gitea
- Email address synced from Zitadel
- Avatar updated (if available in Zitadel)
Phase 3: Immich Configuration
Step 3.1: Access Immich Admin Panel
- Navigate to https://immich.phiiiil.de
- Login with admin credentials
Step 3.2: Configure OAuth2
Via Web UI:
- Go to Administration → Settings → Authentication
- Under OAuth, click Enable or Add OAuth
- Configure:
OAuth Button Display Name: Login with Netbird OAuth Button Link URL: [auto-generated] Client ID: [from Zitadel Step 1.3.3] Client Secret: [from Zitadel Step 1.3.3] Issuer URL: https://nb.phiiiil.de Authorization Endpoint: https://nb.phiiiil.de/oauth/v2/authorize Token Endpoint: https://nb.phiiiil.de/oauth/v2/token User Info Endpoint: https://nb.phiiiil.de/oidc/v1/userinfo Scope: openid profile email Auto Registering: ✅ Enabled Auto Linking: ✅ Enabled Storage Label Claim: email - Click Save
Alternative: Via Environment Variables
Edit /home/phil/docker/immich-app/.env and add:
# OAuth2/OIDC Configuration
IMMICH_OAUTH_ENABLED=true
IMMICH_OAUTH_BUTTON_TEXT="Login with Netbird"
IMMICH_OAUTH_ISSUER_URL=https://nb.phiiiil.de
IMMICH_OAUTH_CLIENT_ID=[from Zitadel]
IMMICH_OAUTH_CLIENT_SECRET=[from Zitadel]
IMMICH_OAUTH_AUTO_REGISTER=true
IMMICH_OAUTH_STORAGE_LABEL_CLAIM=email
IMMICH_OAUTH_SCOPE=openid profile email
Then restart Immich:
cd /home/phil/docker/immich-app
docker compose restart immich-server
Step 3.3: Test Immich SSO
- Logout of Immich
- Go to https://immich.phiiiil.de
- Click Login with Netbird
- Authenticate with Netbird credentials
- Should be redirected back to Immich, logged in
Expected Result:
- User is created automatically in Immich
- Email address synced from Zitadel
- User can access their photo library
Phase 4: Testing & Verification
Step 4.1: Gitea Verification
Test Checklist:
- Login page shows "Sign In with Netbird Zitadel" button
- Clicking button redirects to Zitadel login
- After authentication, user is logged into Gitea
- User profile shows correct email from Zitadel
- User avatar is imported (if available)
- Logout works correctly
- Can login again with SSO
Verify User Sync:
# Check Gitea database for new user
docker exec -it gitea-db psql -U gitea -d gitea -c "SELECT * FROM user WHERE login_name LIKE '%@%';"
Step 4.2: Immich Verification
Test Checklist:
- Login page shows "Login with Netbird" button
- Clicking button redirects to Zitadel login
- After authentication, user is logged into Immich
- User can access photos
- User settings show correct email from Zitadel
- Logout works correctly
- Can login again with SSO
Verify User Creation:
# Check Immich database for OAuth user
docker exec -it immich_postgres psql -U postgres -d immich -c "SELECT id, email, oauthId FROM \"user\" WHERE email LIKE '%@%';"
Step 4.3: Cross-Service Testing
Test that:
- Logging into Zitadel automatically logs into both Gitea and Immich (single sign-on)
- Logout from one service doesn't affect other services
- New users created in Zitadel can access both applications
Phase 5: Security Configuration
Step 5.1: Enable HTTPS Only
Gitea:
- Already enforced via Caddy reverse proxy
- Ensure
GITEA__server__PROTOCOL=httpsis set (should be)
Immich:
- Already enforced via Caddy reverse proxy
Step 5.2: Configure Token Expiration
In Zitadel:
- Go to Settings → Token Configuration
- Set reasonable token lifetimes:
- Access Token: 1 hour
- Refresh Token: 30 days
- ID Token: 1 hour
Step 5.3: Enable PKCE
Verify both applications are using PKCE:
- Gitea: ✅ Already configured in Zitadel
- Immich: ✅ Supported via OAuth2 flow
Step 5.4: Review Scopes
Minimal recommended scopes:
openid- Required for OIDCprofile- User name and basic infoemail- Email address for user identification
Optional scopes:
groups- Group membership (not currently used)address- Physical address (not needed)phone- Phone number (not needed)
Phase 6: Backup & Rollback
Pre-Integration Backup
Before starting, run a full backup:
/home/phil/docker/backup/backup.sh
Verify backup completed:
ls -lah /mnt/backup/latest/
Rollback Procedures
If Gitea SSO fails:
- Login with local admin account (
phil/j8bKvIl3AtIp5aTG) - Go to Administration → Authentication Sources
- Delete the Netbird Zitadel OAuth source
- Users can still login with local passwords
If Immich SSO fails:
- Login with local admin account
- Go to Administration → Settings → Authentication
- Disable OAuth or remove the configuration
- Restart Immich:
cd /home/phil/docker/immich-app docker compose restart immich-server
Complete rollback:
# Restore Gitea database
gunzip < /mnt/backup/latest/gitea-db.sql.gz | docker exec -i gitea-db psql -U gitea gitea
# Restore Immich database
gunzip < /mnt/backup/latest/immich-db.sql.gz | docker exec -i immich_postgres psql -U postgres immich
Phase 7: User Migration
Option A: Manual Migration (Recommended for Small Teams)
- Create user accounts in Zitadel with same email addresses
- Users login via SSO
- Applications automatically create user accounts
- Manual data association may be needed (repositories, photos, etc.)
Option B: Automated Mapping
For Gitea:
- Set up email matching between Git local users and Zitadel users
- Enable Automatically create users for OAuth2
- First OAuth login will create new Gitea account
- Manual migration of repositories may be needed
For Immich:
- Enable Auto Registering and Auto Linking
- First OAuth login will create new Immich account
- WARNING: Photos are tied to user accounts - migration may be complex
- Consider testing with a test user first
Phase 8: Documentation & Maintenance
Step 8.1: Update Documentation
Update /home/phil/Schreibtisch/Privat/vps/vps1-state-25012026.md:
- Add SSO configuration section
- Document Client IDs (encrypted) and where they're stored
- Add troubleshooting section
Update /home/phil/Schreibtisch/Privat/vps/docs/deployment-summary.md:
- Mark OIDC SSO as completed
- Add SSO URLs to quick reference
Step 8.2: Maintenance Tasks
Monthly:
- Review OAuth2 token usage in Zitadel
- Check for failed authentication attempts
- Review user access
Quarterly:
- Rotate client secrets (recommended)
- Review and update scopes
- Audit user access
Implementation Checklist
Pre-Implementation
- Create full backup of all databases
- Verify backup integrity
- Document current authentication state
- Prepare rollback procedures
Zitadel Configuration
- Access Zitadel console
- Create Gitea project
- Create Gitea application
- Save Gitea Client ID and Secret
- Create Immich project
- Create Immich application
- Save Immich Client ID and Secret
Gitea Integration
- Configure OAuth2 in Gitea admin
- Enable auto-user creation
- Test Gitea SSO login
- Verify user creation
- Test Gitea logout
Immich Integration
- Configure OAuth2 in Immich admin
- Enable auto-user registration
- Test Immich SSO login
- Verify user creation
- Test Immich logout
Testing & Verification
- Test Gitea SSO full flow
- Test Immich SSO full flow
- Test cross-service SSO
- Verify user data sync
- Test logout functionality
Documentation
- Update vps1-state-25012026.md
- Update deployment-summary.md
- Document Client IDs securely
- Create user guide for SSO login
Troubleshooting
Issue: "Invalid redirect URI"
Symptoms:
- Error in Zitadel logs about redirect URI mismatch
- OAuth flow fails during redirect
Solution:
- Check exact redirect URI in application logs
- Compare with Zitadel application configuration
- Ensure protocol (http vs https) matches
- Ensure no trailing slashes
Gitea correct URI: https://git.phiiiil.de/user/oauth2/zitadel/callback
Immich correct URI: https://immich.phiiiil.de/auth/login
Issue: "Client authentication failed"
Symptoms:
- Token endpoint returns 401 Unauthorized
- Error about invalid client_secret
Solution:
- Verify Client ID matches exactly
- Reveal and copy Client Secret again from Zitadel
- Check for extra spaces or characters
- Regenerate Client Secret in Zitadel if needed
Issue: "User not created automatically"
Symptoms:
- OAuth login succeeds but no user created
- User sees "Access denied" or similar
Solution:
Gitea:
- Go to Authentication → Enable "Automatically create users"
- Check for email conflicts with existing users
Immich:
- Enable Auto Registering in OAuth settings
- Enable Auto Linking to match existing users by email
Issue: "Discovery endpoint not accessible"
Symptoms:
- Application cannot fetch OIDC configuration
- Error connecting to
https://nb.phiiiil.de/.well-known/openid-configuration
Solution:
- Check Caddy is running:
docker ps | grep caddy - Test endpoint manually:
curl https://nb.phiiiil.de/.well-known/openid-configuration - Check Caddy logs:
docker logs netbird-caddy-1 | grep openid - Verify firewall allows connection to port 443
Issue: "Avatar not syncing"
Symptoms:
- User logs in successfully but avatar not updated
Solution:
Gitea:
- Enable Update Avatar in OAuth configuration
- Ensure Zitadel profile includes avatar URL
- Check Gitea logs for avatar fetch errors
Immich:
- Avatar may need manual upload after first login
- Immich doesn't always fetch avatar from IdP
Success Criteria
The integration will be considered successful when:
-
Gitea:
- Users can login via "Sign In with Netbird Zitadel"
- User accounts are created automatically
- Email addresses are synced from Zitadel
- Existing functionality (repositories, SSH) still works
-
Immich:
- Users can login via "Login with Netbird"
- User accounts are created automatically
- Email addresses are synced from Zitadel
- Photo access and functionality preserved
-
Security:
- All authentication uses OAuth2/OIDC with PKCE
- HTTPS enforced for all communications
- Token lifetimes are reasonable
- No security warnings in browser console
-
Usability:
- Login process takes < 10 seconds
- Single sign-on works across services
- Logout works correctly
- User experience is intuitive
Timeline Estimate
- Phase 1 (Zitadel Config): 30 minutes
- Phase 2 (Gitea Config): 20 minutes
- Phase 3 (Immich Config): 20 minutes
- Phase 4 (Testing): 30 minutes
- Phase 5 (Security Config): 15 minutes
- Phase 6 (Backups): 10 minutes
- Phase 7 (User Migration): Variable (depends on users)
- Phase 8 (Documentation): 30 minutes
Total: ~2.5 hours (excluding user migration)
Post-Implementation Tasks
-
Monitor logs for first 24-48 hours:
# Gitea OAuth logs docker logs gitea | grep -i oauth # Immich OAuth logs docker logs immich_server | grep -i oauth # Caddy/OAuth routing logs docker logs netbird-caddy-1 | grep -i oauth -
Check Zitadel dashboard regularly:
- Active sessions
- Failed login attempts
- Token issuance
-
User feedback:
- Gather user experience feedback
- Document any issues or improvements needed
Appendix: OAuth2 Endpoints Reference
Zitadel (Netbird):
- Issuer:
https://nb.phiiiil.de - Discovery:
https://nb.phiiiil.de/.well-known/openid-configuration - Authorization:
https://nb.phiiiil.de/oauth/v2/authorize - Token:
https://nb.phiiiil.de/oauth/v2/token - UserInfo:
https://nb.phiiiil.de/oidc/v1/userinfo - JWKS:
https://nb.phiiiil.de/oauth/v2/keys - End Session:
https://nb.phiiiil.de/oidc/v1/end_session
Application Redirect URIs:
- Gitea:
https://git.phiiiil.de/user/oauth2/zitadel/callback - Immich:
https://immich.phiiiil.de/auth/login
Notes
- This plan assumes Netbird admin access is available
- Client secrets should be stored securely (consider using a password manager)
- Test with a test user first before migrating all users
- Immich user migration may require additional consideration for photo ownership
- Gitea SSH key access is independent of OAuth and continues to work
Document Version: 1.0 Last Updated: 2026-01-25 Status: Ready for Implementation