This guide covers RBAC and security configuration for the OpenShift Lightspeed Operator.
📖 For K8s RBAC Fundamentals: See Kubernetes RBAC
📖 For Security Basics: See Pod Security Standards
The operator requires specific permissions to manage resources. We follow least privilege principles:
- Operator RBAC: Minimal permissions to manage OLSConfig and operand resources
- User RBAC: Three roles for CR access (viewer, editor, query-access)
- Security Context: Non-root, read-only filesystem, restricted capabilities
Location: config/rbac/role.yaml (generated from kubebuilder markers)
Key permissions:
- OLSConfig: Full CRUD + status + finalizers
- Core resources: Deployments, Services, ConfigMaps, Secrets
- OpenShift: ConsolePlugin
- Monitoring: ServiceMonitors
- RBAC: ClusterRoles, ClusterRoleBindings
1. Viewer Role (lightspeed-operator-olsconfig-viewer-role)
- Read-only access to OLSConfig
- Use case: Monitoring, auditing
2. Editor Role (lightspeed-operator-olsconfig-editor-role)
- Full CRUD on OLSConfig
- Use case: Managing operator configuration
3. Query Access Role (lightspeed-operator-query-access)
- Read access to metrics endpoint
- Use case: Prometheus scraping
Location: config/rbac/olsconfig_editor_role.yaml, olsconfig_viewer_role.yaml, query_access_role.yaml
Grant access:
# Viewer
oc adm policy add-role-to-user lightspeed-operator-olsconfig-viewer-role <username> -n openshift-lightspeed
# Editor
oc adm policy add-role-to-user lightspeed-operator-olsconfig-editor-role <username> -n openshift-lightspeed
# Query access
oc adm policy add-cluster-role-to-user lightspeed-operator-query-access <service-account>We use kubebuilder RBAC markers in controller code to generate permissions.
In your reconciler code:
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=ols.openshift.io,resources=olsconfigs,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=ols.openshift.io,resources=olsconfigs/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=ols.openshift.io,resources=olsconfigs/finalizers,verbs=update
func (r *OLSConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
// Your code
}Regenerate RBAC:
make manifests # Regenerate from markers
make bundle BUNDLE_TAG=0.1.0
git diff config/rbac/role.yamlMarker syntax:
//+kubebuilder:rbac:groups=<group>,resources=<resource>,verbs=<verbs>📖 Kubebuilder RBAC Markers: See Kubebuilder Markers
Location: config/manager/manager.yaml
Our security settings:
runAsNonRoot: true- Don't run as rootreadOnlyRootFilesystem: true- Read-only filesystemallowPrivilegeEscalation: false- Prevent privilege escalationcapabilities.drop: [ALL]- Drop all capabilitiesseccompProfile.type: RuntimeDefault- Use default seccomp profile
Why:
- Non-root reduces attack surface
- Read-only filesystem prevents tampering
- Dropped capabilities = minimal privileges
- Resource limits prevent exhaustion
Location: config/rbac/network_policy.yaml
Our NetworkPolicy:
- Allows metrics scraping on port 8443
- Allows API server access (required for reconciliation)
- Restricts all other traffic
Best practices we follow:
- Secret References - Use
credentialsSecretRef, never inline values - Validation - Operator validates secret exists and has required keys
- Watching - Automatic operand restart on secret changes
- Rotation - Update secret content, operator auto-detects and restarts
📖 Watcher Implementation: See ARCHITECTURE.md - Resource Management section
Implementation: internal/controller/watchers/ for secret watching logic
# 1. Add kubebuilder marker to code
vim internal/controller/mycontroller.go
# Add: //+kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list
# 2. Regenerate and verify
make manifests
git diff config/rbac/role.yaml
# 3. Update bundle
make bundle BUNDLE_TAG=0.1.0# Viewer role
oc create rolebinding user-viewer \
--clusterrole=lightspeed-operator-olsconfig-viewer-role \
--user=alice \
-n openshift-lightspeed
# Editor role
oc create rolebinding user-editor \
--clusterrole=lightspeed-operator-olsconfig-editor-role \
--user=bob \
-n openshift-lightspeed# Check operator permissions
oc auth can-i create deployments \
--as=system:serviceaccount:openshift-lightspeed:lightspeed-operator-controller-manager
# Check user permissions
oc auth can-i create olsconfig --as=alice
# View all operator permissions
oc describe clusterrole lightspeed-operator-manager-role# View security context
oc get pod -n openshift-lightspeed <pod> -o jsonpath='{.spec.securityContext}'
oc get pod -n openshift-lightspeed <pod> -o jsonpath='{.spec.containers[0].securityContext}'
# Verify non-root
oc get pod -n openshift-lightspeed <pod> -o jsonpath='{.spec.containers[0].securityContext.runAsNonRoot}'Symptoms: Operator logs show "forbidden" or "cannot create/update resource"
Diagnosis:
# Check service account
oc get sa lightspeed-operator-controller-manager -n openshift-lightspeed
# Check role bindings
oc get clusterrolebinding | grep lightspeed-operator
# Test permission
oc auth can-i create deployments \
--as=system:serviceaccount:openshift-lightspeed:lightspeed-operator-controller-managerFix:
- Add missing kubebuilder marker to code
make manifestsmake bundle- Redeploy operator
Diagnosis:
# Check user permissions
oc auth can-i get olsconfig --as=<username>
# List role bindings
oc get rolebinding -n openshift-lightspeed -o yaml | grep <username>Fix:
oc create rolebinding <username>-viewer \
--clusterrole=lightspeed-operator-olsconfig-viewer-role \
--user=<username> \
-n openshift-lightspeedDiagnosis:
# Check pod events
oc describe pod -n openshift-lightspeed <pod>
# Check security context constraints (OpenShift)
oc get sccFix:
- Verify
config/manager/manager.yamlhas correct security context - Ensure no privileged settings (root user,
privileged: true)
- OLM Bundle Management - RBAC in CSV
- ARCHITECTURE.md - Resource management patterns
- Kubernetes RBAC
- Kubebuilder RBAC Markers
Project Files:
config/rbac/- All RBAC manifestsconfig/manager/manager.yaml- Security contextinternal/controller/*_controller.go- RBAC markers in code