# Admin-Level SSO Setup Guide **Date:** 2025-11-23 **Objective:** Create separate user-level and admin-level SSO providers for proper access control ## Overview This guide sets up a two-tier SSO architecture: - **User Services Proxy** - For general authenticated access (Organizr) - **Admin Services Proxy** - For administrative interfaces (Core API, future admin tools) ## Prerequisites - Authentik accessible at https://auth.schweitz.net - Admin credentials: akadmin / yzXAhiBAggPB5cz - Standalone outpost running on port 9445 ## Step 1: Create Admin Group 1. Navigate to https://auth.schweitz.net 2. Log in as `akadmin` 3. Go to **Directory** → **Groups** 4. Click **Create** 5. Fill in: - **Name:** `homelab-admins` - **Parent:** (none) - Click **Create** 6. Click on the new `homelab-admins` group 7. Go to **Users** tab 8. Click **Add existing user** 9. Select your user (jpmschweitzer@gmail.com) 10. Click **Add** ## Step 2: Create Admin Authorization Policy 1. Go to **Customization** → **Policies** 2. Click **Create** → **Group Membership Policy** 3. Fill in: - **Name:** `Admin Group Required` - **Groups:** Select `homelab-admins` - Click **Create** ## Step 3: Create Admin Proxy Provider 1. Go to **Applications** → **Providers** 2. Click **Create** → **Proxy Provider** 3. Fill in: - **Name:** `Admin Services Proxy` - **Authorization flow:** `default-provider-authorization-implicit-consent` - **Mode:** `Forward auth (single application)` - **External host:** `https://api.schweitz.net` - **Cookie domain:** `.schweitz.net` - **Token validity:** `hours=8` - Click **Next** 4. On Policy Bindings page: - Click **Bind existing policy** - Select `Admin Group Required` - **Order:** 0 - Click **Create** ## Step 4: Create Core API Application 1. Go to **Applications** → **Applications** 2. Click **Create** 3. Fill in: - **Name:** `Core API` - **Slug:** `core-api` - **Provider:** Select `Admin Services Proxy` - **Launch URL:** `https://api.schweitz.net` - **Policy engine mode:** `all` (require all policies to pass) - Click **Create** ## Step 5: Assign Provider to Standalone Outpost 1. Go to **Applications** → **Outposts** 2. Click on **Outpost Standalone Proxy Outpost** 3. In the **Applications** field, you should see `Organizr` 4. Add `Core API` to the applications list 5. Click **Update** 6. Wait 10-20 seconds for the outpost to reconnect 7. Check logs: `docker logs authentik-proxy --tail 50` - Should see: "WebSocket connected" and no errors ## Step 6: Verify NPM Configuration The NPM config for `api.schweitz.net` should already be correct: ```nginx # Forward auth to standalone outpost auth_request /outpost.goauthentik.io/auth/nginx; # Outpost proxy location location /outpost.goauthentik.io { proxy_pass https://localhost:9445/outpost.goauthentik.io; # ... rest of config } ``` **No changes needed to NPM** - The outpost automatically handles routing to the correct provider based on the external host. ## Step 7: Test Admin Access 1. **Test in incognito window:** ```bash # Open incognito window https://api.schweitz.net/docs ``` 2. **Expected flow:** - Redirects to https://auth.schweitz.net - Shows Google OAuth login - After authentication, checks group membership - If in `homelab-admins` group → allows access - If NOT in group → shows "Access Denied" or "Insufficient Permissions" 3. **Verify headers are passed:** ```bash # After logging in, check developer tools → Network → Headers # Should see X-authentik-groups containing "homelab-admins" ``` ## Step 8: Rename Organizr Provider (Optional) For consistency, rename the existing provider: 1. Go to **Applications** → **Providers** 2. Click on `Organizr Proxy` 3. Change **Name** to `User Services Proxy` 4. Click **Update** ## Architecture Diagram ``` User → https://api.schweitz.net ↓ NPM: Forward auth check ↓ Standalone Outpost (port 9445) ↓ Authentik: Check which provider matches external host ↓ Provider: "Admin Services Proxy" (for api.schweitz.net) ↓ Policy: "Admin Group Required" ↓ ✅ User in homelab-admins → Allow ❌ User NOT in group → Deny (403) ``` ## Verification Checklist - [ ] Admin group `homelab-admins` created - [ ] Your user added to `homelab-admins` group - [ ] Policy `Admin Group Required` created - [ ] Provider `Admin Services Proxy` created with policy binding - [ ] Application `Core API` created and linked to provider - [ ] Outpost has both `Organizr` and `Core API` applications assigned - [ ] Outpost logs show successful WebSocket connection - [ ] Test access to https://api.schweitz.net/docs requires auth - [ ] After auth, access is granted (user is in admin group) - [ ] X-authentik-groups header contains `homelab-admins` ## Troubleshooting ### Issue: "Access Denied" even though user is in admin group **Check:** ```bash # Verify policy is bound to provider curl -s -H "Authorization: Bearer 9blMGz71CFMJszs7AedQefgydpTnwvybjmMn0AlYilIKBV5LIq7snqnCodwX" \ https://auth.schweitz.net/api/v3/providers/proxy/ | \ python3 -m json.tool | grep -A 20 "Admin Services" ``` ### Issue: Outpost not picking up new provider **Fix:** ```bash # Restart outpost docker restart authentik-proxy # Check logs docker logs authentik-proxy --tail 100 ``` ### Issue: Still using old provider **Check:** ```bash # Verify external host is EXACTLY "https://api.schweitz.net" (no trailing slash) # Authentik matches providers by exact external host match ``` ## Next Steps After admin SSO is working: 1. Mark Milestone 4 as complete in STATUS.md 2. Continue to Milestone 5: Protect remaining services - git.schweitz.net (Gitea) → Admin provider - amp.schweitz.net (AMP) → User provider - tatlock.schweitz.net → User provider 3. Update CHANGELOG.md with 0.8.3-admin-sso version ## Reference - Authentik Proxy Provider Docs: https://docs.goauthentik.io/docs/providers/proxy/ - Group Policies: https://docs.goauthentik.io/docs/policies/expression/ - Outpost Configuration: https://docs.goauthentik.io/docs/outposts/