# Issue a Certificate for a Kubernetes API Client Using A CertificateSigningRequest

Issue a Certificate for a Kubernetes API Client Using A CertificateSigningRequestKubernetes lets you use a public key infrastructure (PKI) to authenticate to your cluster as a client.A few steps are required in order to get a normal user to be able to authenticate and invoke an API. First, this user must have an X.509 certificate issued by an authority that your Kubernetes cluster trusts. The client must then present that certificate to the Kubernetes API.You use a CertificateSigningRequest as part of this process, and either you or some other principal must approve the request.You will create a private key, and then get a certificate issued, and finally configure that private key for a client.Before you beginYou need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:iximiuz LabsKillercodaKodeKloudPlay with KubernetesYou need the kubectl, openssl and base64 utilities.This page assumes you are using Kubernetes role based access control (RBAC). If you have alternative or additional security mechanisms around authorization, you need to account for those as well.Create private keyIn this step, you create a private key. You need to keep this document secret; anyone who has it can impersonate the user.# Create a private key openssl genrsa -out myuser.key 3072 Create an X.509 certificate signing requestNote:This is not the same as the similarly-named CertificateSigningRequest API; the file you generate here goes into the CertificateSigningRequest.It is important to set CN and O attribute of the CSR. CN is the name of the user and O is the group that this user will belong to. You can refer to RBAC for standard groups.# Change the common name "myuser" to the actual username that you want to use openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser" Create a Kubernetes CertificateSigningRequestEncode the CSR document using this command:cat myuser.csr | base64 | tr -d "\n" Create a CertificateSigningRequest and submit it to a Kubernetes Cluster via kubectl. Below is a snippet of shell that you can use to generate the CertificateSigningRequest.cat <<EOF | kubectl apply -f - apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: myuser # example spec: # This is an encoded CSR. Change this to the base64-encoded contents of myuser.csr request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo= signerName: kubernetes.io/kube-apiserver-client expirationSeconds: 86400 # one day usages: - client auth EOF Some points to note:usages has to be client authexpirationSeconds could be made longer (i.e. 864000 for ten days) or shorter (i.e. 3600 for one hour). You cannot request a duration shorter than 10 minutes.request is the base64 encoded value of the CSR file content.Approve the CertificateSigningRequestUse kubectl to find the CSR you made, and manually approve it.Get the list of CSRs:kubectl get csr Approve the CSR:kubectl certificate approve myuser Get the certificateRetrieve the certificate from the CSR, to check it looks OK.kubectl get csr/myuser -o yaml The certificate value is in Base64-encoded format under .status.certificate.Export the issued certificate from the CertificateSigningRequest.kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt Configure the certificate into kubeconfigThe next step is to add this user into the kubeconfig file.First, you need to add new credentials:kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true Then, you need to add the context:kubectl config set-context myuser --cluster=kubernetes --user=myuser To test it:kubectl --context myuser auth whoami You should see output confirming that you are “myuser“.Create Role and RoleBindingNote:If you don't use Kubernetes RBAC, skip this step and make the appropriate changes for the authorization mechanism your cluster actually uses.With the certificate created it is time to define the Role and RoleBinding for this user to access Kubernetes cluster resources.This is a sample command to create a Role for this new user:kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods This is a sample command to create a RoleBinding for this new user:kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser What's nextRead Manage TLS Certificates in a ClusterFor details of X.509 itself, refer to RFC 5280 section 3.1For information on the syntax of PKCS#10 certificate signing requests, refer to RFC 2986Read about ClusterTrustBundles