Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions docs/rbac.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# RBAC Management

## Structure

### capi-operator and capi-installer

The `capi-operator` and `capi-installer` ServiceAccounts (in `openshift-cluster-api-operator`) have separate, scoped permissions:

| Manifest | Kind | Scope | SA | Purpose |
|----------|------|-------|----|---------|
| `0000_30_cluster-api-operator_03_clusterrole.yaml` | ClusterRole `openshift-capi-operator` | cluster-wide | `capi-operator` | config.openshift.io resources, ClusterOperator management, ClusterAPI/ConfigMap/Deployment read |
| `0000_30_cluster-api-operator_03_clusterrole.yaml` | Role `capi-operator` | `openshift-cluster-api-operator` | `capi-operator` | Leader election leases, Deployment write (capi-installer), pod self-read, events |
| `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | ClusterRole `openshift-capi-installer` | cluster-wide | `capi-installer` | CRDs, admission resources, cluster RBAC, config.openshift.io, ClusterAPI/ClusterOperator status, tracking cache informers |
| `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-cluster-api-operator` | `capi-installer` | Leader election leases, pod self-read, ConfigMap read, events |
| `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-cluster-api` | `capi-installer` | boxcutter-managed resources (ServiceAccounts, Services, Deployments, Roles, RoleBindings), VAP paramRef list |
| `0000_30_cluster-api-operator_03_capi-installer-clusterrole.yaml` | Role `capi-installer` | `openshift-machine-api` | `capi-installer` | VAP paramRef list (machines, machinesets) |

Both SAs also bind to ClusterRole `system:openshift:openshift-cluster-api:read-tls-configuration` for APIServer TLS profile reading.

### capi-controllers

The `capi-controllers` ServiceAccount (used by both the `capi-controllers` and `machine-api-migration` containers) has permissions split across scopes:

| Manifest | Kind | Scope | Purpose |
|----------|------|-------|---------|
| `03_rbac_roles.yaml` | ClusterRole `openshift-capi-controllers` | cluster-wide | Cluster-scoped resources only: infrastructures, clusteroperators, featuregates, clusterversions, nodes, CRDs |
| `03_rbac_roles.yaml` | Role `capi-controllers` | `openshift-cluster-api` | CAPI core + infra provider resources, secrets, events, leases |
| `03_rbac_roles.yaml` | Role `capi-controllers` | `openshift-machine-api` | MAPI machines, machinesets, controlplanemachinesets, secrets, events |
| `03_rbac_roles.yaml` | Role `capi-controllers-kube-system` | `kube-system` | Secrets (vSphere credentials) |
| `03_rbac_roles.yaml` | Role `cluster-capi-operator-pull-secret` | `openshift-config` | Pull-secret read |

## Principles

- Each permission lives in the narrowest scope where it's used
- Cluster-scoped Kubernetes objects (CRDs, ClusterRoles, ClusterOperators) go in ClusterRoles
- Namespaced resources go into Roles in the specific namespace where they're accessed
- Read-only informer permissions may use ClusterRoles when the cache watches multiple namespaces

## Updating RBAC

Use the `/rbac-review` skill to audit and regenerate RBAC permissions. It requires a live cluster and uses audit2rbac + static code analysis to derive least-privilege rules.
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
include.release.openshift.io/single-node-developer: "true"
release.openshift.io/feature-gate: "ClusterAPIMachineManagement"
name: openshift-capi-installer
rules:
# VAP binding creation requires get+list on all resources when the referenced
# policy doesn't exist yet. Also covers boxcutter tracking cache reads.
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- apiGroups:
- config.openshift.io
resources:
- infrastructures
verbs:
- get
- list
- watch
- apiGroups:
- config.openshift.io
resources:
- clusteroperators
verbs:
- get
- list
- watch
- apiGroups:
- config.openshift.io
resources:
- clusteroperators/status
verbs:
- get
- update
- patch
- apiGroups:
- operator.openshift.io
resources:
- clusterapis
verbs:
- get
- list
- watch
- apiGroups:
- operator.openshift.io
resources:
- clusterapis/status
verbs:
- get
- update
- patch
# boxcutter: manages CRDs from provider manifests
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
# boxcutter: manages admission resources from provider manifests
- apiGroups:
- admissionregistration.k8s.io
resources:
- mutatingwebhookconfigurations
- validatingwebhookconfigurations
- validatingadmissionpolicies
- validatingadmissionpolicybindings
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
# boxcutter: manages cluster-scoped RBAC from provider manifests.
# escalate + bind: installer creates Roles granting permissions it doesn't hold.
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterroles
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- escalate
- bind
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterrolebindings
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
# boxcutter: tracking cache watches namespace-scoped types cluster-wide
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
- rolebindings
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
- services
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
include.release.openshift.io/single-node-developer: "true"
release.openshift.io/feature-gate: "ClusterAPIMachineManagement"
name: capi-installer
namespace: openshift-cluster-api-operator
rules:
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
include.release.openshift.io/single-node-developer: "true"
release.openshift.io/feature-gate: "ClusterAPIMachineManagement"
name: capi-installer
namespace: openshift-cluster-api
rules:
# boxcutter: applies namespace-scoped provider resources
- apiGroups:
- ""
resources:
- serviceaccounts
- services
verbs:
- create
- get
- update
- patch
- delete
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- get
- update
- patch
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
verbs:
- create
- get
- update
- patch
- delete
- escalate
- bind
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
verbs:
- create
- get
- update
- patch
- delete
# VAP paramRef authorization: API server requires list on paramKind types
- apiGroups:
- cluster.x-k8s.io
resources:
- machines
- machinesets
verbs:
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
exclude.release.openshift.io/internal-openshift-hosted: "true"
include.release.openshift.io/self-managed-high-availability: "true"
include.release.openshift.io/single-node-developer: "true"
release.openshift.io/feature-gate: "ClusterAPIMachineManagement"
name: capi-installer
namespace: openshift-machine-api
rules:
# VAP paramRef authorization: API server requires list on paramKind types
- apiGroups:
- machine.openshift.io
resources:
- machines
- machinesets
verbs:
- list
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Loading