Skip to main content
Version: 1.0

RBAC

Botkube allows users to restrict plugins by defining RBAC rules as part of plugin configuration.

Based on this configuration Botkube generates a temporary kubeconfig file with user/group impersonation. This kubeconfig is available to plugins in the Execute and Stream contexts. If you're a plugin developer and want to learn more, refer to Plugin Development docs.

note

kubeconfig files are generated on-demand. Plugins have to define an rbac section in the configuration to enable kubeconfig generation.

Architecture

Botkube uses its own cluster credentials to generate a temporary kubeconfig, and the temporary kubeconfig only impersonates the requested user/group.

For source plugins, the kubeconfig is generated once - during plugin startup. For executor plugins, the kubeconfig is generated every time a command is sent to the plugin, which allows for greater flexibility, such as including the name of the channel the command was sent from in the kubeconfig generation.

diagram

Configuration

Each executor and source plugin can provide a context section with rbac config. This config is used to generate a dedicated kube config.

Supported mapping:

  • Static mapping - user or group impersonation, always the same subject for given plugin
  • Channel mapping - name of the channel is used as subject for group impersonation, only available for executor plugins
note

Automated actions only support Static mapping.

Example - kubectl executor with read-only RBAC

In this example a single executor plugin is defined with static RBAC that maps to user kubectl-read-only.

  1. ClusterRole and ClusterRoleBinding
  apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kubectl-read-only
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubectl-read-only
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubectl-read-only
subjects:
- kind: User
name: kubectl-read-only
apiGroup: rbac.authorization.k8s.io

Here we define a plugin with Static mapping to User.rbac.authorization.k8s.io kubectl-read-only.

  1. Executor definition with RBAC
executors:
"kubectl-read-only":
botkube/kubectl@v1:
enabled: true
context:
rbac:
user:
type: Static
static:
value: kubectl-read-only

When this executor plugin is invoked, a kubeconfig impersonating user kubectl-read-only is generated by Botkube and passed to the plugin. The plugin then can authenticate with the API server with identity of user kubectl-read-only.

Example: Kubernetes source plugin with static mapping

In this example a single source plugin is defined with static RBAC that maps to user kubernetes-read-only.

  1. Botkube config:
sources:
"kubernetes":
botkube/kubernetes@v1:
context:
rbac:
user:
type: Static
static:
value: kubernetes-read-only
  1. Kubernetes RBAC
  apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: reader
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: reader
subjects:
- kind: User
name: kubernetes-read-only
apiGroup: rbac.authorization.k8s.io

Example: kubectl executor plugin with channel name mapping

In this example kubectl executor plugin is configured with channel name mapping and bound to two channels, ch-1 and ch-2.

In Kubernetes RBAC Group ch-1 is given write access, while Group ch-2 is given only read access. Therefore users in channel ch-2 cannot create/update/delete resources, while users in ch-1 can.

  1. Botkube config:
executors:
"kubectl":
botkube/kubectl@v1:
context:
rbac:
group:
type: ChannelName
communications:
"default-group":
socketSlack:
channels:
"ch-1":
name: ch-1
bindings:
executors:
- kubectl
"ch-2":
name: ch-2
bindings:
executors:
- kubectl
  1. Kubernetes RBAC
  apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: editor
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: editor
subjects:
- kind: Group
name: ch-1
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: editor
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "watch", "list", "update", "create", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-only
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: read-only
subjects:
- kind: Group
name: ch-2
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: read-only
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "watch", "list"]
tip

You can use extraObjects section in helm values.yaml for the ClusterRoles and ClusterRoleBindings.

Limitations

Shared file system

Botkube executes plugin in the same pod and container - plugins share resources. If you're a plugin developer and decide to write kubeconfig to the file system, be aware that it will be accessible by all plugins in the container.

Merging of RBAC config

Plugins of the same type but with unique RBAC config cannot be bound to the same channel.

Troubleshooting

In most cases troubleshooting Botkube RBAC issues means troubleshooting Kubernetes RBAC - kubectl auth can help.

  1. Forbidden
Error: create: failed to create: secrets is forbidden: User "botkube-internal-static-user" cannot create resource "secrets" in API group "" in the namespace "default"

To see what the a user/group can do, use:

$ kubectl auth can-i --list

To see if user/group can do:

$ kubectl auth can-i get pod -n botkube --as user-1 --as-group group-1