Dedicated Kubernetes Service Accounts
Prerequisites
-
Akeyless Gateway with network access to the Kubernetes (K8s) cluster.
-
Kubernetes v1.2` or later.
InfoRequired Gateway Access Permissions
To set Kubernetes Authentication method, make sure you have Access Permissions on your Gateway to manage the Kubernetes Auth.
Dedicated ServiceAccount
This flow describes the creation of a dedicated Kubernetes ServiceAccount which will work based on token projection.
For a Rancher cluster, please create your Rancher API Key and refer to Extract Kubernetes Cluster CA Certificate to extract your Rancher server CA certificate.
NoteTo enable and use token request projection on a self-managed cluster, 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-audiencesFor more details, check out the minikube configuration example at the end of this page.
- Create a ServiceAccount named
gateway-token-reviewerwith permission to access token review API. This ServiceAccount will be used to validate a Kubernetes JWT coming from a pod that will try to authenticate to Akeyless.
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: defaultApply:
kubectl apply -f akl_gw_token_reviewer.yamlBearer Token Extraction for Kubernetes Server v1.23 or lower
- Extract the
gateway-token-reviewerServiceAccount secret name:
GW_SA_NAME=$(kubectl get sa gateway-token-reviewer \
--output jsonpath="{.secrets[*]['name']}")- Extract the ServiceAccount
JWTBearer Token (Kubernetes Server <= v1.23):
SA_JWT_TOKEN=$(kubectl get secret $GW_SA_NAME \
--output 'go-template={{ .data.token | base64decode }}')Bearer Token Extraction for Kubernetes Server v1.24 or higher
Kubernetes won’t generate Secrets automatically for ServiceAccounts, to get your ServiceAccount token, run the following commands instead:
- Create the long-lived ServiceAccount secret called
gateway-token-reviewer-token(Kubernetes Server >= v1.24):
apiVersion: v1
kind: Secret
metadata:
name: gateway-token-reviewer-token
namespace: default
annotations:
kubernetes.io/service-account.name: gateway-token-reviewer
type: kubernetes.io/service-account-tokenkubectl apply -f akl_gw_token_reviewer_token.yaml- Extract the ServiceAccount JWT Bearer Token (Kubernetes Server >= v1.24):
SA_JWT_TOKEN=$(kubectl get secret gateway-token-reviewer-token \
--output 'go-template={{.data.token | base64decode}}')Extract Kubernetes Cluster CA Certificate
To extract the Kubernetes cluster CA cert used to talk to Kubernetes API run the following command:
CA_CERT=$(kubectl config view --raw --minify --flatten \
--output 'jsonpath={.clusters[].cluster.certificate-authority-data}')CA_CERT=$(openssl s_client -host <Rancher Server> -port 443 2>&1 | sed -n -e '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/ p' | base64)Create Kubernetes Auth Method
- Use the Akeyless CLI to create the Kubernetes auth method. The result contains an
access Idand aprivate keythat you will need later for the Kubernetes Auth configuration in your Akeyless Gateway:
akeyless create-auth-method-k8s -n my-k8s-auth-method --jsonUpon successful creation, the response:
{
"access_id": "p-abcdefg1234",
"prv_key": "LS0tLS1CRUdJTiBSUlNDUUxt.....QVRFIEtFWS0tLS0tCg=="
}
NoteSave returned private key & AccessID for next steps inside an environment variables
$PRV_KEYand$ACCESS_ID.
Create Kubernetes Gateway Auth Config Using Bearer Tokens
To discover your Kubernetes service account issuer run the following command:
NoteThe Kubernetes Issuer parameter is no longer used by default, as the issuer validation is done by the API server, if you still wish to work with local issuer validation open a new tab to run this command as it starts a server. Then, go back to your original tab to extract the issuer.
Forwarding the Kubernetes API:
kubectl proxy --api-prefix=/k8s-apiExtract the issuer:
K8S_ISSUER=$(curl -s http://localhost:8001/k8s-api/.well-known/openid-configuration | jq -r .issuer)Or extract the issuer directly from your pod token:
K8S_ISSUER=$(jq -R 'split(".") | .[1] | @base64d | fromjson |.iss' <<< $(cat /var/run/secrets/kubernetes.io/serviceaccount/token) -r)Use the Akeyless CLI to create the Kubernetes auth config:
akeyless gateway-create-k8s-auth-config --name k8s-conf \
--gateway-url https://<Your_Akeyless_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_ISSUERakeyless gateway-create-k8s-auth-config --name k8s-conf-rancher \
--gateway-url https://<Your_Akeyless_GW_URL:8000> \
--access-id $ACCESS_ID \
--signing-key $PRV_KEY \
--cluster-api-type rancher \
--k8s-host https://<Rancher Host:443> \
--k8s-ca-cert $CA_CERT \
--k8s-issuer $K8S_ISSUER \
--rancher-api-key <API_KEY_bearer_token> \
--rancher-cluster-id <CLUSTER_ID> \Where:
-
name: The config name (will be used during the authentication process). -
gateway-url: Akeyless Gateway Configuration Manager URL (port8000). -
access-id: TheAccess Idof the Kubernetes auth method that was created. -
signing-key: The private key (base64 encoded) associated with the public key defined in the Kubernetes auth (The private key that was created when the Kubernetes auth method was created previously). -
k8s-host: The URL of your Kubernetes API server or your Rancher server. -
token-reviewer-jwt: The ServiceAccountJWTused to access theTokenReviewAPI (relevant only tonative_k8saccess type). -
k8s-ca-cert: The certificate to use to validate the Kubernetes cluster. -
k8s-issuer: Optional, the Kubernetes JWT issuer name (default iskubernetes/serviceaccount).
When the cluster access type is Rancher, add the following parameters: (in addition to the relevant parameters above)
cluster-api-type: Cluster access type, we will writerancher(default isnative_k8s).rancher-api-key: Rancher Bearer token, based on the created Rancher API Key.rancher-cluster-id: Rancher Cluster ID, i.e., your Rancher API Key Scope.
Authenticate from a pod in your Kubernetes cluster
- Create a namespace in your Kubernetes cluster:
kubectl create namespace my-namespace-a- In this namespace create a pod:
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
./akeyless --init- Authenticate via your Kubernetes auth method with the following parameters:
./akeyless auth --access-id $ACCESS_ID \
--access-type k8s \
--gateway-url https://<Your_Akeyless_GW_URL:8000> \
--k8s-auth-config-name k8s-confWhere:
-
access-id: TheAccess Idof the Kubernetes auth method that was created previously. -
access-type: The Auth Method access type,k8s. -
gateway-url: Akeyless Gateway Configuration Manager URL (port8000). -
k8s-auth-config-name: The Kubernetes auth config name in your Gateway.
Upon successful authentication, the response will be:
Authentication succeeded.
Token: t-bb7b...3564a7c9
NoteDelete the private key and Access ID which you stored as an environment variables
$PRV_KEYand$ACCESS_ID
Available claims for Kubernetes Auth
The following list of claims can be configured within Akeyless Role-based Access Control (RBAC) to control and segregate the relevant policy for Kubernetes.
"service_account_name"
"service_account_uid"
"service_account_secret_name"
"namespace"
"aud"
"pod_name" # available only when "token request projection" is enabled on your Kubernetes cluster
"pod_uid" # available only when "token request projection" is enabled on your Kubernetes clusterEach claim can be enforced as part of your role association to enforce the right policy for your items.
Enable token request projection on Minikube
To enable token request projection on a managed Kubernetes 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
NoteThis example uses
apias the service account issuer name, for your service accounts API audience.
Tutorial
Check out our tutorial video on Kubernetes Authentication.
Updated about 24 hours ago
