<p>I'm trying to get access to my kubernetes cluster in my self hosted gitlab instance as it is described in the <a href="https://gitlab.jaqua.de/help/user/project/clusters/deploy_to_cluster.md#deployment-variables" rel="noreferrer">docs</a>.</p>
<pre><code>deploy:
  stage: deployment
  script: 
    - kubectl create secret docker-registry gitlab-registry --docker-server=&quot;$CI_REGISTRY&quot; --docker-username=&quot;$CI_DEPLOY_USER&quot; --docker-password=&quot;$CI_DEPLOY_PASSWORD&quot; --docker-email=&quot;$GITLAB_USER_EMAIL&quot; -o yaml --dry-run=client | kubectl apply -f -
</code></pre>
<p>But I do get the error</p>
<pre><code>Error from server (Forbidden): error when retrieving current configuration of:
Resource: &quot;/v1, Resource=secrets&quot;, GroupVersionKind: &quot;/v1, Kind=Secret&quot;
Name: &quot;gitlab-registry&quot;, Namespace: &quot;gitlab&quot;
from server for: &quot;STDIN&quot;: secrets &quot;gitlab-registry&quot; is forbidden: User &quot;system:serviceaccount:gitlab:default&quot; cannot get resource &quot;secrets&quot; in API group &quot;&quot; in the namespace &quot;gitlab&quot;
</code></pre>
<p>I do not understand the error. Why do I get a forbidden error?</p>
<hr />
<p><em>Update</em></p>
<p>The kubernetes cluster is integrated in gitlab at instance level.</p>
<p>But running <code>kubectl config view</code> in the CI pipeline gives me</p>
<pre><code>apiVersion: v1
clusters: null
contexts: null
current-context: &quot;&quot;
kind: Config
preferences: {}
users: null
</code></pre>
<hr />
<p><em>Update2</em></p>
<p>Thanks to AndD, the secret can be created with this role / service account:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: gitlab
  name: gitlab-deploy
rules:
- apiGroups: [&quot;&quot;] # &quot;&quot; indicates the core API group
  resources: [&quot;secrets&quot;]
  verbs: [&quot;get&quot;, &quot;list&quot;, &quot;watch&quot;, &quot;create&quot;, &quot;update&quot;, &quot;patch&quot;, &quot;delete&quot;]

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: use-secrets
  namespace: gitlab
subjects:
- kind: ServiceAccount
  name: default
  namespace: gitlab
roleRef:
  kind: ClusterRole
  name: gitlab-deploy
  apiGroup: rbac.authorization.k8s.io
</code></pre>
<p>But running a simple apply for this namespace.yaml file</p>
<pre><code>apiVersion: v1
kind: Namespace
metadata:
  name: myns
</code></pre>
<p>gives me a similar error:</p>
<pre><code>Error from server (Forbidden): error when retrieving current configuration of:
Resource: &quot;/v1, Resource=namespaces&quot;, GroupVersionKind: &quot;/v1, Kind=Namespace&quot;
Name: &quot;myns&quot;, Namespace: &quot;&quot;
from server for: &quot;namespace.yaml&quot;: namespaces &quot;myns&quot; is forbidden: User &quot;system:serviceaccount:gitlab:default&quot; cannot get resource &quot;namespaces&quot; in API group &quot;&quot; in the namespace &quot;myns&quot;
</code></pre>
<p>I used ClusterBinding to get this working even for a different namespace. What am I doing wrong?</p>

<p>Kubernetes makes use of a Role-based access control (RBAC) to prevent Pods and Users from being able to interact with resources in the cluster, unless they are not authorized.</p>
<p>From the error, you can see that Gitlab is trying to use the <code>secrets</code> resource and also that it is using as <code>ServiceAccount</code> the <code>default</code> service account in its namespace.</p>
<p>This means that Gitlab is not configured to use a particular ServiceAccount, which means it makes use of the default one (there's a default service account in each namespace of the cluster)</p>
<hr />
<p>You can attach role auth and permissions to service accounts by using <code>Role</code> / <code>ClusterRole</code> and <code>RoleBinding</code> / <code>ClusterRoleBinding</code>.</p>
<p>Roles or ClusterRoles describe permissions. For example, a Role could be:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: gitlab
  name: secret-user
rules:
- apiGroups: [&quot;&quot;] # &quot;&quot; indicates the core API group
  resources: [&quot;secrets&quot;]
  verbs: [&quot;get&quot;, &quot;list&quot;, &quot;watch&quot;, &quot;create&quot;, &quot;update&quot;, &quot;patch&quot;, &quot;delete&quot;]
</code></pre>
<p>and this states that &quot;whoever has this role, can do whatever (all the verbs) with secrets <strong>but only</strong> in the namespace <code>gitlab</code>&quot;</p>
<p>If you want to give generic permissions in all namespaces, you can use a ClusterRole instead, which is very similar.</p>
<p>Once the Role is created, you then can attach it to a User, a Group or a ServiceAccount, for example:</p>
<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: use-secrets
  namespace: gitlab
subjects:
subjects:
- kind: ServiceAccount
  name: default
  namespace: gitlab
roleRef:
  # &quot;roleRef&quot; specifies the binding to a Role / ClusterRole
  kind: Role # this must be Role or ClusterRole
  name: secret-user # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io
</code></pre>
<p>and this bind the role previously created to the <code>ServiceAccount</code> called default in the namespace <code>gitlab</code>.</p>
<p>Then, <strong>all</strong> Pods running in the namespace <code>gitlab</code> and using the <code>default</code> service account, will be able to use <code>secrets</code> (use the verbs listed in the Role) <strong>but only</strong> in the namespace specified by the Role.</p>
<hr />
<p>As you can see, this aspect of Kubernetes is pretty complex and powerful, so have a look at the docs because they explain things <strong>really</strong> well and are also full of examples:</p>
<p>Service Accounts - <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/" rel="noreferrer">https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/</a></p>
<p>RBAC - <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/" rel="noreferrer">https://kubernetes.io/docs/reference/access-authn-authz/rbac/</a></p>
<p>A list of RBAC resources - <a href="https://stackoverflow.com/questions/57872201/how-to-refer-to-all-subresources-in-a-role-definition">How to refer to all subresources in a Role definition?</a></p>
<hr />
<p><strong>UPDATE</strong></p>
<p>You are doing nothing wrong. It's just that you are trying to use the resource <code>namespace</code> but Gitlab has no Bind that gives access to that type of resource. With your <code>ClusterRole</code> you just gave it access to <code>secrets</code>, but nothing more.</p>
<p>Consider giving the ClusterRole more permissions, changing it to list all resources that you need to access:</p>
<pre><code>rules:
- apiGroups: [&quot;&quot;] # &quot;&quot; indicates the core API group
  resources: [&quot;secrets&quot;, &quot;namespaces&quot;, &quot;pods&quot;]
  verbs: [&quot;get&quot;, &quot;list&quot;, &quot;watch&quot;, &quot;create&quot;, &quot;update&quot;, &quot;patch&quot;, &quot;delete&quot;]
</code></pre>
<p>For example this will give access to secrets, namespaces and Pods.</p>
<p>As an alternative, you can bind Gitlab's service account to <code>cluster-admin</code> to directly give it access to <strong>everything</strong>.</p>
<pre><code>kubectl create clusterrolebinding gitlab-is-now-cluster-admin \
  --clusterrole=cluster-admin \
  --serviceaccount=gitlab:default
</code></pre>
<p>Before doing so tho, consider the following:</p>
<blockquote>
<p>Fine-grained role bindings provide greater security, but require more
effort to administrate. Broader grants can give unnecessary (and
potentially escalating) API access to ServiceAccounts, but are easier
to administrate.</p>
</blockquote>
<p>So, it is way more secure to first decide which resources can be used by Gitlab and then create a Role / ClusterRole giving access to only those resources (and with the verbs that you need)</p>
