grafana: log in through keycloak's oidc-client provision

HAL's grafana logged in through a hand-made Keycloak client whose secret sat
in its .env. Requiring oidc-client gives it a client the mesh makes and keeps:
the id and URLs come from the binding, the secret arrives as a file grafana
reads itself (__FILE), and the callback it contributes is what keycloak
registers as its redirect.

GF_SERVER_ROOT_URL is still a literal: a module cannot yet learn the public
name the mesh composes for its own endpoint (hq issue 122), and without it
grafana sends a redirect Keycloak refuses.
This commit is contained in:
2026-09-30 00:39:16 +02:00
parent 54557b77bf
commit d8ee88e487
+37 -4
View File
@@ -47,6 +47,21 @@
"owner": "472:472", "owner": "472:472",
"content": "${secret:admin}" "content": "${secret:admin}"
}, },
{
"id": "oidc-secret",
"type": "file",
"path": "${dir:state}/oidc-client.secret",
"mode": "0400",
"owner": "472:472",
"content": "${secret:oidc-client}"
},
{
"id": "oidc-env",
"type": "file",
"path": "${dir:state}/oidc.env",
"mode": "0644",
"content": "GF_SERVER_ROOT_URL=https://grafana.zurag.be\nGF_AUTH_GENERIC_OAUTH_ENABLED=true\nGF_AUTH_GENERIC_OAUTH_NAME=Keycloak\nGF_AUTH_GENERIC_OAUTH_CLIENT_ID=${bound:oidc-client:as}\nGF_AUTH_GENERIC_OAUTH_CLIENT_SECRET__FILE=/run/secrets/oidc-client\nGF_AUTH_GENERIC_OAUTH_SCOPES=openid email profile roles\nGF_AUTH_GENERIC_OAUTH_AUTH_URL=${bound:oidc-client:issuer}${bound:oidc-client:authorization-path}\nGF_AUTH_GENERIC_OAUTH_TOKEN_URL=${bound:oidc-client:issuer}${bound:oidc-client:token-path}\nGF_AUTH_GENERIC_OAUTH_API_URL=${bound:oidc-client:issuer}${bound:oidc-client:userinfo-path}\nGF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH=contains(roles[*], 'admin') && 'Admin' || contains(realm_access.roles[*], 'admin') && 'Admin' || 'Viewer'\nGF_AUTH_GENERIC_OAUTH_USE_PKCE=true\nGF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP=true\nGF_AUTH_GENERIC_OAUTH_ALLOW_ASSIGN_GRAFANA_ADMIN=true\n"
},
{ {
"id": "server", "id": "server",
"type": "container", "type": "container",
@@ -57,11 +72,19 @@
], ],
"volumes": [ "volumes": [
"${dir:data}:/var/lib/grafana", "${dir:data}:/var/lib/grafana",
"${dir:state}/admin.secret:/run/secrets/admin:ro" "${dir:state}/admin.secret:/run/secrets/admin:ro",
"${dir:state}/oidc-client.secret:/run/secrets/oidc-client:ro"
], ],
"env": { "env": {
"GF_SECURITY_ADMIN_PASSWORD__FILE": "/run/secrets/admin" "GF_SECURITY_ADMIN_PASSWORD__FILE": "/run/secrets/admin"
} },
"env-file": [
"${dir:state}/oidc.env"
],
"restart-on": [
"oidc-env",
"oidc-secret"
]
}, },
{ {
"id": "runtime-config", "id": "runtime-config",
@@ -92,16 +115,26 @@
} }
], ],
"requires": [ "requires": [
"route" "route",
"oidc-client"
], ],
"contributes": { "contributes": {
"route": { "route": {
"label": "grafana", "label": "grafana",
"endpoint": "web" "endpoint": "web"
},
"oidc-client": {
"label": "grafana",
"endpoint": "web",
"callback": "/login/generic_oauth"
} }
}, },
"binds": { "binds": {
"route": "${dir:state}/route.json" "route": "${dir:state}/route.json",
"oidc-client": "${dir:state}/oidc.json"
},
"secrets": {
"oidc-client": "/var/lib/mesh/grafana/oidc-client"
}, },
"build": { "build": {
"on": [ "on": [