This guide explains how to authorize actions on resources in your control planes on Upbound. It uses the built-in Kubernetes role-based access control (RBAC) mechanism. This gives you fine-grained control over control plane access.
In a control plane on Upbound, Upbound RBAC and the control planes’s Kubernetes RBAC are integrated to authorize users to perform actions. They must have enough permission according to either system. To authorize users with their Upbound account, you must configure kubectl to authenticate to Upbound before running any commands that require authorization.
Define permissions and assign roles
Because control planes in Upbound are based on Kubernetes, you can use ClusterRole and Role objects to define RBAC rules in your control planes. Assign those rules using ClusterRoleBinding and RoleBinding objects:
- Role: A namespace-scoped group of resources and allowed operations that you can assign to a user or a group of users using a RoleBinding.
- ClusterRole: A cluster-scoped group of resources and allowed operations that you can assign to a user or a group of users using a RoleBinding or ClusterRoleBinding.
- RoleBinding: A namespace-scoped assignment of a Role or ClusterRole to a user or group.
- ClusterRoleBinding: A cluster-scoped assignment of a Role or ClusterRole to a user or group.
If you plan to use namespaces in your control plane as an isolation mechanism between tenants, its recommended to use RoleBinding objects. If namespace-scoping isn’t a priority, use ClusterRoleBinding objects instead.
Define permissions using Roles and ClusterRoles
Define permissions with a Role or ClusterRole object. A Role defines access to resources in a single namespace of your control plane. A ClusterRole defines access to resources in the entire control plane.
The example below demonstrates creating a sql-instance-viewer
cluster-scoped role. This role permits viewing sqlinstance
objects, a composite resource created with Crossplane.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: sqlinstance-viewer
rules:
- apiGroups: ["aws.platform.upbound.io"]
resources: ["sqlinstances"]
verbs: ["get", "watch", "list"]
Assign roles
The example below demonstrates how to assign the role in the earlier section to an Upbound user, robot, and control plane group member:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sqlinstance-viewer-binding
namespace: tenant1
subjects:
# An Upbound account user
- kind: User
name: upbound:user:${username-on-upbound}
# A robot on Upbound
- kind: User
name: upbound:robot:${robot-name}
apiGroup: rbac.authorization.k8s.io
# An Upbound control plane group member
- kind: Group
name: upbound:team:${team-uuid}
roleRef:
kind: ClusterRole
name: sqlinstance-viewer
apiGroup: rbac.authorization.k8s.io
RBAC manager
Each control plane in Upbound has a built-in Crossplane RBAC manager. This feature dynamically manages and binds RBAC roles. These roles grant subjects access to use the control plane as it gets extended by installing control plane software, such as providers, Crossplane composite resources, and more.
kubectl get ClusterRoles -A
NAME CREATED AT
admin 2025-03-12T18:57:25Z
cluster-admin 2025-03-12T18:57:25Z
controlplane-admin 2025-03-12T18:57:56Z
controlplane-admin-spaces-extras 2025-03-12T18:57:56Z
controlplane-controller 2025-03-12T18:57:56Z
controlplane-controller-spaces-extras 2025-03-12T18:57:56Z
controlplane-edit 2025-03-12T18:57:56Z
controlplane-edit-controller-spaces-extras 2025-03-12T18:57:56Z
controlplane-edit-spaces-extras 2025-03-12T18:57:56Z
controlplane-view 2025-03-12T18:57:56Z
controlplane-view-spaces-extras 2025-03-12T18:57:56Z
crossplane 2025-03-12T18:57:54Z
crossplane-admin 2025-03-12T18:57:54Z
crossplane-browse 2025-03-12T18:57:54Z
crossplane-edit 2025-03-12T18:57:54Z
crossplane-rbac-manager 2025-03-12T18:57:54Z
crossplane-view 2025-03-12T18:57:54Z
crossplane:aggregate-to-admin 2025-03-12T18:57:54Z
crossplane:aggregate-to-browse 2025-03-12T18:57:54Z
crossplane:aggregate-to-edit 2025-03-12T18:57:54Z
crossplane:aggregate-to-view 2025-03-12T18:57:54Z
crossplane:allowed-provider-permissions 2025-03-12T18:57:54Z
crossplane:composite:xnetworks.azure.platform.upbound.io:aggregate-to-browse 2025-03-15T15:26:08Z
crossplane:composite:xnetworks.azure.platform.upbound.io:aggregate-to-crossplane 2025-03-15T15:26:08Z
crossplane:composite:xnetworks.azure.platform.upbound.io:aggregate-to-edit 2025-03-15T15:26:08Z
How Upbound RBAC works in a control plane
Predefined roles
Each control plane offers predefined ClusterRoles related to granting permissions for Crossplane objects:
- controlplane-view lets subjects have read-only access to all Crossplane resources.
- controlplane-edit lets subjects have full access to composite resources.
- controlplane-admin lets subjects have full access and the ability to grant others access by managing role bindings.
Whenever control plane software gets installed or uninstalled, the RBAC manager handles the lifecycle of ClusterRoles and ClusterRoleBindings to aggregate permissions up to these predefined roles.
controlplane-view
The controlplane-view
ClusterRole has the following permissions:
- read-only access to all Crossplane types
- read-only access to all namespaces and events (even those unrelated to Crossplane).
View the full RBAC policy by running the following command on your control plane:
kubectl describe clusterrole controlplane-view
controlplane-edit
The controlplane-edit
ClusterRole has the following permissions:
- full access to all Crossplane types
- full access to all secrets (even those unrelated to Crossplane)
- read-only access to all namespaces and events (even those unrelated to Crossplane).
View the full RBAC policy by running the following command on your control plane:
kubectl describe clusterrole controlplane-edit
controlplane-admin
The controlplane-admin
ClusterRole has the following permissions:
- full access to all Crossplane types
- full access to all secrets and namespaces (even those unrelated to Crossplane)
- read-only access to all cluster RBAC roles, CustomResourceDefinitions and events ability to bind RBAC roles to other entities.
View the full RBAC policy by running the following command on your control plane:
kubectl describe clusterrole controlplane-admin
Upbound RBAC roles in a control plane
Roles granted with Upbound RBAC transitively affect what a user can do in a control plane. Upbound RBAC permissions are granted at the control plane group scope to teams. A team is a group of subjects consisting of users and robots. Here is how roles granted at the group scope transitively affect permissions in a control plane in that group:
- group viewer means users and robots receive the ClusterRole
controlplane-view
in the control plane. This role gets bound for all subjects with theupbound:controlplane:view
group attribute. - group editor means users and robots receive the ClusterRole
controlplane-edit
in the control plane. This role gets bound for all subjects with theupbound:controlplane:edit
group attribute. - group administrator means users and robots receive the ClusterRole
controlplane-admin
in the control plane. This role gets bound for all subjects with theupbound:controlplane:admin
group attribute.
Example usage
The example below demonstrates step-by-step how to give a tenant in a control plane limited ability to create only certain APIs.
Create a control plane in a group
As an administrator, create a control plane in a new control plane group:
up ctx /upbound-gcp-us-central-1
up group create group1
up ctp create prod-ctp -g group1
Connect to the control plane and configure it. For this example, you can install configuration-azure-data:
up ctx /upbound-gcp-us-central-1/group1/prod-ctp
up ctp configuration install xpkg.upbound.io/upbound/configuration-azure-database
Create a team and assign tenants to it
Create a team:
up team create team1
Use the Upbound Console to add the desired users to the team.
Use Upbound RBAC to assign a role to the team
First, find the ID of the team:
up team list
Assign the control plane group viewer
role to the team.
apiVersion: authorization.spaces.upbound.io/v1alpha1
kind: ObjectRoleBinding
metadata:
name: group1-viewer-binding
namespace: group1
spec:
object:
apiGroup: core
resource: namespaces
name: group1
subjects:
- kind: UpboundTeam
name:
role: viewer
You can also use the Upbound Console to assign this role.
The users in team1
now have a view-only experience on the control plane. To let them create only a certain set of APIs, you need to define Roles and RoleBindings on the control plane itself.
Configure RBAC on the control plane
Change your kubecontext to the control plane:
up ctx /upbound-gcp-us-central-1/group1/prod-ctp
Create a namespace in the control plane for the team:
kubectl create namespace team1
Create the Role and RoleBinding to let users in this namespace create and edit SQLInstances
. Apply the following manifests to your control plane:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: crossplane:composite:xsqlinstances.azure.platform.upbound.io:edit
namespace: team1
rules:
- apiGroups:
- azure.platform.upbound.io
resources:
- xsqlinstances
- xsqlinstances/status
verbs:
- '*'
- apiGroups:
- azure.platform.upbound.io
resources:
- sqlinstances
- sqlinstances/status
verbs:
- '*'
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sqlinstance-edit
namespace: team1
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: crossplane:composite:xsqlinstances.azure.platform.upbound.io:edit
subjects:
- kind: Group
name: upbound:team:
Users in team1
can now access the control plane and only have the ability to manage SQLInstances in their designated namespace.