Tenant boundaries

Verify how multi-tenant mode separates namespace introduction, cluster discovery, namespaced mutation, and tenant-user access.

Updated 9 August 2026 · 5 min read

On this page

Multi-tenant mode separates the identity that grants namespace access from the controller that uses that access. The boundary limits routine workload mutation to namespaces introduced through OpenBaoTenant; it does not make a shared Kubernetes cluster a complete security boundary by itself.

Use single-tenant mode when one team owns one operator and one namespace and does not need the Provisioner handoff.

Understand the authority split

ActorCluster-wide authorityNamespaced authority
ProvisionerWatches OpenBaoTenant and applies the approved tenant-governance resourcesCreates tenant RBAC, Secret-access roles, quota, LimitRange, and optional Pod Security labels
ControllerGets, lists, and watches OpenBaoCluster and OpenBaoRestore resources for discoveryMutates workloads and supporting resources through Roles bound only in onboarded namespaces
Tenant authorDepends on how a platform administrator binds the supplied ClusterRolesCan manage tenant or cluster intent in the namespace without receiving broad Secret access
Kubernetes administratorCan alter CRDs, admission, RBAC, namespaces, and operator workloadsRemains trusted outside the operator’s tenant boundary

The controller is not fully namespace-scoped: it discovers operator custom resources cluster-wide. Its workload permissions are namespace-scoped because multi-tenant mode does not grant cluster-wide mutation of StatefulSets, Services, Pods, Jobs, Secrets, or the other generated resources.

Use the onboarding handoff

OpenBaoTenant names an existing target namespace. The Provisioner creates openbao-operator-tenant-rolebinding, which binds the controller ServiceAccount to the generated tenant Role. The cluster controller treats that RoleBinding as the handoff marker and pauses until it exists.

Admission and runtime checks enforce two onboarding paths:

  • A self-service request lives in its target namespace, targets only that namespace, and uses the platform defaults.
  • A centrally managed request lives in the rendered operator namespace and can target another namespace or override its quota and LimitRange.

Apply OpenBaoTenant and OpenBaoCluster in the same GitOps synchronization when needed. Reconciliation requeues until the handoff is ready instead of treating that ordering as a permanent failure. Follow the namespace-onboarding procedure for manifests and status checks.

Know which controls onboarding creates

ControlBoundaryImportant limitation
Tenant Role and RoleBindingGrants the controller namespaced workload-management permissionsThe RoleBinding is not a grant to tenant users
Secret reader RoleGrants get only for Secret names referenced by tenant resourcesThe Role is removed when no referenced Secrets remain
Secret writer RoleGrants name-scoped get, update, patch, and delete for operator-owned SecretsKubernetes RBAC cannot restrict create by resourceNames, so Secret creation is collection-scoped
ResourceQuota and LimitRangeEstablishes default namespace resource ceilings and container defaultsCentrally managed onboarding can replace the defaults
Pod Security labelsSets enforce, audit, and warn to restricted by defaultexternal mode delegates only label ownership
NetworkPolicyCreated during OpenBaoCluster reconciliationIt is not evidence that tenant onboarding completed, and enforcement depends on the cluster network implementation

The base tenant Role contains no Secret permissions. The Provisioner derives separate reader and writer allowlists from the OpenBaoCluster and OpenBaoRestore specifications in that namespace and removes empty allowlist roles.

Bind tenant users deliberately

The supplied user-facing roles are all ClusterRole objects. A ClusterRole defines reusable rules; the binding determines their effective scope. Use a RoleBinding for one tenant namespace. Reserve a ClusterRoleBinding for an identity that intentionally needs the permissions across all namespaces.

PurposeRaw-manifest nameHelm name suffixPermissions
Cluster administrationopenbaocluster-admin-roleopenbaocluster-adminAll verbs on OpenBaoCluster; read its status
Cluster editingopenbaocluster-editor-roleopenbaocluster-editorCreate, read, update, patch, delete, list, and watch OpenBaoCluster; read its status
Self-service onboardingopenbaotenant-editor-roleopenbaotenant-editorManage OpenBaoTenant; read its status

Helm prefixes the suffixes with the rendered release name. Inspect the rendered ClusterRole name before creating a binding. The cluster-administration role administers OpenBaoCluster; it does not itself grant permission to create or modify Kubernetes RBAC.

Protected operations such as restore, network publication, custom executable use, cloud identity, and image trust roots require separate delegated verbs. Do not add those permissions to the ordinary editor binding for convenience.

Verify the effective boundary

  1. Verify the onboarding handoff and generated controls.

    inspect

    Inspect the tenant namespace

    kubectl -n <request-namespace> get openbaotenant <name> \
         -o jsonpath='{.status.provisioned}{"\n"}'
       kubectl -n <target-namespace> get \
         role,rolebinding,resourcequota,limitrange \
         -l app.kubernetes.io/managed-by=openbao-operator

    The first command must print true. Confirm that the controller ServiceAccount is the subject of openbao-operator-tenant-rolebinding.

  2. Test the tenant user’s actual binding.

    verify

    Check tenant-user permissions

    kubectl auth can-i create openbaoclusters.openbao.org \
         -n <target-namespace> --as <tenant-user>
       kubectl auth can-i get secrets \
         -n <target-namespace> --as <tenant-user>

    An ordinary cluster editor should receive yes for cluster creation and no for broad Secret reads. Test the real group or ServiceAccount identity as well when bindings use groups or workload identities.

  3. After creating an OpenBaoCluster, verify the workload network boundary separately.

    inspect

    Inspect cluster network policy

    kubectl -n <target-namespace> get networkpolicy

    Confirm that the installed CNI enforces NetworkPolicy and test the allowed ingress and egress paths. Object-storage credentials and backup prefixes also need tenant-specific isolation outside Kubernetes RBAC.

Remove a tenant safely

spec.targetNamespace is immutable. Deleting OpenBaoTenant waits until every OpenBaoCluster in the target namespace is gone, then removes the controller RoleBinding, tenant Role, and Secret allowlist RBAC.

Tenant cleanup does not remove the ResourceQuota, LimitRange, or Pod Security labels. Review those resources explicitly before reusing or deleting the namespace. Cluster-owned NetworkPolicies follow the cluster lifecycle, not the tenant finalizer.

Continue with the threat model to review the cluster-administrator, supply-chain, OpenBao, and external-service boundaries that tenancy does not cover.

Search the handbook

Try “install”, “threat model”, or “compatibility”.