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.
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.
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
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
.
- 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
.
- 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
.
- Botkube config:
sources:
"kubernetes":
botkube/kubernetes@v1:
context:
rbac:
user:
type: Static
static:
value: kubernetes-read-only
- 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.
- 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
- 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"]
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.
- 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