<p>I'm trying to create <em>RBAC Role / rules</em> for a service that needs a persistent volume and it's still failing with <em>forbidden</em> error.</p>

<p>Here is my role config:</p>

<pre><code>kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: logdrop-user-full-access
  namespace: logdrop
rules:
- apiGroups: ["", "extensions", "apps", "autoscaling"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["batch"]
  resources:
  - jobs
  - cronjobs
  verbs: ["*"]
</code></pre>

<p>And this is my cut down <em>PersistentVolume</em> manifest:</p>

<pre><code>apiVersion: v1
kind: PersistentVolume
metadata:
  name: logdrop-pv
  namespace: logdrop
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  claimRef:
    namespace: logdrop
    name: logdrop-pvc
  hostPath:
    path: /efs/logdrop/logdrop-pv
</code></pre>

<p>When I try to apply it I get a forbidden error.</p>

<pre><code>$ kubectl --kubeconfig ~/logdrop/kubeconfig-logdrop.yml apply -f pv-test.yml 
Error from server (Forbidden): error when retrieving current configuration of:
Resource: "/v1, Resource=persistentvolumes", GroupVersionKind: "/v1, Kind=PersistentVolume"
Name: "logdrop-pv", Namespace: ""
Object: &amp;{map["apiVersion":"v1" "kind":"PersistentVolume" "metadata":map["annotations":map["kubectl.kubernetes.io/last-applied-configuration":""] "name":"logdrop-pv"] "spec":map["accessModes":["ReadWriteMany"] "capacity":map["storage":"10Gi"] "claimRef":map["name":"logdrop-pvc" "namespace":"logdrop"] "hostPath":map["path":"/efs/logdrop/logdrop-pv"] "persistentVolumeReclaimPolicy":"Retain"]]}
from server for: "pv-test.yml": persistentvolumes "logdrop-pv" is forbidden: User "system:serviceaccount:logdrop:logdrop-user" cannot get resource "persistentvolumes" in API group "" at the cluster scope
</code></pre>

<p>On the last line it specifically says <code>resource "persistentvolumes" in API group ""</code> - that's what I have allowed in the <em>rules</em>! </p>

<p>I can create the PV with <em>admin</em> credentials from the same yaml file and I can create any other resources (pods, services, etc) with the <em>logdrop</em> permissions. Just the <em>PersistentVolume</em> doesn't work for some reason. Any idea why?</p>

<p>I'm using Kubernetes 1.15.0.</p>

<p>Update:</p>

<p>This is my role binding as requested:</p>

<pre><code>kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: logdrop-user-view
  namespace: logdrop
subjects:
- kind: ServiceAccount
  name: logdrop-user
  namespace: logdrop
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: logdrop-user-full-access
</code></pre>

<p>It's not a ClusterRoleBinding as my intention is to give the user access only to one namespace (<code>logdrop</code>), not to all namespaces across the cluster.</p>

<p>PVs, namespaces, nodes and storages are <strong>cluster-scoped</strong> objects. As a best practice, to be able to list/watch those objects, you need to create <em>ClusterRole</em> and bind them to a <em>ServiceAccount</em> via <em>ClusterRoleBinding</em>. As an example;</p>

<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: &lt;name of your cluster role&gt;
rules:
- apiGroups: [""]
  resources:
  - nodes
  - persistentvolumes
  - namespaces
  verbs: ["list", "watch"]
- apiGroups: ["storage.k8s.io"]
  resources:
  - storageclasses
  verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: &lt;name of your cluster role binding&gt;
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: &lt;name of your cluster role which should be matched with the previous one&gt;
subjects:
  - kind: ServiceAccount
    name: &lt;service account name&gt;
</code></pre>
