Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Analysis of OpenShift node-system-admin-client lifespan

The timing for updating and switching internal certificates in OpenShift

September 29, 2025
George Zheng Wang
Related topics:
KubernetesOperatorsSecurity
Related products:
Red Hat OpenShiftRed Hat OpenShift Container Platform

Share:

    In Red Hat OpenShift Container Platform (RHOCP), a robust Public Key Infrastructure (PKI) managed by various operators secures internal communication. One critical component is the node-system-admin-client certificate, which is used by the system:admin user. This user possesses the cluster-admin role, granting it the highest level of privileges required for cluster administration and maintenance tasks.

    This article provides a detailed analysis of this certificate's lifecycle, addressing a common point of confusion: the discrepancy between its configured validity period in the source code and its actual expiration date. We will explore the certificate chain, investigate the relevant operator source code, and simulate a manual rotation to understand the underlying mechanics.

    Certificate rotation

    We will refer to OpenShift 4.16 in this article. For a freshly installed OpenShift cluster, Figure 1 illustrates the certificate rotation for node-system-admin-client.

    An illustration of OpenShift cluster certificate rotation for node-system-admin-client.
    Figure 1: This illustrates a freshly installed OpenShift cluster.

    Figure 2 illustrates an existing OCP cluster after rotation.

    An illustration of an existing OCP cluster after rotation.
    Figure2: This illustrates an existing OpenShift cluster after rotation.

    Certificate and signer inspection

    Upon inspecting a cluster, we can observe the details of the node-system-admin-client certificate and its signer.

    First, let's examine the client certificate stored in a secret within the openshift-kube-apiserver-operator namespace.

    # Inspect the client certificate details
    oc get secret -n openshift-kube-apiserver-operator node-system-admin-client -o jsonpath='{.data.tls\.crt}' | base64 --decode | openssl x509 -noout -issuer -subject -dates
    # issuer=CN=openshift-kube-apiserver-operator_node-system-admin-signer@1752634724
    # subject=O=system:masters, CN=system:admin
    # notBefore=Jul 16 02:58:51 2025 GMT
    # notAfter=Jul 16 02:58:44 2026 GMT

    Next, we inspect its issuer, the node-system-admin-signer certificate:

    # Inspect the signer (CA) certificate details
    oc get secret -n openshift-kube-apiserver-operator node-system-admin-signer -o jsonpath='{.data.tls\.crt}' | base64 --decode | openssl x509 -noout -issuer -subject -dates
    # issuer=CN=openshift-kube-apiserver-operator_node-system-admin-signer@1752634724
    # subject=CN=openshift-kube-apiserver-operator_node-system-admin-signer@1752634724
    # notBefore=Jul 16 02:58:43 2025 GMT
    # notAfter=Jul 16 02:58:44 2026 GMT

    The output clearly shows that both the client certificate and its signer have a validity of one year. To confirm the integrity of the chain, we can perform a verification:

    # Step 1: Extract the client certificate
    oc get secret -n openshift-kube-apiserver-operator node-system-admin-client -o jsonpath='{.data.tls\.crt}' | base64 --decode > client.crt
    # Step 2: Extract the signer's root certificate
    oc get secret -n openshift-kube-apiserver-operator node-system-admin-signer -o jsonpath='{.data.tls\.crt}' | base64 --decode > root-for-csr-signer.crt
    # Step 3: Verify the certification chain
    openssl verify -CAfile root-for-csr-signer.crt client.crt
    # client.crt: OK

    The successful verification confirms that root-for-csr-signer.crt is the direct issuer of client.crt.

    Investigating the validity discrepancy

    A review of the cluster-kube-apiserver-operator source code reveals that the node-system-admin-client certificate is intended to have a two-year validity period.

    certrotation.RotatedSelfSignedCertKeySecret{
    			Namespace: operatorclient.OperatorNamespace,
    			Name:      "node-system-admin-client",
    			// ... annotations ...
    			// This needs to live longer then control plane certs so there is high chance that if a cluster breaks
    			// because of expired certs these are still valid to use for collecting data using localhost-recovery
    			// endpoint with long lived serving certs for localhost.
    			Validity: 2 * 365 * defaultRotationDay, // Configured for 2 years
    			// We rotate sooner so certs are always valid for 90 days (30 days more then kube-control-plane-signer)
    			Refresh:                30 * defaultRotationDay,
    			// ... other parameters ...
    			},

    The code comment indicates a clear intention: this certificate should be long-lived to aid in cluster recovery scenarios where other control plane certificates might have expired. So, why do we observe only a one-year validity?

    The answer lies in a fundamental principle of PKI: a leaf certificate's validity period cannot extend beyond that of its signing CA.

    By examining the source code for the node-system-admin-signer, we find its configuration:

    		certrotation.RotatedSigningCASecret{
    			Namespace: operatorclient.OperatorNamespace,
    			Name:      "node-system-admin-signer",
    			// ... annotations ...
    			Validity: 1 * 365 * defaultRotationDay, // Configured for 1 year
    			// Refresh set to 80% of the validity.
    			// This range is consistent with most other signers defined in this pkg.
    			Refresh:                292 * defaultRotationDay,
    			// ... other parameters ...
    		},

    The signer CA itself is configured with a one-year validity. Therefore, even though the node-system-admin-client certificate requests a two-year lifespan, it is ultimately constrained by its issuer's one-year expiration date.

    Simulating the signer CA rotation

    To further understand the relationship between the signer and the client certificate, we can simulate a manual rotation of the signer CA. The following steps demonstrate what happens when renewing the CA.

    Note: In a live cluster, the operator automatically handles the certificate rotation based on the Refresh interval. The manual deletion of a secret is a disruptive action used here for demonstration purposes. The actual rotation process is more graceful and includes mechanisms to ensure trust is maintained by bundling old and new CAs.

    Step 1: Capture the initial state

    First, we will document the creation timestamps and serial numbers of the existing signer and client certificates.

    The signer CA details:

    oc get secret node-system-admin-signer -n openshift-kube-apiserver-operator -o=jsonpath='{.metadata.creationTimestamp}{"\n"}'
    # 2025-07-08T22:40:46Z
    oc get secret node-system-admin-signer -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -serial -issuer -subject -dates
    # serial=038106BD877BDCBE
    # issuer=CN = openshift-kube-apiserver-operator_node-system-admin-signer@1752014437
    # ...

    The following shows the client certificate details:

    oc get secret node-system-admin-client -n openshift-kube-apiserver-operator -o=jsonpath='{.metadata.creationTimestamp}{"\n"}'
    # 2025-07-08T22:40:53Z
    oc get secret node-system-admin-client -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -serial -issuer -subject -dates
    # serial=023EE1F3311AF1D5
    # issuer=CN = openshift-kube-apiserver-operator_node-system-admin-signer@1752014437
    # ...
    

    Step 2: Manually trigger rotation

    We can force the operator to regenerate the signer CA by deleting its corresponding secret.

    oc delete secret node-system-admin-signer -n 
    openshift-kube-apiserver-operator

    Step 3: Observe the aftermath

    The operator will quickly create a new signer secret. Let's inspect it.

    The following is the new signer CA details (updated):

    oc get secret node-system-admin-signer -n openshift-kube-apiserver-operator -o=jsonpath='{.metadata.creationTimestamp}{"\n"}'
    # 2025-07-17T06:30:49Z
    oc get secret node-system-admin-signer -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -serial -issuer -subject -dates
    # serial=31A8CCE1005C0642
    # issuer=CN = openshift-kube-apiserver-operator_node-system-admin-signer@1752733849
    # ...

    Now, let's check the client certificate. The following shows the client certificate details (not updated):

    oc get secret node-system-admin-client -n openshift-kube-apiserver-operator -o=jsonpath='{.metadata.creationTimestamp}{"\n"}'
    # 2025-07-08T22:40:53Z
    oc get secret node-system-admin-client -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -serial -issuer -subject -dates
    # serial=023EE1F3311AF1D5
    # issuer=CN = openshift-kube-apiserver-operator_node-system-admin-signer@1752014437
    # ...

    This is a critical observation: rotating the signer CA does not automatically trigger the renewal of the leaf certificates it has issued. The old client certificate remains untouched.

    Step 4: Verify the broken chain

    If we try to verify the old client certificate against the new CA, the validation fails as expected.

    # Extract the new CA certificate
    oc get secret node-system-admin-signer -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d > new-ca.crt
    # Extract the (old) leaf certificate
    oc get secret node-system-admin-client -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d > old-leaf.crt
    # Verify the chain
    openssl verify -CAfile new-ca.crt old-leaf.crt
    # O = system:masters, CN = system:admin
    # error 20 at 0 depth lookup: unable to get local issuer certificate
    # error old-leaf.crt: verification failed

    The "unable to get local issuer certificate" error confirms that the issuer of old-leaf.crt is not new-ca.crt.

    Forcing the client certificate renewal

    To fix the broken chain, we must force the node-system-admin-client certificate to be renewed and signed by the new CA. This can be done by removing the auth.openshift.io/certificate-not-after annotation from the secret, which signals the operator to regenerate it.

    oc patch secret node-system-admin-client -n openshift-kube-apiserver-operator -p='{"metadata": {"annotations": {"auth.openshift.io/certificate-not-after": null}}}'

    After patching, the operator re-issues the client certificate. Let's inspect the new details:

    # Get serial number and issuer of the renewed client certificate
    oc get secret node-system-admin-client -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -serial -issuer -subject -dates
    # serial=028AC59829CF3F15
    # issuer=CN = openshift-kube-apiserver-operator_node-system-admin-signer@1752733849
    # subject=O = system:masters, CN = system:admin
    # notBefore=Jul 17 06:52:17 2025 GMT
    # notAfter=Jul 17 06:30:49 2026 GMT

    The issuer now matches the new signer CA. Finally, we can verify the complete, valid chain.

    # Extract the new CA certificate
    oc get secret node-system-admin-signer -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d > new-ca.crt
    # Extract the new leaf certificate
    oc get secret node-system-admin-client -n openshift-kube-apiserver-operator -o=jsonpath='{.data.tls\.crt}' | base64 -d > new-leaf.crt
    # Verify the chain
    openssl verify -CAfile new-ca.crt new-leaf.crt
    # new-leaf.crt: OK

    Wrap up

    This article provides an in-depth analysis of the node-system-admin-client certificate lifecycle in OpenShift, focusing on the discrepancy between its configured two-year validity and its actual one-year expiration. The analysis reveals that a leaf certificate's validity is constrained by its signing Certificate Authority (CA), which in this case has a one-year lifespan. The article further demonstrates that rotating the signer CA does not automatically renew issued leaf certificates, and manual intervention is required to force client certificate renewal by manipulating annotations on the certificate's secret. This highlights key aspects of OpenShift's internal PKI management, including issuer constraints on validity, the actual lifespan of the node-system-admin-client certificate, rotation mechanics, and manual renewal processes.

    In summary, we demonstrated the following key aspects of the OpenShift internal PKI management.

    • Issuer constrains validity: The effective validity of a certificate is capped by the expiration date of its signing CA.
    • node-system-admin-client lifespan: While configured for two years for recovery purposes, its actual lifespan is one year due to its signer's configuration.
    • Rotation mechanics: The rotation of a signing CA does not automatically trigger the renewal of all certificates it has issued. Leaf certificates are renewed based on their own lifecycle triggers.
    • Manual renewal: Certificate renewal can be forced by manipulating annotations on the certificate's secret, signaling the managing operator to take action.

    Related Posts

    • Easily expanding Red Hat OpenShift clusters

    • Get started with the OpenShift Cluster Observability Operator

    • Wiping the Slate Clean with the OpenShift Container Platform

    • How to connect Kubernetes clusters with Service Interconnect

    Recent Posts

    • How to implement and monitor circuit breakers in OpenShift Service Mesh 3

    • Analysis of OpenShift node-system-admin-client lifespan

    • What's New in OpenShift GitOps 1.18

    • Beyond a single cluster with OpenShift Service Mesh 3

    • Kubernetes MCP server: AI-powered cluster management

    What’s up next?

    In this activity, you will connect services distributed across multiple OpenShift clusters using Red Hat Service Interconnect to establish a Virtual Applications Network and seamlessly leverage a GitOps workflow for service management.

    Start the activity
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue