<p><strong>Goal</strong></p>
<p>I want to allow unauthenticated access to the following OIDC endpoints in my K3s cluster (from other pods inside the cluster mostly but access from outside is also acceptable):</p>
<ul>
<li><a href="https://kubernetes.default.svc/.well-known/openid-configuration" rel="nofollow noreferrer">https://kubernetes.default.svc/.well-known/openid-configuration</a></li>
<li><a href="https://kubernetes.default.svc/openid/v1/jwks" rel="nofollow noreferrer">https://kubernetes.default.svc/openid/v1/jwks</a></li>
</ul>
<p><strong>Problem</strong></p>
<p>By default, Kubernetes requires an authorization token for accessing those endpoints and despite my efforts to enable unauthenticated access, I cannot seem to get the unauthenticated access to work.</p>
<p><strong>What I have tried</strong></p>
<p>According to the Kubernetes documentation on <a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-issuer-discovery" rel="nofollow noreferrer">Service account issuer discovery</a>, one must create a ClusterRoleBinding that maps the ClusterRole <code>system:service-account-issuer-discovery</code> to the Group <code>system:unauthenticated</code>.</p>
<p>I also found this helpful example for a different use-case but they're exposing the OIDC endpoints anonymously just like I want to do:
<a href="https://banzaicloud.com/blog/kubernetes-oidc/" rel="nofollow noreferrer">OIDC issuer discovery for Kubernetes service accounts</a></p>
<p>Based on both of those, I created my ClusterRoleBinding with:</p>
<pre class="lang-bash prettyprint-override"><code>kubectl create clusterrolebinding service-account-issuer-discovery-unauthenticated --clusterrole=system:service-account-issuer-discovery --group=system:unauthenticated
</code></pre>
<p>This results in the following spec:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: &quot;2022-11-28T15:24:41Z&quot;
  name: service-account-issuer-discovery-unauthenticated
  resourceVersion: &quot;92377634&quot;
  uid: 75402324-a8cf-412f-923e-a7a87ed082c2
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:service-account-issuer-discovery
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:unauthenticated
</code></pre>
<p>I also confirmed RBAC is enabled by running this which showed an entry:</p>
<pre class="lang-bash prettyprint-override"><code>kubectl api-versions | grep 'rbac.authorization.k8s.io/v1'
</code></pre>
<p>Unfortunately, despite creating that ClusterRoleBinding, it still seems to be requiring an authorization token to access the OIDC endpoints. For example, when I call from outside the cluster:</p>
<pre class="lang-bash prettyprint-override"><code>curl -vk https://my-cluster-hostname:6443/.well-known/openid-configuration
</code></pre>
<p>Output:</p>
<pre class="lang-json prettyprint-override"><code>{
  &quot;kind&quot;: &quot;Status&quot;,
  &quot;apiVersion&quot;: &quot;v1&quot;,
  &quot;metadata&quot;: {

  },
  &quot;status&quot;: &quot;Failure&quot;,
  &quot;message&quot;: &quot;Unauthorized&quot;,
  &quot;reason&quot;: &quot;Unauthorized&quot;,
  &quot;code&quot;: 401
}
</code></pre>
<p>Accessing from the Ingress controller inside the pod (by execing into it), I get the same error.</p>
<pre class="lang-bash prettyprint-override"><code>curl -vk https://kubernetes.default.svc/.well-known/openid-configuration
</code></pre>
<p>I am using K3s for this cluster... Is there something special about K3s that I have not accounted for? Do I need to do something to get this ClusterRoleBinding to take effect? Something else I missed?</p>

BearsEars
<p>The issue was that the <code>--anonymous-auth</code> api server setting is set to <code>false</code> by default.</p>
<p>I was able to adjust this with my already-installed K3s server nodes by editing the systemd unit for the k3s service. Step-by-step guide:</p>
<p>Edit the systemd unit with:</p>
<pre class="lang-bash prettyprint-override"><code>sudo vim /etc/systemd/system/k3s.service
</code></pre>
<p>You'll see the K3s unit:</p>
<pre><code>[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=notify
EnvironmentFile=-/etc/default/%N
EnvironmentFile=-/etc/sysconfig/%N
EnvironmentFile=-/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=/bin/sh -xc '! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service'
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
    server \
        '--cluster-init' \
        '--disable=traefik' \
        '--write-kubeconfig-mode' \
        '644' \
</code></pre>
<p>Add the last two lines to the <code>ExecStart</code>:</p>
<pre><code>ExecStart=/usr/local/bin/k3s \
    server \
        '--cluster-init' \
        '--disable=traefik' \
        '--write-kubeconfig-mode' \
        '644' \
        '--kube-apiserver-arg' \
        '--anonymous-auth=true' \
</code></pre>
<p>Reload the systemd unit:</p>
<pre class="lang-bash prettyprint-override"><code>sudo systemctl daemon-reload
</code></pre>
<p>Finally, restart the k3s service:</p>
<pre class="lang-bash prettyprint-override"><code>sudo systemctl restart k3s
</code></pre>
<p>References:</p>
<ul>
<li><a href="https://docs.k3s.io/security/hardening-guide#control-plane-execution-and-arguments" rel="nofollow noreferrer">Control Plane Execution and Arguments</a> - You can see the default for K3s there</li>
<li><a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#discovery-roles" rel="nofollow noreferrer">API discovery roles</a> - also mentions this flag at the top</li>
</ul>
