Files
portainer-core/docs/sessions/2025-11-23-admin-sso-setup.md
T

210 lines
6.0 KiB
Markdown

# 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/