Kubernetes Certificate Signing Requests CSR
In a Kubernetes cluster, everything runs on trust. Users, applications, and even node components (like the Kubelet) need a digital “ID card” (a TLS Certificate) to talk to the API Server securely. Instead of an administrator manually creating these ID cards and risking exposing secret passwords, a user can generate a request (the CSR) on their own machine. They send this request to Kubernetes, the admin approves it, and Kubernetes issues the shiny new certificate. It is a highly secure, built-in way to manage identities without ever sharing private keys!
Think of the CSR process exactly like applying for a Passport in India:
- The Private Key (Your Biometrics): You have your fingerprints and retina scan. These are uniquely yours, and you never give them away to anyone.
- The CSR (The Application Form): You fill out a passport application form with your name, address, and photo, and you sign it. This form is your Certificate Signing Request.
- The API Server (The Passport Seva Kendra): You submit your application form here.
- The Admin Approval (Police Verification): An authority checks if you are actually an employee who deserves a passport. They say, “Yes, approve this.”
- The Certificate (The Passport): The Government (Kubernetes Certificate Authority) stamps your form and issues a valid Passport. Now, you can travel (access the cluster) securely!
Quick Reference
- CSR: Certificate Signing Request. A base64-encoded file containing your public key and identity details.
- Private Key: Your secret cryptographic key. Never share this or upload it to Kubernetes.
- SignerName: Tells Kubernetes who should sign this certificate (e.g.,
kubernetes.io/kube-apiserver-clientfor user logins). - Usages: What the certificate will be used for (e.g.,
client auth,server auth).
| Action | Command / Logic |
| Generate Key | openssl genrsa -out user.key 2048 |
| Create CSR File | openssl req -new -key user.key -out user.csr -subj "/CN=myuser/O=dev-team" |
| Submit to K8s | Create a CertificateSigningRequest YAML manifest and kubectl apply -f csr.yaml |
| Check Status | kubectl get csr |
| Approve CSR | kubectl certificate approve <csr-name> |
| Extract Cert | kubectl get csr <csr-name> -o jsonpath='{.status.certificate}' | base64 -d > user.crt |
What is a Kubernetes CSR?
A CertificateSigningRequest resource (certificates.k8s.io/v1) allows a client to ask for a certificate to be signed by a specific signer (Certificate Authority). Once created, the request sits in a Pending state until explicitly approved or denied either manually by a cluster administrator or automatically by a controller.
Key Components of the CSR Object
- Request: The base64-encoded PKCS#10 certificate signing request (generated via tools like OpenSSL).
- SignerName: Identifies which CA should sign the certificate. Examples include:
kubernetes.io/kube-apiserver-client: For human users or external services authenticating to the API server.kubernetes.io/kube-apiserver-client-kubelet: For Kubelets authenticating to the API server.kubernetes.io/kubelet-serving: For Kubelets serving TLS endpoints.
- ExpirationSeconds: (Introduced in v1.22) Specifies the requested lifetime of the certificate.
- Usages: Defines what the certificate is allowed to do (e.g.,
client auth,server auth,digital signature,key encipherment).
The CSR Architecture and Workflow
Let’s break down the exact flow step-by-step so you can easily understand how to onboard a new user.
Step 1: Private Key and CSR Generation Using a tool like OpenSSL, the developer (let’s call him Rahul) opens his terminal and generates a private key. Then, he creates a CSR, mentioning his name (CN=rahul) and his department/group (O=developers). The private key never leaves his machine.
Step 2: Encoding the CSR Kubernetes only understands base64-encoded text for this API object. Rahul converts his rahul.csr file into base64 format. (Pro tip: Use cat rahul.csr | base64 -w 0 on Linux, or cat rahul.csr | base64 | tr -d "\n" on macOS, to avoid hidden line breaks).
Step 3: Creating the Kubernetes Manifest Rahul (or the admin) creates a YAML file of kind CertificateSigningRequest and pastes the base64 string into the request field.
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: rahul-req
spec:
request: <BASE64_ENCODED_CSR_GOES_HERE>
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # 1 day
usages:
- client auth
He submits this to the cluster using kubectl apply -f csr.yaml.
Step 4: Admin Approval The request sits in a Pending state. A cluster administrator logs in, inspects the request using kubectl describe csr rahul-req, verifies Rahul is a real employee, and runs the kubectl certificate approve rahul-req command.
Step 5: Certificate Generation The Kubernetes internal CA (the kube-controller-manager) instantly signs it. The status changes to Approved,Issued.
Step 6: Handover and Access The admin extracts the newly generated certificate from the .status.certificate field and gives it to Rahul. Rahul configures his kubeconfig file with his private key and this new certificate, successfully logging into the cluster!
Let’s break down the exact flow step-by-step so you can easily understand how to onboard a new user.
- Step 1: The User generates their Private Key and CSR. Using a tool like OpenSSL, the developer (let’s call him Rahul) opens his terminal and generates a private key. Then, he creates a CSR, mentioning his name (
CN=rahul) and his department/group (O=developers). - Step 2: Encoding the CSR. Kubernetes only understands base64 encoded text. So, Rahul has to convert his
rahul.csrfile into base64 format. - Step 3: Creating the Kubernetes Manifest. Rahul (or the admin) creates a YAML file of kind
CertificateSigningRequest. He pastes the base64 string into therequestfield of this YAML and submits it to the cluster. - Step 4: Admin Approval. The request sits in a
Pendingstate. A cluster administrator logs in, inspects the request usingkubectl describe csr rahul-req, verifies Rahul is a real employee, and runs thekubectl certificate approve rahul-reqcommand. - Step 5: Certificate Generation. The Kubernetes internal CA instantly signs it. The status changes to
Approved,Issued. - Step 6: Handover. The admin extracts the newly generated certificate and gives it to Rahul. Rahul now configures his
kubeconfigfile with his private key and this new certificate, and he successfully logs into the cluster!
Core Use Cases
- User Authentication (Client mTLS): Kubernetes does not have a native “User” object. Instead, it trusts any user who presents a valid certificate signed by the cluster’s CA. The Common Name (
CN) in the certificate translates to the Kubernetes username, and the Organization (O) translates to the user’s group. - Node Bootstrapping (Kubelet TLS): When a new node joins the cluster, the Kubelet uses the CSR API to request a client certificate (
kube-apiserver-client-kubelet) to talk to the API server, and a serving certificate (kubelet-serving) so the API server can securely securely talk to the Kubelet (e.g., forkubectl execorkubectl logs).
DevSecOps Level
- Strict RBAC for Approvals: Only highly trusted administrators should have the RBAC permissions to
create,update, andapproveCSR resources (apiGroups: ["certificates.k8s.io"]). - Enforce Short Expirations: Utilize the
expirationSecondsfield to issue short-lived certificates. Long-lived certificates increase the risk surface if a private key is compromised, as Kubernetes lacks a native Certificate Revocation List (CRL) mechanism for user certs. - Audit CSR Creation: Monitor audit logs for unusual CSR creations, specifically looking for requests attempting to impersonate high-privilege groups like
system:masters. - Custom Signers: For internal service mesh or webhook TLS, use custom signer names (e.g.,
devsecopsguru.in/internal-webhook) rather than the core Kubernetes signers. - In a production-grade DevSecOps environment, manually approving CSRs via
kubectlis entirely unscalable and anti-pattern. Everything must be automated and governed by policy. - Automated Certificate Management: Relying on the built-in Kubernetes CA for everything is not ideal for massive enterprises. Production clusters use cert-manager, a powerful operator that handles the entire lifecycle of certificates.
- External PKI Integration: Instead of using the kube-controller-manager’s local CA, a DevSecOps architect will configure
cert-managerto integrate with an enterprise Public Key Infrastructure (PKI) like HashiCorp Vault or AWS Private CA.cert-managerintercepts the CSR, authenticates the request, forwards it to Vault to be signed, and pushes the resulting certificate back into Kubernetes. - Kubelet TLS Bootstrapping: In dynamic environments (like AWS Auto Scaling groups), worker nodes scale up and down continuously. You cannot manually approve CSRs for nodes. You must configure Kubelet TLS Bootstrapping where a specialized controller automatically approves CSRs originating from the
system:nodesgroup, provided they have the correct bootstrap token.
Additional Details
- Key Components
- User/Client: Generates the Private Key and CSR.
- CertificateSigningRequest API: The Kubernetes object that holds the request.
- Approver: A human admin or an automated controller with RBAC permissions to update the
/approvalsubresource. - Signer (kube-controller-manager): The component holding the cluster’s Root CA key that actually performs the cryptographic signing.
- Key Characteristics
- Relies on Asymmetric Encryption (Public/Private key pairs).
- Entirely API-driven workflow.
- Data inside the YAML must be strictly base64 encoded.
- Use Case
- Onboarding new human developers who need
kubectlaccess (if OIDC is not available). - Bootstrapping new worker nodes joining the cluster securely.
- Securing internal Admission Webhooks with TLS.
- Onboarding new human developers who need
- Benefits
- High Security: The Private Key never leaves the client’s local machine. No risk of transmission interception.
- Auditability: Every CSR is an API object, meaning creation and approval actions are logged in the Kubernetes Audit Logs.
- Native Integration: No need for external heavy CA software for basic internal cluster needs.
- Best Practices
- Never paste your private key anywhere.
- Always define the principle of least privilege in the CSR Subject (e.g., specific Groups using
O=). - Use external tools like
cert-managerfor production workloads to handle auto-renewal.
- Technical Challenges
- Base64 Padding: Beginners often use
echo "content" | base64which adds a newline character at the end, causing the API server to reject the CSR as “invalid format”. Always usecat file.csr | base64 | tr -d "\n". - Mismatched Usages: Requesting
server authbut using thekubernetes.io/kube-apiserver-clientsigner will fail silently after approval.
- Base64 Padding: Beginners often use
- Limitations
- No native Certificate Revocation List (CRL) support.
- The default controller manager CA is very basic and not suitable as an Enterprise Root CA.
- Common Issues
- Stuck in Pending: The CSR is created but nobody (or no controller) has approved it.
- Approved but not Issued: The CSR was approved, but the controller manager is not configured with the
--cluster-signing-cert-fileand--cluster-signing-key-fileflags, so it lacks the cryptographic material to actually sign it.
- Problems and Solutions
- Problem: I get
x509: certificate signed by unknown authoritywhen trying to use my new cert.- Solution: Your
kubeconfigis missing thecertificate-authority-dataof the cluster’s Root CA. The client needs the Root CA to trust the certificate it was just given.
- Solution: Your
- Problem: CSR is rejected immediately upon submission.
- Solution: Check your base64 encoding for hidden newline characters and ensure the
requestblock in your YAML is perfectly formatted.
- Solution: Check your base64 encoding for hidden newline characters and ensure the
- Problem: I get
Conclusion
Mastering Certificate Signing Requests in Kubernetes is a giant leap forward in your DevSecOps journey. It shifts your mindset from “sharing passwords” to “cryptographic trust without sharing secrets.” While it might look like a few extra steps involving OpenSSL and base64 encoding at first, it is a beautifully designed, highly secure system. Keep practicing the commands, and soon, managing cluster identities will become second nature to you. Happy learning and stay secure!