Skip to main content

RBAC Manager

Purpose: For platform engineers, shows how to configure RBAC Manager RBACDefinition CRDs and Keycloak group bindings.

What RBAC Manager Does

RBAC Manager automates Kubernetes RBAC by converting declarative RBACDefinition custom resources into RoleBindings and ClusterRoleBindings. Instead of manually creating bindings for each user or group, you define an RBACDefinition that maps subjects (users, groups, service accounts) to roles. RBAC Manager watches these CRs and keeps the actual bindings in sync.

In openCenter, RBAC Manager integrates with Keycloak OIDC: Keycloak groups appear as group claims in OIDC tokens, and RBACDefinitions bind those groups to Kubernetes ClusterRoles.

How It's Deployed

RBAC Manager is deployed via FluxCD from openCenter-gitops-base:

openCenter-gitops-base/applications/base/services/rbac-manager/
├── namespace.yaml
├── source.yaml
├── helmrelease.yaml
└── helm-values/
└── hardened-values.yaml

Customer overlay:

applications/overlays/<cluster>/services/rbac-manager/
├── kustomization.yaml
└── override-values.yaml

Key Configuration

RBACDefinition for Keycloak Groups

The primary use case is mapping Keycloak OIDC groups to Kubernetes ClusterRoles. openCenter deploys default RBACDefinitions for cluster-admins and viewers:

apiVersion: rbacmanager.reactiveops.io/v1beta1
kind: RBACDefinition
metadata:
name: cluster-admins
spec:
rbacBindings:
- name: cluster-admins
subjects:
- kind: Group
name: cluster-admins # Keycloak group name (from OIDC groups claim)
clusterRoleBindings:
- clusterRole: cluster-admin
apiVersion: rbacmanager.reactiveops.io/v1beta1
kind: RBACDefinition
metadata:
name: viewers
spec:
rbacBindings:
- name: viewers
subjects:
- kind: Group
name: viewers
clusterRoleBindings:
- clusterRole: view

Namespace-Scoped Bindings

To grant a group access to specific namespaces only:

apiVersion: rbacmanager.reactiveops.io/v1beta1
kind: RBACDefinition
metadata:
name: app-team-alpha
spec:
rbacBindings:
- name: alpha-devs
subjects:
- kind: Group
name: team-alpha # Keycloak group
roleBindings:
- clusterRole: edit
namespace: app-alpha
- clusterRole: view
namespace: monitoring

RBAC Manager creates the RoleBindings in the specified namespaces and keeps them in sync. If the RBACDefinition is updated or deleted, the bindings are updated or removed.

Adding Custom Roles

Create custom ClusterRoles for fine-grained access, then reference them in RBACDefinitions:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-admin
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["networking.k8s.io"]
resources: ["networkpolicies"]
verbs: ["get", "list"]

How the Flow Works

  1. User authenticates via Keycloak and receives an OIDC token containing a groups claim.
  2. The Kubernetes API server validates the token and extracts group memberships.
  3. RBAC Manager has already created ClusterRoleBindings/RoleBindings for those groups.
  4. Kubernetes RBAC authorizes the request based on the bindings.

This chain requires Keycloak OIDC to be configured on the API server (see Keycloak doc).

Verification

# Check RBAC Manager pods
kubectl get pods -n rbac-manager

# List RBACDefinitions
kubectl get rbacdefinitions

# Verify generated bindings
kubectl get clusterrolebindings | grep rbacmanager
kubectl get rolebindings -A | grep rbacmanager

# Test access as a specific user
kubectl auth can-i list pods --as=user@example.com --as-group=viewers

Common Customizations

  • Team-based access: Create one RBACDefinition per team, mapping their Keycloak group to the appropriate namespaces and roles.
  • Service account bindings: RBACDefinitions can also bind ServiceAccounts, not just users and groups.
  • Audit trail: RBAC Manager logs all binding changes. Check its logs for reconciliation activity.
  • Cleanup: Deleting an RBACDefinition removes all bindings it created. This makes offboarding teams straightforward.