logo

cert-manager

Last Updated: 2024-03-03

Read more: Certificates

Why cert-manager?

Cert-manager is needed to properly handle certificate renewal and revocation.

cert-manager adds certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of obtaining, renewing and using those certificates.

Install

install cert-manager:

$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/<version>/cert-manager.yaml

APIs

cert-manager introduces the following concepts / API objects:

  • Certificate: represents a human readable definition of a certificate request that is to be honored by an issuer.
  • CertificateRequest
  • Issuer / ClusterIssuer: represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. An Issuer is a namespaced resource, a ClusterIssuer can be consumed in multiple namespaces.
apiVersion: cert-manager.io/v1
kind: Issuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
# spec.ca.secretName => Secret

apiVersion: cert-manager.io/v1
kind: Certificate
# spec.issuerRef => ClusterIssuer
# secretName => Secret

apiVersion: cert-manager.io/v1
kind: CertificateRequest
# metadata.ownerReferences => Certificate
# spec.issuerRef => ClusterIssuer

https://cert-manager.io/docs/concepts/

Use kubectl explain Certificate to see the details.

Links between objects:

  • Certificate - (issuerRef) -> ClusterIssuer
  • ClusterIssuer - (.spec.ca.secretName) -> Secret

Flow

  • configure an Issuer or ClusterIssuer resource first. (e.g. specify ca secret)
  • user creates A Certificate resource that specifies fields that are used to generate certificate signing requests.
  • When a Certificate is created, a corresponding CertificateRequest resource is created by cert-manager containing the encoded X.509 certificate request, Issuer reference, and other options based upon the specification of the Certificate resource.
  • Issuer or ClusterIssuer issues certificate based on the request.
  • the returned certificate stored in status -> update Certificate -> creates the Secret, the signed certificate will be stored in a Secret resource

Chain

   Secret (`.metadata.annotations."cert-manager.io/issuer-name"`)
=> Issuer/ClusterIssuer (`.spec.ca.secretName`)
=> Secret
=> Issuer/ClusterIssuer
=> ...
=> Secret
=> selfsigned Issuer/ClusterIssuer (`spec.selfSigned: {}`)

caBundle and cainjector

caBundle field can be found

  • ValidatingWebhookConfiguration, MutatingWebhookConfiguration, CustomResourceDefinition: caBundle field is used by the K8s API server to verify a TLS connection to the webhook server.
  • APIService: used to represent an Extension API Server. caBundle can be populated with CA cert, used to validate the API server's serving certificate.

cainjector populates caBundle field: the data source depend on the annotation:

  • cert-manager.io/inject-ca-from: injects caBundle from a cert-manager Certificate.
  • cert-manager.io/inject-ca-from-secret injects caBundle from a k8s Secret.
  • cert-manager.io/inject-apiserver-ca: populate caBundle field using the same CA cert used by the K8s API Server. (Which cainjector itself uses to verify its TLS connection to the Kubernetes API server).

Certs (ca.crt / tls.crt)

The certificate stored in the secret ca-key-pair can then be used to trust newly signed certificates by this Issuer

a public key certificate that identifies a root certificate authority (CA).

ca.crt is the CA's public certificate file. Users, servers, and clients will use this certificate to verify that they are part of the same web of trust. Every user and server that uses your CA will need to have a copy of this file.

  • root certificate: ca.crt
  • server certificate: tls.crt

Check /etc/kubernetes/pki/apiserver.crt should match .clusters[*].cluster.certificate-authority-data in kubeconfig.

For web services

  • service owner specifies the Certificate object.
  • cert-manager ingests Certificate objects, and produces CertificateRequest objects.
  • cert-manager will generate Secrets containing signed certificates.
  • the Istio Gateway object references the Seret the holds the signed certificate. (spec.servers[0].tls.credentialName => Secret)
  • Istio Gateway loads the signed certificate and key from the Secret, and serves the HTTPS endpoint.

Key / Cert Rotation

All certificates have a start and end date. Key rotation: create a new private key AND a new cert periodically.

Certs Extensions

A certificate remains the same thing: a file linking a key to an identity. Its information could be used for any purpose: authenticating a server, a client, signing other certificates, signing emails, signing software/driver code, etc.

That's where extensions enters into play: they tell the application which usages are applicable to this certificate, so that when the application encounters the certificate in an unauthorized context it could (or must, depending if the usage is set to critical or not) consider the certificate as invalid and refuse it.

Commonly found key usages for a SSL/TLS client/server application are the following ones:

  • Server: Digital Signature, Non Repudiation, Key Encipherment,
  • Client: Digital Signature, Key Encipherment, Data Encipherment.

Examples

Server: TLS Web Server Authentication

Certificate:
    Data:
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication

Client: TLS Web Client Authentication

Certificate:
    Data:
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication

CA: CA:TRUE

Certificate:
    Data:
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment, Certificate Sign
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0