Files
homelab-optimized/docs/services/individual/grafana-oauth.md
Gitea Mirror Bot 4c8d376e9b
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m2s
Documentation / Deploy to GitHub Pages (push) Has been skipped
Sanitized mirror from private repository - 2026-04-18 10:57:41 UTC
2026-04-18 10:57:41 +00:00

6.2 KiB

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

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:

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

docker logs grafana --tail 100 2>&1 | grep -i "oauth\|error"

Test Authentik userinfo endpoint

curl https://sso.vish.gg/application/o/userinfo/
# Should return REDACTED_APP_PASSWORD when authenticated

Verify OAuth provider configuration via API

# 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

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