> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Lab Solution Certificates API

> Walkthrough for creating, approving, denying, extracting, and managing Kubernetes CertificateSigningRequest objects including embedding PEM CSRs and best practices for secure handling.

This walkthrough demonstrates how to create, approve, deny, and delete Kubernetes CertificateSigningRequest (CSR) objects. We'll follow a real-world scenario: a new team member (Akshay) needs a client certificate to access the cluster. On the control-plane host we find a CSR and its corresponding private key in `/root`. The steps below show how to embed the CSR into a Kubernetes `CertificateSigningRequest` resource, approve it so the cluster issues a certificate, and how to inspect and handle unexpected CSRs.

## Prerequisites

* Access to a control-plane node or a machine with `kubectl` configured to talk to the cluster control plane.
* The CSR file (PEM) and private key available locally (in this example `/root/akshay.csr` and `/root/akshay.key`).

## Inspect the working directory

Confirm the CSR and private key are present:

```bash theme={null}
root@controlplane:~# pwd
/root
root@controlplane:~# ls -l
-rw-r--r-- 1 root root  1234 Apr 17 12:00 akshay.csr
-rw-r--r-- 1 root root  1700 Apr 17 12:00 akshay.key
```

View the CSR (truncated for brevity):

```bash theme={null}
root@controlplane:~# cat akshay.csr
-----BEGIN CERTIFICATE REQUEST-----
MIICVjCCAT4CAQAwETEPMA0G1UEAwwGYWtzaGF5MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEApzFRPPSJHgmyUO9jVrd...
-----END CERTIFICATE REQUEST-----
```

<Callout icon="lightbulb" color="#1CB2FE">
  When embedding a PEM CSR into the `spec.request` field of a `CertificateSigningRequest` manifest, the CSR must be base64-encoded and written as a single continuous line. On Linux, use `base64 -w 0` to produce single-line output.
</Callout>

## Step-by-step: create and approve a CSR

1. Base64-encode the CSR as a single line and save it to a file:

```bash theme={null}
root@controlplane:~# base64 -w 0 akshay.csr > akshay.csr.base64
root@controlplane:~# cat akshay.csr.base64
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMv...
```

2. Create a YAML manifest for the Kubernetes `CertificateSigningRequest`. Replace the `request:` value with the single-line base64 string you generated.

Save the following as `akshay.yaml`:

```yaml theme={null}
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: akshay
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMv...
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400  # one day
  usages:
  - client auth
```

3. Apply the `CertificateSigningRequest` manifest:

```bash theme={null}
root@controlplane:~# kubectl apply -f akshay.yaml
certificatesigningrequest.certificates.k8s.io/akshay created
```

4. Check the CSR list. Newly created CSRs appear in the Pending state until approved:

```bash theme={null}
root@controlplane:~# kubectl get csr
NAME      AGE   SIGNERNAME                                     REQUESTOR          CONDITION
akshay    1m    kubernetes.io/kube-apiserver-client            kubernetes-admin   Pending
```

5. Approve the CSR so the cluster controller will issue a certificate:

```bash theme={null}
root@controlplane:~# kubectl certificate approve akshay
certificatesigningrequest.certificates.k8s.io/akshay approved
```

6. Verify the CSR status is now Approved and Issued:

```bash theme={null}
root@controlplane:~# kubectl get csr
NAME      AGE   SIGNERNAME                                     REQUESTOR          CONDITION
akshay    2m    kubernetes.io/kube-apiserver-client            kubernetes-admin   Approved,Issued
```

7. Extract the issued certificate (base64-decoded) from the CSR object and write it to a PEM file:

```bash theme={null}
root@controlplane:~# kubectl get csr akshay -o jsonpath='{.status.certificate}' | base64 -d > akshay.crt
root@controlplane:~# openssl x509 -in akshay.crt -text -noout
```

This `akshay.crt` is the PEM certificate issued by the cluster. Pair it with the private key (`akshay.key`) to use as a client certificate.

## Inspecting and handling suspicious CSRs

Occasionally you'll see unexpected CSRs (for example, a CSR requesting cluster-admin groups). Inspect such CSRs closely before approving.

Example: a CSR named `agent-smith` requests privileged groups.

1. View the CSR YAML to inspect `spec.groups`, `spec.usages`, and `username`:

```bash theme={null}
root@controlplane:~# kubectl get csr agent-smith -o yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: agent-smith
spec:
  groups:
  - system:masters
  - system:authenticated
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FE...
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - digital signature
  - key encipherment
  - server auth
username: agent-x
status: {}
```

2. If you did not expect this request and it requests privileged groups (like `system:masters`), deny it:

```bash theme={null}
root@controlplane:~# kubectl certificate deny agent-smith
certificatesigningrequest.certificates.k8s.io/agent-smith denied
```

3. Optionally delete the denied CSR from the cluster:

```bash theme={null}
root@controlplane:~# kubectl delete csr agent-smith
certificatesigningrequest.certificates.k8s.io "agent-smith" deleted
```

## Final verification

Check all remaining CSRs and their conditions:

```bash theme={null}
root@controlplane:~# kubectl get csr
NAME       AGE   SIGNERNAME                                          REQUESTOR                CONDITION
akshay     10m   kubernetes.io/kube-apiserver-client                 kubernetes-admin         Approved,Issued
csr-8mfn8  32m   kubernetes.io/kube-apiserver-client-kubelet         system:node:controlplane Approved,Issued
```

## Common CSR commands

| Purpose | Command |
| - | - |
| Create or apply a CSR manifest | `kubectl apply -f akshay.yaml` |
| List CSRs | `kubectl get csr` |
| Get full CSR YAML | `kubectl get csr <name> -o yaml` |
| Approve a CSR | `kubectl certificate approve <name>` |
| Deny a CSR | `kubectl certificate deny <name>` |
| Delete a CSR | `kubectl delete csr <name>` |
| Extract issued certificate from CSR | `kubectl get csr <name> -o jsonpath='{.status.certificate}' \| base64 -d > <name>.crt` |

## Notes and best practices

* Always inspect `spec.groups`, `spec.usages`, and `username` before approving a CSR. Approving a CSR grants the requester the privileges encoded in the certificate.
* Use the appropriate `signerName` for the certificate purpose:
  * `kubernetes.io/kube-apiserver-client` for kube-apiserver clients (client auth).
  * Other built-in signers exist for kubelet serving certificates (e.g., `kubernetes.io/kubelet-serving`) or custom signers for external issuers.
* Base64-encode the CSR as a single-line string before embedding it into `spec.request`.
* Keep private keys secure at all times. Never commit private keys into source control or store them in cluster manifests.

<Callout icon="warning" color="#FF6B6B">
  Do not approve CSRs that request privileged groups (for example `system:masters`) unless you can verify the identity and intent of the requester. Approving such CSRs can grant cluster-admin access.
</Callout>

## Links and references

* [Kubernetes Certificates API](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/)
* [kubectl documentation](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands)
* [Understanding Kubernetes signers and signersNames](https://kubernetes.io/docs/reference/using-api/)

This completes the walkthrough for creating, approving, denying, and deleting Kubernetes CertificateSigningRequest objects.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/cka-certification-course-certified-kubernetes-administrator/module/77826599-d456-4cb5-8cbc-b713cc077b45/lesson/33eb5b1e-0ce7-4b33-b19f-948669de967c" />
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.