From 2461c239b03840cba10111029fb79e8b8195527e Mon Sep 17 00:00:00 2001 From: Myasnikov Daniil Date: Fri, 17 Apr 2026 11:32:44 +0500 Subject: [PATCH] fix(linstor): restrict linstor-gui to cozystack-cluster-admin group MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this change oauth2-proxy fronting linstor-gui only enforced that the user could authenticate against the `cozy` Keycloak realm (`--email-domain=*`, no group restriction). Any realm user could reach the UI and, through it, the LINSTOR controller REST API — which the gatekeeper proxies with a static mTLS client cert and no per-user RBAC. Add `--allowed-group=cozystack-cluster-admin` and include `groups` in the OIDC scope so the claim is present at validation time. The `cozystack-cluster-admin` KeycloakRealmGroup and the `groups` client scope are already provisioned by keycloak-configure, so no cluster-wide changes are needed. Assisted-By: Claude Signed-off-by: Myasnikov Daniil (cherry picked from commit 9b54e4672364a0de7859c5273dd2b280374083ea) --- packages/system/linstor-gui/README.md | 7 +++++-- packages/system/linstor-gui/templates/gatekeeper.yaml | 8 +++++++- packages/system/linstor-gui/tests/ingress_auth_test.yaml | 6 ++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/system/linstor-gui/README.md b/packages/system/linstor-gui/README.md index 2c9ac5d5..8f8053ab 100644 --- a/packages/system/linstor-gui/README.md +++ b/packages/system/linstor-gui/README.md @@ -13,8 +13,11 @@ using mTLS with the `linstor-client-tls` secret created by the `linstor` package The chart ships an `oauth2-proxy` based gatekeeper plus a `KeycloakClient` CRD so the UI can be published on `linstor-gui.` behind the cluster -Keycloak realm. Access is granted to any user who can authenticate against the -`cozy` realm. +Keycloak realm. Access is restricted to members of the +`cozystack-cluster-admin` Keycloak group — the same group that grants +cluster-admin RBAC on the host cluster. Authenticating against the `cozy` +realm alone is not sufficient; users outside that group receive a 403 from +oauth2-proxy before any request reaches the UI or the LINSTOR controller. To turn it on, add `linstor-gui` to `publishing.exposedServices` in the core `cozystack` values (same list that controls `dashboard`). OIDC must be diff --git a/packages/system/linstor-gui/templates/gatekeeper.yaml b/packages/system/linstor-gui/templates/gatekeeper.yaml index 0830a5fa..81451f41 100644 --- a/packages/system/linstor-gui/templates/gatekeeper.yaml +++ b/packages/system/linstor-gui/templates/gatekeeper.yaml @@ -13,6 +13,11 @@ Only rendered when oidc-enabled=true. If the cluster has OIDC disabled we deliberately do not ship an unauthenticated token-proxy fallback (unlike dashboard): linstor-gui surfaces raw storage state and should not be reachable via Ingress without Keycloak login. + +Access is further restricted to the cozystack-cluster-admin group +(--allowed-group below). The proxy authenticates with a static mTLS client +cert and LINSTOR itself has no per-user RBAC, so group membership is the +only boundary between a realm user and raw storage state. */ -}} {{- if eq $oidcEnabled "true" }} apiVersion: apps/v1 @@ -84,7 +89,8 @@ spec: - --cookie-secure=true - --cookie-secret=$(OAUTH2_PROXY_COOKIE_SECRET) - --skip-provider-button - - --scope=openid email profile offline_access + - --scope=openid email profile groups offline_access + - --allowed-group=cozystack-cluster-admin {{- if eq $oidcInsecureSkipVerify "true" }} - --ssl-insecure-skip-verify=true {{- end }} diff --git a/packages/system/linstor-gui/tests/ingress_auth_test.yaml b/packages/system/linstor-gui/tests/ingress_auth_test.yaml index fe735f50..2f0b1d73 100644 --- a/packages/system/linstor-gui/tests/ingress_auth_test.yaml +++ b/packages/system/linstor-gui/tests/ingress_auth_test.yaml @@ -109,6 +109,12 @@ tests: - contains: path: spec.template.spec.containers[0].args content: --oidc-issuer-url=https://keycloak.dev10.example.org/realms/cozy + - contains: + path: spec.template.spec.containers[0].args + content: --scope=openid email profile groups offline_access + - contains: + path: spec.template.spec.containers[0].args + content: --allowed-group=cozystack-cluster-admin - contains: path: spec.template.spec.containers[0].env content: