All Products
Search
Document Center

Container Service for Kubernetes:Use custom RBAC to restrict resource operations in a cluster

Last Updated:Mar 26, 2026

When the predefined ClusterRoles in Container Service for Kubernetes (ACK) don't cover your permission requirements, create custom Roles or ClusterRoles for fine-grained role-based access control (RBAC) on cluster resources.

Before creating a custom role, check whether the built-in ClusterRoles (cluster-admin, admin, edit, view) already meet your needs. Custom roles are only necessary when built-in roles are too broad or too restrictive.

Built-in ClusterRole Access level
cluster-admin Full access to all resources across the cluster
admin Read/write access to most resources within a namespace
edit Read/write access to most objects in a namespace, excluding RBAC resources
view Read-only access to most objects in a namespace

Prerequisites

Before you begin, ensure that you have:

  • An ACK cluster

  • kubectl configured to connect to the cluster

  • Sufficient permissions to create RBAC resources in the cluster

Key concepts

Kubernetes RBAC uses two role types with different scopes:

  • Role: grants permissions within a specific namespace.

  • ClusterRole: grants permissions at the cluster level, across all namespaces. A namespace cannot be specified in a ClusterRole YAML manifest.

Both role types use the same three-field rule structure: apiGroups, resources, and verbs.

Permission verbs

Category Verbs Description
Read get Retrieve details of a specific resource
Read list List a collection of resources
Read watch Stream real-time updates for resource changes
Write create Create a new resource instance
Write update Replace an existing resource
Write patch Partially modify an existing resource
Write delete Remove a resource
Important

Avoid using wildcards (["*"]) in resources or verbs. Wildcards grant access to all current and future resources or verbs, including any new ones added later. Always list specific resources and verbs to follow the principle of least privilege.

Supported resources

Use the following table to build your rules field. Each row maps a resource type to its resources value, apiGroups value, and the verbs it supports.

Resource resources apiGroups Supported verbs
Pod ["pods"] [""] get, list, watch, update, create, patch, delete, exec, proxy
Service ["services"] [""] get, list, watch, update, create, patch, delete
ConfigMap ["configmaps"] [""] get, list, watch, update, create, patch, delete
Secret ["secrets"] [""] get, list, watch, update, create, patch, delete
PersistentVolume ["persistentvolumes"] [""] get, list, watch, update, create, patch, delete
PersistentVolumeClaim ["persistentvolumeclaims"] [""] get, list, watch, update, create, patch, delete
Namespace ["namespaces"] [""] get, list, watch, update, create, patch, delete
Deployment ["deployments"] ["apps"] get, list, watch, update, create, patch, delete
DaemonSet ["daemonsets"] ["apps"] get, list, watch, update, create, patch, delete
StatefulSet ["statefulsets"] ["apps"] get, list, watch, update, create, patch, delete
Ingress ["ingresses"] ["networking.k8s.io"] get, list, watch, update, create, patch, delete
NetworkPolicy ["networkpolicies"] ["networking.k8s.io"] get, list, watch, update, create, patch, delete
Job ["jobs"] ["batch"] get, list, watch, update, create, patch, delete
CronJob ["cronjobs"] ["batch"] get, list, watch, update, create, patch, delete
StorageClass ["storageclasses"] ["storage.k8s.io"] get, list, watch, update, create, patch, delete
HorizontalPodAutoscaler ["horizontalpodautoscalers"] ["autoscaling"] get, list, watch, update, create, patch, delete

Subresources

Some resources expose subresources that require separate grants. Use a slash (/) to specify a subresource. For example, to allow reading pod logs in addition to pods:

rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list"]

Common pod subresources: pods/log, pods/exec, pods/portforward, pods/proxy.

Create and bind a custom RBAC role

The ACK console supports binding custom ClusterRoles only. To bind a custom Role scoped to a specific namespace, use kubectl.

  • ACK console: create a ClusterRole and bind it to a RAM user or RAM role

  • kubectl: create a ClusterRole or Role, then create the corresponding binding

Console

Step 1: Create a ClusterRole

The following steps create a ClusterRole named my-clusterrole that grants read-only access to pods and Services across the cluster.

  1. Log on to the ACK console. In the left-side navigation pane, click Clusters.

  2. On the Clusters page, click the name of the target cluster. In the left-side pane, choose Security > Role.

  3. On the Role page, select the Cluster Role tab, then click OK.

  4. In the Create YAML panel, enter the ClusterRole manifest and click OK. The following manifest grants read-only access (get, list, watch) to pods and Services:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: my-clusterrole
    rules:
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["get", "list", "watch"]
      - apiGroups: [""]
        resources: ["services"]
        verbs: ["get", "list", "watch"]

    After creation, my-clusterrole appears under the Cluster Role tab.

Step 2: Bind the ClusterRole to a RAM user or RAM role

  1. In the left-side navigation pane, click Authorizations.

  2. On the Authorizations page, select the authorization target:

    • RAM user: click the RAM Users tab, find the target RAM user, and click Modify Permissions.

    • RAM role: click the RAM Roles tab, enter or select the RAM role name in the RAM Role Name field, and click Modify Permissions.

  3. In the Permission Management panel, click + Add Permissions. In the Add Permissions section:

    1. Select the Clusters associated with my-clusterrole.

    2. Select the target Namespace.

    3. Under Permission Management, select Custom, then select my-clusterrole from the drop-down list.

    4. Click Submit.

kubectl

Step 1: Create a custom role

ClusterRole — grants permissions across the entire cluster.

The following manifest creates a ClusterRole named my-clusterrole with read-only access to pods and Services:

# my-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: my-clusterrole
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "list", "watch"]

Role — grants permissions within a specific namespace.

The following manifest creates a Role named my-role with read access to pods in the default namespace:

# my-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: my-role
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list"]

Apply the manifest:

kubectl apply -f my-clusterrole.yaml

Step 2: Get the authorization object ID

To bind the role to a RAM user or RAM role, you need the corresponding ID:

  • RAM user: get the UserId by calling the GetUser API with the RAM username.

  • RAM role: get the RoleId by calling the GetRole API with the RAM role name.

Step 3: Create the binding

The following manifest binds my-clusterrole to a RAM user or RAM role. Replace 20811XXXXXXXXX2288 with the UserId or RoleId from the previous step.

# my-clusterrole-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: my-clusterrole-binding
subjects:
  - kind: User
    name: "20811XXXXXXXXX2288"    # UserId or RoleId from Step 2
roleRef:
  kind: ClusterRole
  name: my-clusterrole
  apiGroup: rbac.authorization.k8s.io

Apply the binding:

kubectl apply -f my-clusterrole-binding.yaml

Verify the permissions

After binding, verify that the RAM user has the expected access. Retrieve the kubeconfig of the cluster and connect using kubectl, then run a command that the role permits:

kubectl get pods

To confirm that access outside the granted permissions is correctly denied, run a command not covered by the role — for example, listing Deployments when only pod access was granted:

kubectl get deployments

The expected output is:

Error from server (Forbidden): deployments.apps is forbidden: User "20811XXXXXXXXX2288" cannot list resource "deployments" in API group "apps" at the cluster scope

This error confirms the permission boundary is working correctly.

What's next