<h3>Problem</h3>

<p>I have a simple RBAC configuration to access the Kubernetes API in-cluster. However I am getting what appears to be conflicting information from <code>kubectl</code>. After deploying the manifest, it appears that RBAC is set up properly.</p>

<pre><code>$ kubectl exec -ti pod/controller -- kubectl auth can-i get namespaces
Warning: resource 'namespaces' is not namespace scoped
yes
</code></pre>

<p>However, actually making the request yields a permission error</p>

<pre><code>$ kubectl exec -ti pod/controller -- kubectl get namespaces
Error from server (Forbidden): namespaces is forbidden: User "system:serviceaccount:default:controller" cannot list resource "namespaces" in API group "" at the cluster scope
command terminated with exit code 1
</code></pre>

<h3>Manifest</h3>

<pre><code>apiVersion: 'v1'
kind: 'ServiceAccount'
metadata:
  name: 'controller'
---

apiVersion: 'rbac.authorization.k8s.io/v1'
kind: 'Role'
metadata:
  name: 'read-namespaces'
rules:
  - apiGroups:
      - ''
    resources:
      - 'namespaces'
    verbs:
      - 'get'
      - 'watch'
      - 'list'
---

apiVersion: 'rbac.authorization.k8s.io/v1'
kind: 'RoleBinding'
metadata:
  name: 'read-namespaces'
roleRef:
  apiGroup: ''
  kind: 'Role'
  name: 'read-namespaces'
subjects:
  - kind: 'ServiceAccount'
    name: 'controller'
---

apiVersion: 'v1'
kind: 'Pod'
metadata:
  name: 'controller'
  labels:
    'app': 'controller'
spec:
  containers:
    - name: 'kubectl'
      image: 'bitnami/kubectl:latest'
      imagePullPolicy: 'Always'
      command:
        - 'sleep'
        - '3600'
  serviceAccountName: 'controller'
---
</code></pre>

<h3>Other Info</h3>

<p>I've tried <code>kubectl auth reconcile -f manifest.yaml</code> as well as <code>kubectl apply -f manifest.yaml</code> and the results are the same.</p>

<p>I've also set "read-namespaces" <code>RoleBinding.subjects[0].namespace</code> to the  proper namespace ("default" in this case). No change in output.</p>

littlebenlittle
<p>Roles are per namespace, you need to create a cluster role  and binding using <code>ClusterRoleBinding</code></p>

<p>If you want to bind your cluster role to specific namespace, you could do something like this, using RoleBinding on a ClusterRole:</p>

<pre><code>---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa
  namespace: myapp

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: role-myapp
rules:
- apiGroups:
  - batch
  resources:
  - cronjobs
  verbs:
  - create
  - delete
  - deletecollection
  - get
  - list
  - patch
  - update
  - watch

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: job001
  namespace: myapp
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role-myapp
subjects:
- kind: ServiceAccount
  name: sa
  namespace: myapp
</code></pre>
