ServerlessBase Blog
  • Introduction to Kubernetes RBAC (Role-Based Access Control)

    Learn how Kubernetes Role-Based Access Control works and how to implement it for secure multi-tenant clusters.

    Introduction to Kubernetes RBAC (Role-Based Access Control)

    You've deployed your first Kubernetes cluster, and everything works. You can create pods, deploy applications, and manage services. Then you invite a colleague to help, and suddenly they can delete your production database. Or worse, they accidentally delete the entire namespace. This is where Kubernetes RBAC becomes critical.

    Role-Based Access Control in Kubernetes is the mechanism that prevents unauthorized actions by enforcing least privilege principles. It's not just a feature—it's the foundation of secure multi-tenant clusters. Without RBAC, every user with API access has full control over your entire cluster, which is unacceptable for production environments.

    In this article, you'll learn how RBAC works under the hood, how to implement it effectively, and why it's essential for any serious Kubernetes deployment.

    How RBAC Works in Kubernetes

    Kubernetes RBAC uses four core resources to define permissions: Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings. These resources work together to grant permissions to users, groups, or service accounts.

    Roles vs ClusterRoles

    The distinction between Roles and ClusterRoles is fundamental. A Role is namespace-scoped—it defines permissions within a single namespace. A ClusterRole, as the name suggests, can span the entire cluster and includes permissions for cluster-wide resources like nodes, persistent volumes, and namespace-level resources.

    Think of a Role as a permission set for a specific department in a building, while a ClusterRole is a permission set for the entire building. You wouldn't want a marketing team member to have access to the server room, even though they might need access to the marketing department's office.

    RoleBindings vs ClusterRoleBindings

    Similarly, RoleBindings grant the permissions defined in a Role to subjects within a namespace, while ClusterRoleBindings grant permissions to subjects across the entire cluster. A RoleBinding can reference a Role in the same namespace or a ClusterRole, but it only applies within its namespace.

    Subjects: Who Gets the Permissions?

    Subjects are the entities that receive permissions. They can be:

    • Users: Individual human users
    • Groups: Groups of users
    • ServiceAccounts: Applications running in pods

    ServiceAccounts are particularly important in Kubernetes because pods run with a default service account. If you want to restrict what a pod can do, you bind a ClusterRole to its service account.

    The Permission Model

    Kubernetes uses a deny-by-default model. If you don't explicitly grant a permission, it's denied. This is different from some systems where permissions are granted by default and must be revoked.

    When a request comes into the API server, the authentication layer identifies the user or service account, and the authorization layer checks if the request is allowed based on the RBAC rules. If no matching rule exists, the request is denied.

    Resource and Action Permissions

    Permissions are defined at the resource-action level. For example, you can grant permission to "get, list, and watch pods" but not "delete pods." This fine-grained control is what makes RBAC powerful.

    Common actions include:

    • get: Retrieve a single resource
    • list: List resources
    • watch: Watch for changes to resources
    • create: Create new resources
    • update: Update existing resources
    • patch: Apply partial updates
    • delete: Delete resources
    • deletecollection: Delete multiple resources

    Practical Implementation

    Let's walk through a concrete example. Suppose you have a development team that needs to deploy applications but shouldn't be able to modify system resources or access production databases.

    Step 1: Create a Role for Development

    First, create a Role that grants the necessary permissions for development work:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: developer-role
      namespace: development
    rules:
    - apiGroups: [""]
      resources: ["pods", "services", "configmaps", "secrets"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    - apiGroups: ["apps"]
      resources: ["deployments", "replicasets", "daemonsets"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    - apiGroups: ["batch"]
      resources: ["jobs"]
      verbs: ["get", "list", "watch", "create", "delete"]

    This Role grants full CRUD permissions for common application resources in the development namespace. The empty string apiGroups: [""] refers to core Kubernetes resources like pods and services.

    Step 2: Create a RoleBinding

    Next, bind this Role to a group of developers:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: developer-binding
      namespace: development
    subjects:
    - kind: Group
      name: developers
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: developer-role
      apiGroup: rbac.authorization.k8s.io

    Now every user in the developers group can perform the actions defined in the Role within the development namespace.

    Step 3: Restrict Production Access

    For production, you might want more restrictive permissions. Create a separate Role with limited actions:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: production-viewer-role
      namespace: production
    rules:
    - apiGroups: [""]
      resources: ["pods", "services", "configmaps"]
      verbs: ["get", "list", "watch"]
    - apiGroups: ["apps"]
      resources: ["deployments"]
      verbs: ["get", "list", "watch"]

    This Role only allows read operations, preventing accidental deletions or modifications.

    ClusterRole Examples

    ClusterRoles are useful for cluster-wide permissions. Here's an example of a ClusterRole that grants permission to manage nodes:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: node-manager
    rules:
    - apiGroups: [""]
      resources: ["nodes"]
      verbs: ["get", "list", "watch", "patch", "update"]
    - apiGroups: [""]
      resources: ["nodes/status"]
      verbs: ["get", "patch", "update"]

    Bind this ClusterRole to a service account for a node management application:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: node-manager-binding
    subjects:
    - kind: ServiceAccount
      name: node-manager
      namespace: kube-system
    roleRef:
      kind: ClusterRole
      name: node-manager
      apiGroup: rbac.authorization.k8s.io

    Common RBAC Patterns

    ServiceAccount for Applications

    Every pod runs with a service account by default. If your application needs to interact with the Kubernetes API, bind a ClusterRole to its service account:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: my-app
      namespace: production
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: my-app-binding
    subjects:
    - kind: ServiceAccount
      name: my-app
      namespace: production
    roleRef:
      kind: ClusterRole
      name: view
      apiGroup: rbac.authorization.k8s.io

    Admin Role

    For cluster administrators, you can create a ClusterRole with all permissions:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: cluster-admin
    rules:
    - apiGroups: ["*"]
      resources: ["*"]
      verbs: ["*"]

    This ClusterRole is so powerful that it grants full control over the entire cluster. Use it sparingly and only for users who truly need it.

    RBAC vs Other Authorization Models

    Kubernetes supports multiple authorization modes, but RBAC is the default and most widely used. Other modes include:

    • Node: For kubelet authentication
    • ABAC: Attribute-Based Access Control
    • Webhook: Custom authorization logic

    RBAC is generally preferred because it's declarative, easy to understand, and integrates well with Kubernetes' resource model. ABAC requires defining attributes for every resource, which can be complex and doesn't scale well.

    Best Practices

    Principle of Least Privilege

    Always grant the minimum permissions necessary for a user or application to perform its job. If a developer only needs to deploy applications, don't give them permission to manage nodes or access production databases.

    Regular Audits

    Review RBAC rules periodically to ensure they still match your current needs. As teams grow and change, permissions may become outdated or overly permissive.

    Use Groups for Team Management

    Instead of binding individual users, bind groups. This makes it easier to manage permissions as team membership changes.

    Document Your RBAC Structure

    Create documentation that explains your RBAC model, including which roles exist, what permissions they grant, and which users belong to which groups. This is invaluable for onboarding new team members and for troubleshooting permission issues.

    Test Permissions

    Before deploying RBAC changes to production, test them in a staging environment. Create test users with the same permissions and verify that they can and cannot perform the expected actions.

    Troubleshooting RBAC Issues

    If a user can't perform an action they expect to be able to, check these common issues:

    1. Wrong namespace: Verify that the Role or RoleBinding is in the correct namespace.
    2. Missing verbs: Check that the verbs in the rule match the actions you're trying to perform.
    3. Resource mismatch: Ensure the resource name matches exactly (case-sensitive).
    4. API group mismatch: Verify the API group for the resource you're trying to access.
    5. RoleBinding not found: Confirm that the RoleBinding exists and references the correct Role.

    Use kubectl auth can-i to test permissions:

    kubectl auth can-i get pods -n development
    kubectl auth can-i delete pods -n development

    This command shows whether the current user can perform the specified action.

    Conclusion

    Kubernetes RBAC is essential for securing multi-tenant clusters. By understanding the four core resources—Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings—you can implement fine-grained access control that follows the principle of least privilege.

    Remember that Kubernetes uses a deny-by-default model, so every permission must be explicitly granted. This might seem restrictive at first, but it's what makes RBAC powerful and secure.

    As you scale your Kubernetes deployments, RBAC becomes increasingly important. Platforms like ServerlessBase simplify the management of RBAC rules and deployment configurations, allowing you to focus on building applications rather than managing complex access control policies.

    The next step is to audit your current cluster permissions and identify any overly permissive roles. Start with the cluster-admin role—unless you absolutely need it, revoke it and grant more specific permissions instead.

    Leave comment