Grafana with Keycloak integration

A concise guide to configuring Keycloak as your Identity Provider (IdP) for Grafana’s OAuth login, enabling seamless SSO, automatic user provisioning, and role-based access control.

1. Keycloak side

1.1 Create client

Field

Value

Client ID

grafana

Client Protocol

openid‑connect

Access Type

confidential

Standard Flow

ON

Valid Redirect URIs

http://<grafana-host>/login/generic_oauth

Web Origins

http://192.168.0.33:3000

Save, then copy the Client Secret.

1.2 Optional ► add role for auto‑admin

  1. Realm → Roles → Add rolegrafanaadmin.

  2. Users →  alice →  Role Mappings →  assign grafanaadmin.

  3. Mappers → Built‑In → User Realm Role → add, set Token claim name roles.

1.3 Expose mappers Grafana needs

Mapper

Purpose

X500 Email → rename user_email

Grafana expect email claim

Verify with Client → Evaluate – token must show email, roles and stable sub.


2. Grafana side

2.1 Container run / docker‑compose

bash
docker run -d --name grafana \ 
-p 3000:3000 \ 
-e GF_SERVER_ROOT_URL=http://<grafana-host>/ \ 
-e GF_AUTH_OAUTH_ALLOW_INSECURE_EMAIL_LOOKUP=true \ 
-v grafana-storage:/var/lib/grafana \ 
grafana/grafana-oss:latest
  • GF_SERVER_ROOT_URL avoids the infamous redirect_uri=localhost bug 

  • GF_AUTH_OAUTH_ALLOW_INSECURE_EMAIL_LOOKUP=true lets Grafana match by e‑mail if Keycloak user IDs change 

2.2 Configure Generic OAuth provider

Administration → Authentication → Generic OAuth

Field

Example

Name

Keycloak

Client ID / Secret

grafana / secret

Auth URL

https://<keycloak-host>/realms/<realm-name>/protocol/openid-connect/auth

Token URL

…/token

User‑info URL

…/userinfo

Scopes

openid, profile, email, roles

Sign‑out redirect URL

https://<keycloak-host>/realms/<realm-name>/protocol/openid-connect/logout?post_logout_redirect_uri=http%3A%2F%2F<grafana-host>%3A3000%2Flogin

Role attribute path

`contains(roles[*], 'grafanaadmin') && 'GrafanaAdmin'

Enable user sign‑up

ON

Click Save & Test – you should see “Login was successful” .


3. Advanced topics

3.1 Role mapping gotchas

  • Make sure roles claim appears as a String array; Grafana ignores nested realm_access if you omit roles[*].

  • Each Keycloak‑login merges roles only at sign‑in, not continuously; change role → logout → login to refresh.

3.2 Single‑Logout (SLO)

If the logout URL (above) is set, Grafana hits Keycloak’s /logout endpoint. Without it, pressing Sign out only kills Grafana’s session and you’ll log straight back in due to IdP cookies.

3.3 Docker permission error

Error in logs:

ini
GF_PATHS_DATA='/var/lib/grafana' is not writable

Bind‑mounted host folder must be owned by UID 472 or use a named volume which copies correct ownership automatically.


4. Troubleshooting matrix

Symptom

Root cause

Fix

Invalid parameter: redirect_uri

root_url still localhost

Set GF_SERVER_ROOT_URL or [server] root_url 

Login provider denied login request

Missing scope / email claim

scopes = openid profile email roles; add e‑mail mapper 

User sync failed

Local user clash or changed sub

Enable insecure e‑mail lookup, or delete duplicate user record 

Role not applied

Wrong role_attribute_path or claim

Use JMESPath as above, verify token via Keycloak Evaluate 

Can’t log out fully

Sign‑out URL missing

Set logout URL in provider block