<p>We're trying to run a kubernetes cluster with three namespaces:</p>

<ul>
<li><code>public</code> contains services accessible to anyone</li>
<li><code>internal</code> contains services that should only be accessed by members of staff</li>
<li><code>engineering</code> contains services that should only be visible to developers</li>
</ul>

<p>The <code>internal</code> and <code>engineering</code> namespaces are protected with mutual authentication, each using a different certificate authority.</p>

<p>We're using Traefik as to manage ingresses to these services however, following the <a href="https://docs.traefik.io/user-guide/kubernetes/" rel="noreferrer">kubernetes guide</a> to set up Traefik, grants each instance of Traefik permissions to see ingresses across all namespaces. This means you could use a service in the <code>internal</code> namespace via the Traefik instance running in the <code>public</code> namespace, bypassing the mututal authentication.</p>

<p>We're working around this by setting hosts on the ingresses, but this means ingresses must be defined seperately for each environment (eg, <code>host: engineering.example.com</code> is different to <code>host: engineering.staging.example.com</code>). We'd prefer to leave the host out of the ingress configuration.</p>

<p>In theory, using RBAC we, should be able to restrict what Traefik is allowed to see to just resources in it's own ingresses as suggested in <a href="https://kubernetes.io/docs/admin/authorization/rbac/#rolebinding-and-clusterrolebinding" rel="noreferrer">this guide on RBAC</a>.</p>

<p>My understanding is that it still needs ClusterRole permissions such as this:</p>

<pre><code>---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
</code></pre>

<p>But using a Role binding instead of a ClusterRole binding will then restrict those permissions to just the ones in the given service accounts namespace. So if the service account is in the engineering namespace:</p>

<pre><code>---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: engineering
</code></pre>

<p>Then the role binding would be:</p>

<pre><code>---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: engineering
roleRef:
  kind: ClusterRole
  apiGroup: rbac.authorization.k8s.io
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  name: traefik-ingress-controller
</code></pre>

<p>We then tie the service account to the Traefik deployment with:</p>

<pre><code>---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: engineering
spec:
  replicas: 1
  template:
    spec:
      serviceAccountName: traefik-ingress-controller
      ...
</code></pre>

<p>We also set the namespaces in the config as per the kubernetes <a href="https://docs.traefik.io/configuration/backends/kubernetes/" rel="noreferrer">configuration guide</a></p>

<pre><code>[kubernetes]
namespaces = ["engineering"]
</code></pre>

<p>However, when Traefik starts we get the error:</p>

<p><code>E0313 11:15:57.971237 1 reflector.go:199] github.com/containous/traefik/vendor/k8s.io/client-go/tools/cache/reflector.go:94: Failed to list *v1.Endpoints: endpoints is forbidden: User "system:serviceaccount:engineering:traefik-ingress-controller" cannot list endpoints at the cluster scope: Unknown user "system:serviceaccount:engineering:traefik-ingress-controller"</code></p>

<p>The <code>Unknown user</code> is confusing as this is obviously binding a <code>ServiceAccount</code> not a user. Additionally, we can see the <code>ServiceAccount</code> has been created via kubectl.</p>

<p>I'm at a bit of a dead end here. </p>

<p>How do I make Traefik only pick up Ingresses in it's own namespace?</p>

<p>This error may occur when Traefik believes that no namespaces were configured; that is, the TOML configuration you outlined</p>

<pre><code>[kubernetes]
namespaces = ["engineering"]
</code></pre>

<p>is not becoming effective.</p>

<p>I can think of two reasons:</p>

<ol>
<li>In addition to the TOML configuration file, you are also passing a <code>--kubernetes</code> command-line argument to Traefik (through an <code>args</code> entry in the Deployment manifest). This would disable the <code>namespaces</code> option.</li>
<li>The file is not properly mounted into the Deployment, causing the default <code>namespaces</code> value (the empty list) to be effective. To tell whether that's truly the case, we need to see your full ConfigMap and the relevant volume sections of your Deployment manifests.</li>
</ol>
