Sanitized mirror from private repository - 2026-04-18 11:19:59 UTC
This commit is contained in:
191
docs/services/individual/grafana-oauth.md
Normal file
191
docs/services/individual/grafana-oauth.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# 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=<client_id_from_authentik>
|
||||
- GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=<client_secret_from_authentik>
|
||||
- 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 <token>" \
|
||||
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**
|
||||
Reference in New Issue
Block a user