Kubernetes Authentication


Deeper Dive

For more in-depth information, check out our detailed documentation on the following topics:

Kubernetes Authentication


Need any help?

If something in this tutorial isn't working as expected, feel free to contact our support team via Slack.

Below is a text-only guide for users based on the above video

Why use Kubernetes Native Authentication?

Kubernetes Authentication is valuable for two main reasons:

  1. It’s native and easier to work with for Kubernetes workloads
  2. It enables much more specific and drill-down policy segregation and permissions for namespaces, pods, and more which is not available on native Kubernetes.



The Akeyless Kubernetes Auth Method uses the Kubernetes JWT token in order to authenticate the Kubernetes application (e.g. a pod). Throughout the process, this JWT is never shared with Akeyless or any other third party, but only with the Gateway that is controlled and operated on the customer environment. It is therefore considered a trusted machine.


  • Akeyless Gateway with network access to Kubernetes cluster.
  • Kubernetes version 1.21 and higher.

Create service account for Akeyless Gateway

In general, token request projection will work on a managed K8s cluster. In this demo, we are using Amazon EKS.

For a Rancher cluster, please see the docs for more information.

Open your terminal and create a new file called akl_gw_token_reviewer.yaml on your local machine by copying and pasting the below.

cat << EOF > akl_gw_token_reviewer.yaml
apiVersion: v1
kind: ServiceAccount
  name: gateway-token-reviewer
  namespace: default
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
  name: role-tokenreview-binding
  namespace: default
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
- kind: ServiceAccount
  name: gateway-token-reviewer
  namespace: default 

Next, create the service account, called gateway-token-reviewer, by running the below command:

kubectl apply -f akl_gw_token_reviewer.yaml

Bearer Token Extraction

For Kubernetes Server Version 1.23 or Older, see the docs

Create a service account secret by copying and pasting the following in your terminal which creates a file called akl_gw_token_reviewer.yaml:

cat <<EOF > akl_gw_token_reviewer.yaml 
apiVersion: v1
kind: Secret
  name: gateway-token-reviewer-token
  namespace: default
    kubernetes.io/service-account.name: gateway-token-reviewer
type: kubernetes.io/service-account-token

Then, run 'kubectl apply' to create the secret:

kubectl apply -f akl_gw_token_reviewer.yaml

Next, extract the service account JWT Bearer Token and save it as an environment variable:

SA_JWT_TOKEN=$(kubectl get secret gateway-token-reviewer-token \
  --output 'go-template={{.data.token | base64decode}}')

Feel free to check that this worked by running the following:


Extract K8s Cluster CA Certificate

Extract the K8s cluster CA certificate used to talk to Kubernetes API and save it as an environment variable with the following command:

CA_CERT=$(kubectl config view --raw --minify --flatten  \
    --output 'jsonpath={.clusters[].cluster.certificate-authority-data}')

Create Kubernetes Auth Method

Create the Kubernetes Authentication Method either in the UI or CLI. This will be bound to pods mypod1 and mypod2 and the namespace my-name-space-a.

In the UI:

In the CLI:

akeyless create-auth-method-k8s -n my-k8s-auth-method --bound-pod-names mypod1 \
    --bound-pod-names mypod2 --bound-namespaces my-namespace-a --json



Save returned private key & AccessID for next steps inside an environment variables $PRV_KEY and $ACCESS_ID.


Create Kubernetes Auth Config on your Gateway

Open a new tab and run the following command to start the server which allows access to the Kubernetes API server from within a cluster:

kubectl proxy --api-prefix=/k8s-api

Next, extract the Kubernetes OIDC Issuer saved as an environment variable.



JQ needs to be installed for this to work.

K8S_ISSUER=$(curl -s http://localhost:8001/k8s-api/.well-known/openid-configuration | jq -r .issuer)

You can now close the server connection by closing the tab.

Create the auth config within the Gateway by running the following command for a Kubernetes native cluster. You will notice our saved environment variables here:



For a Rancher cluster, see the docs.

akeyless gateway-create-k8s-auth-config  --name k8s-conf \
        --gateway-url <https://Your-GW-URL>:8000 \
        --access-id $ACCESS_ID \
        --signing-key $PRV_KEY \
        --k8s-host=<https://Your-K8s-Cluster-IP:8443> \
        --token-reviewer-jwt $SA_JWT_TOKEN \
        --k8s-ca-cert $CA_CERT \
        --k8s-issuer $K8S_ISSUER

The same thing can be done directly through your Gateway UI by going to the Gateway URL and clicking on the 'Kubernetes Auth' menu item, clicking 'New', and adding your details as follows:

Authenticate from a service account in your Kubernetes cluster

Create the namespace in your Kubernetes cluster that matches the restrictions in our auth method:

kubectl create namespace my-namespace-a

Create a pod inside that namesapce that matches a restricted pod as per our auth method:

kubectl run mypod1 --image=nginx -n my-namespace-a

Start an interactive shell session on the pod and perform the following commands in the pod:

kubectl exec --stdin=true --namespace my-namespace-a  --tty=true mypod1 -- /bin/sh

Install Akeyless CLI inside your pod:

curl -o akeyless https://akeyless-cli.s3.us-east-2.amazonaws.com/cli/latest/production/cli-linux-amd64
chmod +x akeyless

Authenticate via your Kubernetes auth method with the following:

./akeyless auth --access-id $ACCESS_ID \
    --access-type k8s \
    --gateway-url https://<Your-GW-URL>:8000 \
    --k8s-auth-config-name k8s-conf



The first attempt at running the above command might just run a fresh install of the CLI. In that case, type 'n' and 'n' for the first two prompts and run the command again.

Upon successful authentication, you will receive a response like this:

Authentication succeeded.
Token: t-bb7b...3564a7c9



Delete the Private Key and Access ID which you stored as an environment variables $PRV_KEY and $ACCESS_ID

What’s Next