Kubernetes Auth

📘

Info

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 operating on the customer side and is therefore considered a trusted machine.

Prerequisites

  • Akeyless Gateway with network access to Kubernetes cluster.

  • Kubernetes version 1.21 and higher.

Create service account for Akeyless Gateway

📘

Note:

In general, token request projection will work on a managed K8s cluster.

To enable and use token request projection, you must specify each of the following command line arguments to kube-apiserver:
--service-account-issuer
--service-account-key-file
--service-account-signing-key-file
--api-audiences

For more details check out the minikube configuration example at the end of this page.

  1. Create a service account named gateway-token-reviewer with permission to access token review API. This service account will be used to validate a Kubernetes JWT coming from a pod that will try to authenticate to Akeyless.
cat << EOF > akl_gw_token_reviewer.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gateway-token-reviewer
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: role-tokenreview-binding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: gateway-token-reviewer
  namespace: default 
EOF

Apply:

kubectl apply -f akl_gw_token_reviewer.yaml
  1. Extract the gateway-token-reviewer service account JWT:
GW_SA_NAME=$(kubectl get sa gateway-token-reviewer \
    --output jsonpath="{.secrets[*]['name']}")
  1. Extract the service account JWT:
SA_JWT_TOKEN=$(kubectl get secret $GW_SA_NAME \
    --output 'go-template={{ .data.token }}' | base64 --decode)
  1. Extract the K8s cluster CA cert used to talk to Kubernetes API:
CA_CERT=$(kubectl config view --raw --minify --flatten  \
    --output 'jsonpath={.clusters[].cluster.certificate-authority-data}')

Create Kubernetes Auth Method in your Akeyless Console

  1. Use the Akeyless CLI to create the Kubernetes auth method which will restrict access to 2 different pods, named mypod1 and mypod2 from the namespace my-namespace-a. The result contains an access Id and a private key that you will need later for the K8S Auth configuration in your Gateway:
akeyless create-auth-method-k8s -n my-k8s-auth-method --bound-pod-names mypod1 \
    --bound-pod-names mypod2 --bound-namespaces my-namespace-a --json

Upon successful creation, the response:

{
  "access_id": "p-abcdefg1234",
  "prv_key": "LS0tLS1CRUdJTiBSUlNDUUxt.....QVRFIEtFWS0tLS0tCg=="
}

👍

Tip

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

Create Kubernetes Auth Config in Akeyless Gateway

  1. Use the Akeyless CLI to create the K8S auth config. The following parameters are required:

    name: The config name (will be use during the authentication process)

    gateway-url: Your Gateway URL (default is http://localhost:8000)

    access-id: The access id of the Kubernetes auth method that was created on Akeyless console.

    signing-key: The private key (The key that was created when the Kubernetes auth method was created)

    k8s-host: The URL of your kubernetes API server.

    token-reviewer-jwt: The service account JWT used to access the TokenReview API.

    k8s-ca-cert: The certificate to use to call into your kubernetes API.

    k8s-issuer: The Kubernetes JWT issuer name (default - kubernetes/serviceaccount)

To discover your K8s service account issuer run the following command:

Forwarding the Kubernetes API:

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

Extract the issuer:

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

Create the K8S auth config:

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

Upon successful creation, the response:

K8S Auth config k8s-conf successfully created. ID=[UqeOAkg4UDo...bpv52Iq]

Authenticate from a service account in your Kubernetes cluster

  1. Create a namespace with a name that the auth method access is restricted to:
kubectl create namespace my-namespace-a
  1. In this namespace, create a pod with a name that the auth method access is restricted to:
kubectl run mypod1 --image=nginx -n my-namespace-a
  1. 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
  1. 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
  1. Authenticate via your Kubernetes auth method with the following parameters :

access-id: The access id of the Kubernetes auth method that was created in Akeyless console.

access-type: the access type - k8s

gateway-url: Your Gateway URL (default is http://localhost:8000)

k8s-auth-config-name: The K8S Auth config name in your Gateway.

k8s-token-path: An optional path to a projected service account token inside the pod, for use instead of the default /var/run/secrets/kubernetes.io/serviceaccount/token

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

👍

Tip

Delete the private key and AccessID which you stored as an environment variables $PRV_KEY and $ACCESS_ID

Available claims for K8s Auth

The following list of claims can be configured within Akeyless Access Roles (RBAC) to control and segregate the relevant policy for K8s.

"service_account_name"
"service_account_uid"
"service_account_secret_name"
"namespace"
"aud"
"pod_name"   # available only when "token request projection" is enabled on you Kubernetes cluster
"pod_uid"    # available only when "token request projection" is enabled on you Kubernetes cluster

Each claim can be enforces as part of your role association to enforce the right policy for your items.

Enable token request projection minikube example

To enable token request projection on a managed K8s cluster you can follow this guide.

To get this to work with minikube you can start your cluster with the following configuration.

minikube start \
    --vm-driver=none \
    --extra-config=apiserver.service-account-signing-key-file=/var/lib/minikube/certs/sa.key \
    --extra-config=apiserver.service-account-key-file=/var/lib/minikube/certs/sa.pub \
    --extra-config=apiserver.service-account-issuer=api \
    --extra-config=apiserver.service-account-api-audiences=api,spire-server \
    --extra-config=apiserver.authorization-mode=Node,RBAC \
    --extra-config=kubelet.authentication-token-webhook=true

Did this page help you?