Skip to main content
< All Topics

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-client for user logins).
  • Usages: What the certificate will be used for (e.g., client auth, server auth).

ActionCommand / Logic
Generate Keyopenssl genrsa -out user.key 2048
Create CSR Fileopenssl req -new -key user.key -out user.csr -subj "/CN=myuser/O=dev-team"
Submit to K8sCreate a CertificateSigningRequest YAML manifest and kubectl apply -f csr.yaml
Check Statuskubectl get csr
Approve CSRkubectl certificate approve <csr-name>
Extract Certkubectl 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.

YAML
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.csr file 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 the request field of this YAML and submits it to the cluster.
  • 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 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 kubeconfig file 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., for kubectl exec or kubectl logs).

DevSecOps Level
  • Strict RBAC for Approvals: Only highly trusted administrators should have the RBAC permissions to create, update, and approve CSR resources (apiGroups: ["certificates.k8s.io"]).
  • Enforce Short Expirations: Utilize the expirationSeconds field 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 kubectl is 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-manager to integrate with an enterprise Public Key Infrastructure (PKI) like HashiCorp Vault or AWS Private CA. cert-manager intercepts 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:nodes group, provided they have the correct bootstrap token.
Additional Details
  1. 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 /approval subresource.
    • Signer (kube-controller-manager): The component holding the cluster’s Root CA key that actually performs the cryptographic signing.
  2. Key Characteristics
    • Relies on Asymmetric Encryption (Public/Private key pairs).
    • Entirely API-driven workflow.
    • Data inside the YAML must be strictly base64 encoded.
  3. Use Case
    • Onboarding new human developers who need kubectl access (if OIDC is not available).
    • Bootstrapping new worker nodes joining the cluster securely.
    • Securing internal Admission Webhooks with TLS.
  4. 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.
  5. 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-manager for production workloads to handle auto-renewal.
  6. Technical Challenges
    • Base64 Padding: Beginners often use echo "content" | base64 which adds a newline character at the end, causing the API server to reject the CSR as “invalid format”. Always use cat file.csr | base64 | tr -d "\n".
    • Mismatched Usages: Requesting server auth but using the kubernetes.io/kube-apiserver-client signer will fail silently after approval.
  7. Limitations
    • No native Certificate Revocation List (CRL) support.
    • The default controller manager CA is very basic and not suitable as an Enterprise Root CA.
  8. 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-file and --cluster-signing-key-file flags, so it lacks the cryptographic material to actually sign it.
  9. Problems and Solutions
    • Problem: I get x509: certificate signed by unknown authority when trying to use my new cert.
      • Solution: Your kubeconfig is missing the certificate-authority-data of the cluster’s Root CA. The client needs the Root CA to trust the certificate it was just given.
    • Problem: CSR is rejected immediately upon submission.
      • Solution: Check your base64 encoding for hidden newline characters and ensure the request block in your YAML is perfectly formatted.

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!

Contents
Scroll to Top