Introduction ¶
To authenticate in Kubernetes through kubeconfig for access via kubectl, ServiceAccounts are generally used. They are simply easier to create, but this is not the right approach. Tokens from ServiceAccounts are accessible to anyone who can read secrets in the namespace where the ServiceAccount was created, which means that actions can be taken on your behalf. Not secure…
You can create a certificate, sign it in the cluster, and operate as a User. This is much better; no one can do anything on your behalf because we generated the private part locally and did not share it. I’ll explain how to do this since I’ve figured it out.
Recently, I finally tried Authentik and also attempted to link it to the cluster via API server configuration. It turned out to be even simpler in some aspects than dealing with certificates for users. This is what I will talk about.
Access via ServiceAccount ¶
Let’s create a ServiceAccount.
|
|
Previously, before Kubernetes 1.22, a token was automatically generated; now it needs to be created separately. You can generate a temporary one.
|
|
Alternatively, you can obtain a permanent token by creating a secret for it.
|
|
Now we can write it in kubeconfig and use it.
|
|
Creating a User ¶
This part is a bit more complicated. You need to create a certificate, a signing request, sign it, retrieve the public part, and only then are we ready to proceed. I’m attaching my script, but I don’t want to describe all of this. I’m focusing on OIDC, so consider this as a nice bonus 😄
How to use it:
- Write your name in the variable NAME
- Write your company name in the variable GROUP
- Change CLUSTERROLE if you really want to
- Run the script and read the instructions on the screen
|
|
Google OIDC ¶
Configure the OAuth consent screen
Create OAuth2 credentials of type Web application, Authorized redirect URIs - in the list below.
1 2 3 4
http://127.0.0.1:18000 http://127.0.0.1:8000 http://localhost:18000 http://localhost:8000
As a result, you will get the Client ID and Client Secret.
Great, now you need to install the kubectl oidc-login plugin.
After installation, try to ensure everything works.
|
|
If everything is fine, your browser should open, you log in as someone, and a big beautiful instruction will appear in the console. Something like this.
|
|
Authentik ¶
This tool is great! Among its direct analogs, it’s worth mentioning Okta and Keycloak. All three products are excellent; Okta is often considered the benchmark. Other options may be better or worse, but they are always compared to Okta. 😄
I installed Authentik from the official chart. It’s running locally, and I needed a certificate. I obtained one using Certbot with DNS verification. After that, we proceed as follows:
Applications > Providers
Create a Kubernetes provider of type OAuth2/OIDC
- Client type: Confidential
- Client ID: remember this
- Client Secret: remember this
- Redirect URIs:
http://(127.0.0.1|localhost):1?8000(/.*)?
Application > Applications
Create an application Kubernetes and select the provider you created in step 1.
System
Create users (surprise, right?) and also create groups. I made kubernetes:admin and kubernetes:restricted. The first group will be assigned the cluster-admin role in Kubernetes, while the second will have read-only access. Don’t forget to add users to the corresponding groups.
System > Certificates
I’m not sure about this step; I just haven’t checked it without a certificate. I uploaded the certificate obtained via Certbot here, and then selected this certificate in Application > Providers > Kubernetes > Edit > Signing Key. Kubernetes didn’t complain, so it might be possible to use a self-signed certificate, but I’m not sure; you’ll have to try it yourself.
Customization > Property Mappings
Create a mapping with the following parameters:
Name: Kubernetes
Scope name: kubernetes
Expression
1 2 3 4 5 6 7 8 9 10
all_groups = [ "kubernetes:admin", "kubernetes:restricted" ] return dict( groups=[ group for group in all_groups if ak_is_group_member(request.user, name=group) ] )
This way, for those who request this scope, Authentik will append the groups the user belongs to, iterating only through the Kubernetes groups.
Verify kube-oidc-login
1 2 3 4 5
kubectl oidc-login setup \ --oidc-issuer-url=https://authentik.example.com/application/o/kubernetes/ \ --oidc-client-id='YOUR CLIENT ID' \ --oidc-client-secret='YOUR CLIENT SECRET' \ --oidc-extra-scope=kubernetes
Everything should work; just follow the instructions.
Grant permissions to the group in Kubernetes
Authentik will pass the group list, and now we need Kubernetes to pay attention to this. Add the following arguments to the API server:
1 2
--oidc-groups-claim=groups --oidc-groups-prefix=oidc:
Now you can create resources like these:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: oidc:kubernetes:admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: oidc:kubernetes:admin --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: this-name-is-custom roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: oidc:kubernetes:restricted