From 8fa904bb6c87c5daaa4c9c385a173c95510ad1b7 Mon Sep 17 00:00:00 2001 From: Nick Gorse Date: Mon, 11 May 2026 00:11:08 +0100 Subject: [PATCH] fix: add RBAC for keycloak-operator SA to manage resources in login namespace The upstream operator RBAC is scoped to keycloak-system only. With QUARKUS_OPERATOR_SDK_NAMESPACES=login the operator tries to watch/manage resources in login, so it needs a matching Role + RoleBindings there: - keycloak-operator-role: core resources (statefulsets, secrets, services, etc) - keycloakcontroller-cluster-role binding: keycloaks CRD access - keycloakrealmimportcontroller-cluster-role binding: realm import CRD access --- .../production/keycloak-operator-rbac.yaml | 80 +++++++++++++++++++ .../overlays/production/kustomization.yaml | 1 + 2 files changed, 81 insertions(+) create mode 100644 manifest/overlays/production/keycloak-operator-rbac.yaml diff --git a/manifest/overlays/production/keycloak-operator-rbac.yaml b/manifest/overlays/production/keycloak-operator-rbac.yaml new file mode 100644 index 0000000..1a1c4ee --- /dev/null +++ b/manifest/overlays/production/keycloak-operator-rbac.yaml @@ -0,0 +1,80 @@ +# RBAC for the Keycloak Operator SA (keycloak-system:keycloak-operator) to +# manage resources in the 'login' namespace. +# +# The upstream kubernetes.yml scopes the operator's Role/RoleBinding to the +# keycloak-system namespace only. When QUARKUS_OPERATOR_SDK_NAMESPACES is set +# to 'login', the operator tries to watch and manage resources here too, so it +# needs equivalent permissions. +# +# Three bindings are needed: +# 1. keycloak-operator-role — core Kubernetes resources (statefulsets, secrets, +# services, pods, jobs, ingresses, configmaps) +# 2. keycloakcontroller-cluster-role — keycloaks CRD access +# 3. keycloakrealmimportcontroller-cluster-role — keycloakrealmimports CRD access +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: keycloak-operator-role + namespace: login +rules: + - apiGroups: ["apps"] + resources: ["statefulsets"] + verbs: ["get", "list", "watch", "create", "delete", "patch", "update"] + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["secrets", "services"] + verbs: ["get", "list", "watch", "create", "delete", "patch", "update"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["list"] + - apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "watch", "create", "delete", "patch", "update"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch", "create", "delete", "patch", "update"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: keycloak-operator-role-binding + namespace: login +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: keycloak-operator-role +subjects: + - kind: ServiceAccount + name: keycloak-operator + namespace: keycloak-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: keycloakcontroller-role-binding + namespace: login +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: keycloakcontroller-cluster-role +subjects: + - kind: ServiceAccount + name: keycloak-operator + namespace: keycloak-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: keycloakrealmimportcontroller-role-binding + namespace: login +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: keycloakrealmimportcontroller-cluster-role +subjects: + - kind: ServiceAccount + name: keycloak-operator + namespace: keycloak-system diff --git a/manifest/overlays/production/kustomization.yaml b/manifest/overlays/production/kustomization.yaml index 8bf4625..e93dfe9 100644 --- a/manifest/overlays/production/kustomization.yaml +++ b/manifest/overlays/production/kustomization.yaml @@ -5,6 +5,7 @@ namespace: login resources: - ../../base/state + - keycloak-operator-rbac.yaml - cnpg-cluster.yaml - keycloak-instance.yaml - keycloak-realm-home-lab.yaml