# Grafana OAuth2 with Authentik **Host**: Homelab VM (192.168.0.210) **Domain**: `gf.vish.gg` **Port**: 3300 **Compose File**: `homelab_vm/monitoring.yaml` **Status**: ✅ Working ## Overview Grafana is configured to use Authentik OAuth2 for Single Sign-On (SSO). This allows users to log in with their Authentik credentials while maintaining local admin access. ## Authentication Methods 1. **Local Login** - Username/password form (admin/admin by default) 2. **OAuth2 SSO** - "Sign in with Authentik" button ## Architecture ``` User Browser │ ▼ ┌─────────────────┐ │ Cloudflare │ │ (gf.vish.gg) │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ NPM (Calypso) │ ← Direct proxy, NO forward auth │ Port 443 │ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Grafana │ │ 192.168.0.210 │ │ Port 3300 │ └────────┬────────┘ │ │ OAuth2 Flow ▼ ┌─────────────────┐ │ Authentik │ │ sso.vish.gg │ │ Port 9000 │ └─────────────────┘ ``` ## Important: OAuth2 vs Forward Auth **DO NOT** use Authentik Forward Auth (proxy provider) for Grafana. Grafana has native OAuth2 support which provides: - Role mapping based on Authentik groups - Proper session management - User identity within Grafana Forward Auth intercepts requests before they reach Grafana, preventing the OAuth2 flow from working. ## Configuration ### Authentik Setup 1. **Create OAuth2/OpenID Provider** in Authentik: - Name: `Grafana OAuth2` - Client Type: Confidential - Client ID: `lEGw1UJ9Mhk6QVrNA61rAsr59Kel9gAvdPQ1FAJA` - Redirect URIs: `https://gf.vish.gg/login/generic_oauth` 2. **CRITICAL: Add Scope Mappings** to the provider: - `authentik default OAuth Mapping: OpenID 'openid'` - `authentik default OAuth Mapping: OpenID 'email'` - `authentik default OAuth Mapping: OpenID 'profile'` Without these, Authentik won't return email/name claims and Grafana will fail with "InternalError". 3. **Create Application** in Authentik: - Name: `Grafana` - Slug: `grafana` - Provider: Select the OAuth2 provider created above ### Grafana Environment Variables ```yaml environment: # OAuth2 SSO Configuration - GF_AUTH_GENERIC_OAUTH_ENABLED=true - GF_AUTH_GENERIC_OAUTH_NAME=Authentik - GF_AUTH_GENERIC_OAUTH_CLIENT_ID= - GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET= - GF_AUTH_GENERIC_OAUTH_SCOPES=openid profile email - GF_AUTH_GENERIC_OAUTH_AUTH_URL=https://sso.vish.gg/application/o/authorize/ - GF_AUTH_GENERIC_OAUTH_TOKEN_URL=https://sso.vish.gg/application/o/token/ - GF_AUTH_GENERIC_OAUTH_API_URL=https://sso.vish.gg/application/o/userinfo/ - GF_AUTH_SIGNOUT_REDIRECT_URL=https://sso.vish.gg/application/o/grafana/end-session/ # CRITICAL: Attribute paths to extract user info from Authentik response - GF_AUTH_GENERIC_OAUTH_EMAIL_ATTRIBUTE_PATH=email - GF_AUTH_GENERIC_OAUTH_LOGIN_ATTRIBUTE_PATH=preferred_username - GF_AUTH_GENERIC_OAUTH_NAME_ATTRIBUTE_PATH=name # Role mapping based on Authentik groups - GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH=contains(groups[*], 'Grafana Admins') && 'Admin' || contains(groups[*], 'Grafana Editors') && 'Editor' || 'Viewer' # Additional recommended settings - GF_AUTH_GENERIC_OAUTH_USE_PKCE=true - GF_AUTH_GENERIC_OAUTH_ALLOW_ASSIGN_GRAFANA_ADMIN=true # Required for OAuth callbacks - GF_SERVER_ROOT_URL=https://gf.vish.gg ``` ### NPM (Nginx Proxy Manager) Setup The proxy host for `gf.vish.gg` should: - Forward to `192.168.0.210:3300` - **NOT** have any Authentik forward auth configuration - Enable WebSocket support (for Grafana Live) - Enable SSL **Advanced Config should be EMPTY** - no auth_request directives. ### Role Mapping Create these groups in Authentik and add users: - `Grafana Admins` → Admin role in Grafana - `Grafana Editors` → Editor role in Grafana - No group → Viewer role (default) ## Troubleshooting ### "InternalError" after OAuth login **Cause 1**: Missing scope mappings in Authentik provider. **Solution**: In Authentik Admin → Providers → Grafana OAuth2 → Edit: - Add scope mappings for `openid`, `email`, `profile` Verify scopes are configured: ```bash curl https://sso.vish.gg/application/o/grafana/.well-known/openid-configuration | jq '.scopes_supported' # Should include: ["openid", "email", "profile"] ``` **Cause 2**: Missing email attribute path in Grafana config. **Solution**: Ensure these env vars are set: ``` GF_AUTH_GENERIC_OAUTH_EMAIL_ATTRIBUTE_PATH=email GF_AUTH_GENERIC_OAUTH_LOGIN_ATTRIBUTE_PATH=preferred_username ``` ### Redirect loop between Grafana and Authentik **Cause**: Forward Auth is configured in NPM alongside OAuth2. **Solution**: Remove the Authentik forward auth config from NPM's Advanced Config for gf.vish.gg. ### Check Grafana logs ```bash docker logs grafana --tail 100 2>&1 | grep -i "oauth\|error" ``` ### Test Authentik userinfo endpoint ```bash curl https://sso.vish.gg/application/o/userinfo/ # Should return REDACTED_APP_PASSWORD when authenticated ``` ### Verify OAuth provider configuration via API ```bash # Check provider has scope mappings curl -H "Authorization: Bearer " \ https://sso.vish.gg/api/v3/providers/oauth2/1/ | jq '.property_mappings' # Should NOT be empty ``` ## Related Documentation - [Authentik Service](./authentik.md) - [Grafana Generic OAuth Docs](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/) - [Authentik Grafana Integration](https://docs.goauthentik.io/integrations/services/grafana/) ## Change Log - **2026-01-31**: Initial OAuth2 setup, removed forward auth from NPM - **2026-01-31**: Added email/login/name attribute paths to fix userinfo parsing - **2026-01-31**: Added scope mappings (openid, email, profile) to Authentik provider - **THIS WAS THE FIX**