Grafana can`t see roles from keycloak

Hello! I try to setup grafana authorization via keycloak. Grafana can see users, but canr parse their roles. In grafana console I can see that keycloak sent a roles to grafana in few places, but Grafana cant parse it:

grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.23392137Z level=debug msg="Extracting user info from OAuth token"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.234242257Z level=debug msg="Received id_token" raw_json="{\"exp\":1742554057,\"iat\":1742553757,\"auth_time\":1742553757,\"jti\":\"d3947770-a4d7-43cd-bfff-404717047501\",\"iss\":\"https://kk.glorytech.bet/realms/apps\",\"aud\":\"grafana\",\"sub\":\"14616d28-3318-4e62-a0e0-257796478e8e\",\"typ\":\"ID\",\"azp\":\"grafana\",\"sid\":\"185a5d1d-a069-473e-b7bd-00ea5b889637\",\"at_hash\":\"uWB7CQXxRSx1Z6I-9q9q8Q\",\"acr\":\"1\",\"resource_access\":{\"grafana\":{\"roles\":[\"editor\"]}},\"email_verified\":true,\"roles\":[\"editor\",\"manage-account\",\"manage-account-links\",\"view-profile\"],\"name\":\"Isaak Asimov Asimov\",\"preferred_username\":\"asimov\",\"given_name\":\"Isaak Asimov\",\"family_name\":\"Asimov\",\"email\":\"asimov@glorytech.bet\"}" data="Name: Isaak Asimov Asimov, Displayname: , Login: , Username: , Email: asimov@glorytech.bet, Upn: , Attributes: map[]"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.234269711Z level=debug msg="Getting user info from API"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.299441436Z level=debug msg="HTTP GET" url=https://kk.glorytech.bet/realms/apps/protocol/openid-connect/userinfo status="200 OK" response_body="{\"sub\":\"14616d28-3318-4e62-a0e0-257796478e8e\",\"resource_access\":{\"grafana\":{\"roles\":[\"editor\"]}},\"email_verified\":true,\"roles\":[\"editor\",\"manage-account\",\"manage-account-links\",\"view-profile\"],\"name\":\"Isaak Asimov Asimov\",\"preferred_username\":\"asimov\",\"given_name\":\"Isaak Asimov\",\"family_name\":\"Asimov\",\"email\":\"asimov@glorytech.bet\"}"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.299522132Z level=debug msg="Received user info response from API" raw_json="{\"sub\":\"14616d28-3318-4e62-a0e0-257796478e8e\",\"resource_access\":{\"grafana\":{\"roles\":[\"editor\"]}},\"email_verified\":true,\"roles\":[\"editor\",\"manage-account\",\"manage-account-links\",\"view-profile\"],\"name\":\"Isaak Asimov Asimov\",\"preferred_username\":\"asimov\",\"given_name\":\"Isaak Asimov\",\"family_name\":\"Asimov\",\"email\":\"asimov@glorytech.bet\"}" data="Name: Isaak Asimov Asimov, Displayname: , Login: , Username: , Email: asimov@glorytech.bet, Upn: , Attributes: map[]"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.299538096Z level=debug msg="Processing external user info" source=token data="Name: Isaak Asimov Asimov, Displayname: , Login: , Username: , Email: asimov@glorytech.bet, Upn: , Attributes: map[]"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.299660816Z level=debug msg="Setting user info name from nameAttributePath" nameAttributePath=name
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.299678261Z level=debug msg="Searching for login among JSON" loginAttributePath=preferred_username
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.299805394Z level=debug msg="Set user info email from extracted email" email=asimov@glorytech.bet
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.299993239Z level=warn msg="Failed to extract role" err="[oauth.role_attribute_strict_violation] idP did not return a role attribute, but role_attribute_strict is set"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.300015231Z level=debug msg="Processing external user info" source=API data="Name: Isaak Asimov Asimov, Displayname: , Login: , Username: , Email: asimov@glorytech.bet, Upn: , Attributes: map[]"
grafana    | logger=oauth.generic_oauth t=2025-03-21T10:42:34.300245332Z level=warn msg="Failed to extract role" err="[oauth.role_attribute_strict_violation] idP did not return a role attribute, but role_attribute_strict is set"

In Grafana docker compose I setup parse settings:

GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH: "contains(resource_access.grafana.roles, 'admin') ? 'Admin' : contains(resource_access.grafana.roles, 'editor') ? 'Editor' : contains(resource_access.grafana.roles, 'viewer') ? 'Viewer' : ''"

Also, I tried parameter like this:
GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH: “resource_access.grafana.roles”

And I check in JMESPath simulator what I have and it give me correct answer - “Editor”

I would be very glad if someone helped me!

Are you sure? It doesn’t work for me.

Tested with:

contains(resource_access.grafana.roles, 'admin') ? 'Admin' : contains(resource_access.grafana.roles, 'editor') ? 'Editor' : contains(resource_access.grafana.roles, 'viewer') ? 'Viewer' : ''

and

{
    "exp": 1742554057,
    "iat": 1742553757,
    "auth_time": 1742553757,
    "jti": "d3947770-a4d7-43cd-bfff-404717047501",
    "iss": "https://kk.glorytech.bet/realms/apps",
    "aud": "grafana",
    "sub": "14616d28-3318-4e62-a0e0-257796478e8e",
    "typ": "ID",
    "azp": "grafana",
    "sid": "185a5d1d-a069-473e-b7bd-00ea5b889637",
    "at_hash": "uWB7CQXxRSx1Z6I-9q9q8Q",
    "acr": "1",
    "resource_access": {
        "grafana": {
            "roles": [
                "editor"
            ]
        }
    },
    "email_verified": true,
    "roles": [
        "editor",
        "manage-account",
        "manage-account-links",
        "view-profile"
    ],
    "name": "Isaak Asimov Asimov",
    "preferred_username": "asimov",
    "given_name": "Isaak Asimov",
    "family_name": "Asimov",
    "email": "asimov@glorytech.bet"
}

So that JMESPath is not correct → Grafana can’t parse role.

You have weird JMESpath when I compare it with example in the doc:

1 Like