Keep the identity that grants access separate from the identity that uses it.
The operator's RBAC model is built around a split-controller design. The provisioner introduces tenant access and namespace guardrails, while the controller consumes tenant-scoped permissions to manage workloads. Neither long-running identity should be able to do both jobs.
Diagram
Split-controller RBAC model
The provisioner creates the tenant `Role` and `RoleBinding`, but the binding points at the controller ServiceAccount rather than granting those permissions back to the provisioner.
The operator disables default token auto-mounting and uses explicit projected ServiceAccount tokens for Kubernetes API access. Audience pinning can be configured, but the important contract here is that API identity stays explicit and short-lived rather than inherited implicitly.
Decision matrix
Identity split at a glance
| Identity | Primary job | What it must not become |
|---|---|---|
| Provisioner | Introduce tenant namespaces, bind tenant-scoped RBAC, and apply day-0 guardrails. | A long-running identity that can read tenant Secrets or manage tenant workloads. |
| Controller | Reconcile OpenBaoCluster workloads and day-1/day-2 lifecycle actions inside onboarded namespaces. | An identity that can discover arbitrary namespaces or rewrite the RBAC that grants its own access. |
Provisioner access model
Reference table
Provisioner scope
| Resource or action | Why it exists | Why it stays narrow |
|---|---|---|
Watch OpenBaoTenant | Tenant onboarding is the trigger for introducing namespace access. | It is the only cluster-wide watch the provisioner needs for tenant onboarding. |
| Patch Namespaces for fixed PSS labels | Tenant namespaces must be hardened as part of onboarding. | Namespace mutation is limited to the fixed Pod Security label set and blocked in system namespaces. |
Create and patch fixed Role and RoleBinding objects | The provisioner must bind the controller into the target namespace. | Admission policy constrains names, subjects, verbs, and object shapes so this cannot expand into arbitrary RBAC minting. |
Create tenant guardrails such as ResourceQuota and LimitRange | Day-0 governance belongs to provisioning, not to workload reconciliation. | The provisioner manages only the operator-owned fixed objects and does not treat these resources as general namespace inventory. |
The provisioner writes the RBAC that grants the controller access, but it does not grant itself those permissions. That is the core security property of the onboarding path.
Controller access model
Reference table
Controller scope
| Resource or action | Why it exists | Why it stays narrow |
|---|---|---|
Watch OpenBaoCluster | The controller needs the global CRD event stream to reconcile clusters. | This does not imply namespace discovery or broad tenant access by itself. |
| Manage tenant-scoped workload resources | StatefulSets, Services, ConfigMaps, Jobs, and related resources are the normal lifecycle surface. | This access only exists where the provisioner already introduced the controller via RoleBinding. |
| Read and write allowlisted Secrets | Lifecycle workflows need specific Secret names for bootstrap, TLS, and operations. | Secret access is fixed-name, non-enumerating, and guarded by dedicated admission policy. |
Create minimal per-cluster Role and RoleBinding objects | Some service-registration and pod-discovery flows need narrow additional RBAC. | The controller policy only allows a tightly scoped pattern to prevent RBAC self-escalation. |
| Create operator-managed ServiceAccounts for workload and jobs | Backup, restore, and upgrade paths need explicit job identities. | Admission policy constrains names and shapes so the controller cannot mutate unrelated ServiceAccounts. |
What the RBAC model guarantees
Decision matrix
Security properties
| Property | What it means operationally | Primary control |
|---|---|---|
| No topology discovery | The controller is not supposed to list namespaces and infer who else exists in the cluster. | Provisioner-led namespace introduction and narrow cluster-scope reads. |
| No Secret enumeration | Operator identities should not browse tenant Secrets as generic inventory. | Name-scoped Secret roles and the controller Secret-write policy. |
| Privilege separation | The identity that grants access is not the identity that consumes it. | Split provisioner/controller model plus admission guardrails. |
| Blind-create, name-scoped mutate | The operator can create the Secrets it owns without broadening into arbitrary tenant Secret mutation. | Dedicated Secret roles and fixed-name admission constraints. |
Installing with admission policies disabled materially weakens the RBAC defense-in-depth story. The split-controller design still matters, but without the admission guardrails a broader or drifted RBAC grant has fewer backstops.
Continue platform controls
You are reading the unreleased main docs. Use the version menu for the newest published release, or check the release notes for what is already out.
Was this page helpful?
Use Needs work to open a structured GitHub issue for this page. The Yes button only acknowledges the signal locally.