<p>I have a Kubernetes cluster where there is a user who can install, upgrade, and delete the pods.
But I want to block his access to exec into the pod.</p>
<p>How can I achieve this using RBAC?</p>

<p>Permissions are additive. I'm not aware of blocking permissions for Kubernetes RBAC.</p>
<p>You will need to give the user a ClusterRole or a Role.</p>
<p>The specific permission to do this is called
<code>pod/exec</code>. So make sure you don't include that in the role.</p>
<p>Here's an example of a ClusterRole without pod/exec but read access to most resources (excluding secrets). You can modify this to allow create on pods etc if that is a requirement</p>
<pre class="lang-yaml prettyprint-override"><code>kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-only-clusterrole
rules:
  - nonResourceURLs:
      - /metrics
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - &quot;&quot;
    resources:
      - bindings
      - componentstatuses
      - configmaps
      - endpoints
      - events
      - limitranges
      - namespaces
      - namespaces/finalize
      - namespaces/status
      - nodes
      - nodes/proxy
      - nodes/status
      - persistentvolumeclaims
      - persistentvolumeclaims/status
      - persistentvolumes
      - persistentvolumes/status
      - pods
      - pods/attach
      - pods/binding
      - pods/eviction
#      - pods/exec
      - pods/log
      - pods/proxy
      - pods/status
      - podtemplates
      - replicationcontrollers
      - replicationcontrollers/scale
      - replicationcontrollers/status
      - resourcequotas
      - resourcequotas/status
      - serviceaccounts
      - services
      - services/proxy
      - services/status
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - apps
    resources:
      - controllerrevisions
      - daemonsets
      - daemonsets/status
      - deployments
      - deployments/scale
      - deployments/status
      - replicasets
      - replicasets/scale
      - replicasets/status
      - statefulsets
      - statefulsets/scale
      - statefulsets/status
    verbs:
      - list
      - get
      - watch
  - apiGroups:
      - batch
    resources:
      - jobs
      - jobs/status
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - autoscaling
    resources:
      - horizontalpodautoscalers
      - horizontalpodautoscalers/status
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - storage.k8s.io
    resources:
      - csidrivers
      - csinodes
      - storageclasses
      - volumeattachments
      - volumeattachments/status
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - networking.k8s.io
    resources:
      - networkpolicies
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - scheduling.k8s.io
    resources:
      - priorityclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - node.k8s.io
    resources:
      - runtimeclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
      - ingresses/status
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - events.k8s.io
    resources:
      - events
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - apiextensions.k8s.io
    resources:
      - customresourcedefinitions
      - customresourcedefinitions/status
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - apiregistration.k8s.io
    resources:
      - apiservices
      - apiservices/status
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - discovery.k8s.io
    resources:
      - endpointslices
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - metrics.k8s.io
    resources:
      - pods
      - nodes
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - policy
    resources:
      - poddisruptionbudgets
      - poddisruptionbudgets/status
      - podsecuritypolicies
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - rbac.authorization.k8s.io
    resources:
      - clusterrolebindings
      - clusterroles
      - rolebindings
      - roles
    verbs:
      - get
      - list
      - watch
</code></pre>
<p>To anyone who sees this and still can exec into the pod, as OP said it could be that additional ClusterRoles and Roles are adding the permission to the user or service account.</p>
