Whitepaper: Trilio Site Recovery (TSR) — DR for Kubernetes-native VMs

Over the last few years, OpenShift has established itself as the leading enterprise-grade container orchestration platform, allowing organizations to deploy and manage containerized applications at scale. Securing a unified orchestration platform that manages both containers and virtualization, such as OpenShift, is fundamentally different from traditional, perimeter-based server security. While conventional security mechanisms focus on isolated operating systems, securing containers is a far different task. Containers rely on a shared host kernel, making misconfigurations a critical risk that can affect multiple tenant workloads. 

Successful security implementation relies on declarative policies defined as code, integrating security checks directly into the development and deployment process. This approach, coupled with the platform’s reliance on immutable infrastructure and fine-grained network control, differentiates it completely from traditional practices and makes expertise in its unique controls crucial for platform resilience. 

In this article, we explore the native security controls in OpenShift and the practical steps needed to maintain a hardened environment.

Summary of key OpenShift security best practices 

The following table summarizes the key OpenShift Security practices discussed in this article.

Best practiceDescription
Harden the cluster foundation with native host securityConfigure OS-level security policies using the Machine Config Operator (MCO) to enforce immutability.
Harden the software supply chainRequire UBI and enforce image signing alongside continuous vulnerability scanning before deployment.
Enforce runtime security and least privilege accessConfigure SCCs and RBAC to restrict pod capabilities on the host and limit user/service account access via the API.
Ensure secure cluster certificate managementRotate the API and ingress controller certificates and enforce the use of custom, trusted CA bundles to maintain secure communication.
Automate continuous compliance and vulnerability auditsUtilize the Compliance Operator to continuously audit configuration against industry benchmarks and automatically remediate failures.
Protect data at rest with native encryptionEnable etcd encryption to secure stored secrets and provision encrypted storage classes for all sensitive data volumes (PVCs).
Implement node-level file integrity monitoringUse the File Integrity Operator to automate scanning of critical system files.

Automated Application-Centric Red Hat OpenShift Data Protection & Intelligent Recovery

Understanding OpenShift security

Securing OpenShift demands a complete departure from how teams traditionally shield infrastructure. Moving to a shared cluster environment brings technical complications that can jeopardize the entire system if left unmanaged.

Virtual machines isolate workloads by providing a full, dedicated operating system, but containers operate differently: They share the host kernel to maximize efficiency. This specific design choice creates a single point of failure where a kernel-level vulnerability exposes every workload on that machine. Granting excessive privileges to pods makes this threat even worse because if a container runs as root, an attacker can leap directly from a compromised pod into the underlying host hardware.

System consistency is another major pain point. Admins often fall back on old habits, such as logging into individual nodes to make changes or apply manual patches. This behavior creates configuration drift. When nodes become unique, they are impossible to audit reliably. Automation tools often miss the security gaps hidden inside these custom configurations. Without a predictable, uniform environment, verifying the cluster’s security state becomes a guessing game.

Internal networks represent another attack vector. Default cluster networking is flat, allowing any pod to talk to any other pod. A breach in a low-priority application gives an attacker the chance to move across the internal network and hunt for sensitive data. These risks collide with software supply chain issues. Pulling unverified images from public sources essentially invites vulnerabilities into the production stack before the application even starts.

Managing these risks depends on a combination of platform features and human oversight. OpenShift mitigates many of these threats natively—it enforces security by default and provides an immutable host operating system. These integrated layers shrink the attack surface without extra work, but other areas require active administration. 

The following sections explore these integrated layers and demonstrate how to implement a truly hardened production cluster.

Harden the cluster foundation with native host security

Container security is a continuous lifecycle rather than a single configuration event. It requires a protective layer that follows the application from initial development through to production execution. OpenShift addresses this by embedding security directly into the underlying infrastructure.

Host OS lifecycle management

The security of any container is inseparable from the host on which it runs. OpenShift utilizes Red Hat Enterprise Linux CoreOS (RHCOS) to provide an immutable environment that functions as a native cluster component. During cluster upgrades, the platform performs a rolling replacement of node configurations. This architectural choice maintains OS consistency across the entire infrastructure and eliminates the need for manual, per-node maintenance.

The following integrated features define the security posture of RHCOS:

  • Immutable infrastructure: By mounting the /usr directory as read-only, RHCOS blocks users or malicious processes from modifying core system binaries. Even if an attacker gains high-level access, they cannot easily tamper with the underlying OS.
  • Minimal footprint: RHCOS removes unnecessary packages. By only including the bare minimum required for the container runtime and Kubernetes, you have significantly fewer entry points to defend.
  • Automated updates via MCO: The Machine Config Operator (MCO) treats the OS like any other cluster resource. It handles security patches through a controlled, rolling process, ensuring that every node stays in sync.
  • SELinux enforced by default: SELinux is active by default and mandatory. It provides the isolation needed to keep containers from interacting with each other or the host. Red Hat does not support disabling SELinux on RHCOS; if a node is found with SELinux disabled, it must be reprovisioned from scratch. This policy is what makes multi-tenancy viable on the platform.
  • Transactional updates: Using rpm-ostree allows for transactional updates. If a patch fails or causes a regression, you can roll back to the previous known-good state without leaving the system in a broken, half-patched mess.
  • Automated provisioning: Every node starts from a verified state via Ignition. This removes the “manual tweak” factor from the initial setup, ensuring that the infrastructure is identical from day one.

Hardening the host with kernel-level protections

The Machine Config Operator (MCO) can be used to blacklist risky kernel modules, like USB storage drivers, that could be exploited in edge environments or data centers with high physical traffic. The MachineConfigs can be created using Butane, which is a CLI tool used for generating and validating MachineConfigs for OpenShift. The Butane CLI can be downloaded here.

Create a Butane file named usb-lockdown.bu. This file instructs the OS to block the loading of the USB driver on worker nodes by pointing it to /bin/false. 

    
     variant: openshift
version: 4.20.0
metadata:
  name: 05-worker-usb-host-hardening
  labels:
    machineconfiguration.openshift.io/role: worker
storage:
  files:
    - path: /etc/modprobe.d/block-usb-storage.conf
      mode: 0644
      contents:
        inline: |
          blacklist usb-storage
          install usb-storage /bin/false



$ butane usb-lockdown.bu -o usb-lockdown.yaml
$ oc apply -f usb-lockdown.yaml


    
   

Once the changes have been applied, the MCO will now take over, performing a coordinated “cordon, drain, and reboot” cycle across the worker nodes to bake the change into the OS layer.

Automated Red Hat OpenShift Data Protection & Intelligent Recovery

Perform secure application-centric backups of containers, VMs, helm & operators

Use pre-staged snapshots to instantly test, transform, and restore during recovery

Scale with fully automated policy-driven backup-and-restore workflows

Hardening the software supply chain

Protecting a containerized application requires a multi-layered defense strategy that spans the entire software lifecycle. This security model begins with a trusted base image and follows the application through every stage of the build process as it moves through the CI/CD pipeline. By addressing risks early in the development phase, you ensure that security is built into the application rather than added as an afterthought.

In addition to the initial build, security must also account for the interaction between the container and the underlying platform. This includes verifying image signatures, scanning for vulnerabilities, and enforcing strict runtime policies to ensure security. When these layers work together, they create a secure environment capable of defending against both known exploits and emerging threats.

Trusted content for cluster components

A container is only as secure as its base image. Since every container carries its own OS dependencies, the choice of that base layer dictates the security of your entire stack. OpenShift uses Universal Base Images (UBI) to solve the problem of fragmented, unpatched community images.

UBIs are stripped-down, hardened versions of Red Hat Enterprise Linux. Using UBI ensures that you leverage a supply chain that provides vetted patches and a defined support lifecycle. OpenShift builds its own control plane and internal services on these same images. This consistency results in an environment where both platform components and user applications run on a hardened foundation that meets enterprise compliance standards.

Signature verification of container images

Red Hat provides cryptographic signatures for all images within its official container registries. When signature verification is enabled, the MCO can automatically validate these signatures as images are pulled into the OpenShift cluster. This process ensures that the content of the downloaded container images has not been altered or tampered with between the Red Hat registry and your local infrastructure.

To enable container signature validation for Red Hat Container Registries, you can write a signature after specifying the keys to verify images from these registries. To enforce container image signature verification, apply a machine configuration across the cluster nodes. Download the Butane utility to generate the necessary configuration files. In the example below, we create a Butane config file, 51-worker-rh-registry-trust.bu, containing the necessary configuration for the worker nodes.

    
     variant: openshift
version: 4.20.0
metadata:
  name: 51-worker-rh-registry-trust
  labels:
    machineconfiguration.openshift.io/role: worker
storage:
  files:
    - path: /etc/containers/policy.json
      mode: 0644
      overwrite: true
      contents:
        inline: |
          {
            "default": [
              {
                "type": "insecureAcceptAnything"
              }
            ],
            "transports": {
              "docker": {
                "registry.access.redhat.com": [
                  {
                    "type": "signedBy",
                    "keyType": "GPGKeys",
                    "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                  }
                ],
                "registry.redhat.io": [
                  {
                    "type": "signedBy",
                    "keyType": "GPGKeys",
                    "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                  }
                ]
              },
              "docker-daemon": {
                "": [
                  {
                    "type": "insecureAcceptAnything"
                  }
                ]
              }
            }
          }


    
   

We then use Butane to generate a machine config YAML file and apply it to the cluster. Afterwards, we verify that the worker machine config pool is updating.

    
     $ butane 51-worker-rh-registry-trust.bu -o 51-worker-rh-registry-trust.yaml
$ oc apply -f 51-worker-rh-registry-trust.yaml
$ oc get mcp
    
   

Vulnerability scanning and registry security

Integrating scanning tools directly into the development pipeline allows you to maintain clear visibility into the code that is being deployed via containers. OpenShift provides the tools to scan every container image for hidden risks. For instance, Red Hat Advanced Cluster Security (RHACS) can be used to perform a deep analysis on every image layer to identify known vulnerabilities. The cluster constantly monitors the registry for new threats that emerge after the initial build. By enforcing strict distribution controls and triggering immediate alerts upon risk detection, the registry serves as a proactive gatekeeper for the entire cluster.

RHACS for Kubernetes provides continuous protection by periodically scanning all active container images within the cluster. This automated process ensures that image scan results are consistently updated to reflect the most current vulnerability definitions and threat intelligence. To facilitate these checks, RHACS utilizes its native Scanner V4 engine. The Scanner V4 engine uses sources such as RedHat Vex, OSV, and NVD for identifying vulnerabilities.  

To view the vulnerable images in your cluster:

  1. Access the web UI via the Central route in your OpenShift console.
  2. In the left-hand navigation menu, click on Vulnerability Management and then Dashboard.
  3. The dashboard highlights the top riskiest images based on the number and severity of discovered CVEs. This allows you to focus on the most critical threats first.
  4. Click on a specific image to see exactly which layer introduced a vulnerability.

RHACS also provides a command-line interface, “roxctl”, which can be downloaded here. To authenticate to the cluster using roxctl, generate an API token as follows:

  1. In the RHACS portal, go to Platform Configuration -> Integrations.
  2. Go to the Authentication Tokens category and then click API Token.
  3. Click Generate Token and enter a name.
  4. Select a role that provides the required level of access 

First, assign the generated API token to the ROX_API_TOKEN variable, and retrieve the RHACS route to set the ROX_CENTRAL_ADDRESS with the required port suffix. Once both environment variables are set, verify that the CLI can authenticate and communicate with your RHACS instance. 

    
     $ export ROX_API_TOKEN=<api_token>
$ export ROX_CENTRAL_ADDRESS=$(oc get route central -n stackrox -o jsonpath='{.spec.host}'):443
$ roxctl central debug dump --endpoint "$ROX_CENTRAL_ADDRESS"
    
   

Run the following command to scan images.

    
     $ roxctl image scan --endpoint "$ROX_CENTRAL_ADDRESS" --image quay.io/my-org/my-app:v1.0 --output table
    
   

Enforce runtime security and least privilege access

Once the supply chain has been scanned and verified, the next step is to control what the containers can do inside the cluster. OpenShift uses Security Context Constraints (SCCs) and RBAC to basically strip away any permissions a pod doesn’t strictly need. By forcing workloads to run with restricted profiles, the cluster blocks containers from gaining root privileges or accessing host-level files. This approach effectively shrinks the “blast radius”; if a single app gets hit, these native guardrails keep the attacker trapped in a low-privilege sandbox.

Controlling runtime privileges and permissions

To maintain operational integrity, any container orchestration platform must be able to verify the security parameters of a workload before it reaches the cluster node. At the point of admission, the cluster must define precisely what a container is allowed to do. OpenShift uses SCCs to achieve this functionality. The SCCs act as the primary filter for enforcing the principle of least privilege at runtime. For example, SCCs can dictate whether a pod can access the host network, mount sensitive files, or run as a root user. By setting these boundaries at the point of entry, OpenShift ensures that a compromised application cannot easily impact other workloads or the underlying host.

To verify the effectiveness of SCCs, we’ll create a pod that attempts to bypass security boundaries by requesting root user privileges and direct access to the host node’s network.

First attempt to create a pod with the following manifest.

    
     apiVersion: v1
kind: Pod
metadata:
  name: security-violation-pod
spec:
  hostNetwork: true
  containers:
  - name: alpine
    image: alpine
    securityContext:
      runAsUser: 0
    command: ["sleep", "3600"]
    
   
    
     $ oc apply -f badpod.yaml 
Error from server (Forbidden): error when creating "badpod.yaml": pods "security-violation-pod" is forbidden: unable to validate against any security context constraint: Forbidden: not usable by user or serviceaccount, provider "openshift-ai-llminferenceservice-scc": Forbidden: not usable by user or serviceaccount, provider "anyuid": Forbidden: not usable by user or serviceaccount, provider "pipelines-scc": [.............]
    
   

As can be seen, the SCCs act as an admission controller, immediately evaluating high-risk requests against the cluster’s policies. As the pod lacks the specific authorization to use such risky configurations, the SCC blocks the pod from ever reaching a “Running” state.

To simplify the enforcement of advanced security policies such as seccomp and SELinux, OpenShift offers the Security Profiles Operator. Instead of manually configuring these policies on every node, you can define them as standard resources that automatically sync to every node in a specific namespace. This approach ensures that security settings remain consistent and easy to track across your environment.

Once these policies are defined, a background process continuously monitors the cluster to keep profiles up to date and correct any unauthorized changes.

Note that the Security Profiles Operator can only be configured to work with RHCOS nodes in the cluster; standard Red Hat Enterprise Linux (RHEL) nodes are not supported.

The “restricted-v2” SCC in OpenShift automatically enforces the RuntimeDefault seccomp profile. This ensures that every container starts with a restricted set of system calls, providing a baseline of security. Administrators can create custom profiles to specifically block individual system calls based on the application’s unique security requirements.

    
     $ oc get scc restricted-v2 -o custom-columns=SECCOMP_PROFILE:.seccompProfiles
SECCOMP_PROFILE
[runtime/default]


    
   

Authorization and RBAC

In addition to limiting the capabilities of containers, the cluster must also determine who can perform what actions within the environment. OpenShift utilizes role-based access control (RBAC) to define fine-grained permissions for users and groups, which ensures that every API request is both authenticated and authorized. This provides a need-to-know access model that prevents unauthorized users from modifying sensitive configurations.

The following illustrates how RBAC enforces strict isolation between projects, ensuring that a user’s authority is confined to their assigned project.

    
     $ oc whoami
dev-user
$ oc auth can-i delete pods -n openshift-ingress --as=dev-user
no
    
   

Securing non-human access

In an automated environment, service accounts often carry more risk than human users because pods use them to access cluster resources. OpenShift manages this risk by strictly limiting the privileges of these accounts to prevent over-permissioning. Service accounts can be assigned roles in the same way that users are assigned role-based access. Furthermore, the keys for service accounts associated with cluster components are automatically rotated. This focus on non-human access neutralizes the danger of a compromised pod being used to escalate privileges across the cluster.

The following demonstrates that OpenShift applies the same “least-privilege” principle to non-human identities as it does to human users, ensuring that a ServiceAccount’s authority is strictly bounded to its intended project. 

    
     $ oc auth can-i get secrets -n openshift-config --as=system:serviceaccount:my-app:app-reader
    
   

Ensure secure cluster certificate management

In this section, we move from the identity of users and workloads to the identity of the infrastructure itself. Certificate management is the foundation of trust in OpenShift, ensuring that every interaction, whether from an external user or an internal service, is encrypted and verified. The following pillars outline how to secure and maintain the cluster’s cryptographic trust.

Ingress certificate replacement

The Ingress Operator automatically generates a self-signed wildcard certificate for the .apps subdomain during installation. This is fine for a lab but not suitable for production. Using self-signed certificates triggers untrusted connection warnings in browsers and breaks many automated API clients. 

You can replace the default ingress certificate with one signed by a CA that your organization trusts. Once you update the Ingress Controller with a valid certificate, you establish a legitimate identity for all applications on the platform. This removes security blocks for end users and ensures that external traffic follows your corporate encryption standards.

The default ingress certificate can be replaced for the entire “.apps” subdomain. This update automatically secures all hosted applications, the web console, and CLI communications under a single, trusted certificate.

Before changing the certificate, ensure that your setup meets the following requirements:

  • The user must have a wildcard certificate for the fully qualified .apps subdomain and its corresponding private key, with each stored in a separate PEM format file.
  • The private key must be unencrypted, which requires the user to decrypt the key before importing it if a passphrase is currently in place.
  • The certificate must include the subjectAltName extension, specifically identifying *.apps.<clustername>.<domain>.
  • The certificate file must contain a properly ordered chain, starting with the wildcard certificate, followed by intermediate certificates, and ending with the root CA.
  • The user must copy the root CA certificate into a separate, additional PEM format file.
  • Every certificate entry ending with the —–END CERTIFICATE—– tag must be verified to include exactly one carriage return immediately following that line.

To implement the change, follow these steps:

  1. Create a config map in the openshift-config namespace that includes only the root CA certificate used to sign the wildcard certificate.
  2. Update the cluster-wide proxy configuration to reference this newly created config map, which ensures that internal cluster components trust the custom certificate authority.
  3. Create a secret containing the full wildcard certificate chain along with the corresponding private key to be used by the ingress traffic controller.
  4. Modify the Ingress Controller configuration to reference the new secret, allowing the cluster to serve the custom certificate for all applications and console services.
    
     $ oc create configmap custom-ca --from-file=ca-bundle.crt=</path/to/root-ca.crt> -n openshift-config
$ oc patch proxy/cluster --type=merge --patch='{"spec":{"trustedCA":{"name":"custom-ca"}}}'
$ oc create secret tls <secret> --cert=</path/to/cert.crt>  --key=</path/to/cert.key> -n openshift-ingress
$ oc patch ingresscontroller.operator default --type=merge -p
'{"spec":{"defaultCertificate": {"name": "<secret>"}}}'
-n openshift-ingress-operator

    
   

API server and control plane trust

The API server is the heart of the cluster, and its security is paramount. Managing and rotating the serving certificates for the API server ensures that the communication between the CLI, the web console, and the control plane remains encrypted and authentic. Proper lifecycle management of these certificates prevents service interruptions and protects the administrative entry points from man-in-the-middle attacks.

By default, the API server uses a certificate generated by an internal cluster certificate authority. To accommodate specific client requests, such as those routed through a load balancer or reverse proxy, the user can provide additional certificates that the API server serves based on the requested fully qualified domain name (FQDN).

Before updating the API server, the user must ensure that the following prerequisites are met:

  • The user must obtain a certificate specifically for the target FQDN along with its matching private key, maintaining each in a distinct PEM format file.
  • The private key is required to be unencrypted; if it is currently protected by a passphrase, the user must decrypt it prior to the import process.
  • The certificate must be configured with the subjectAltName extension that explicitly lists the requested FQDN.
  • The certificate file should contain the complete trust chain, beginning with the API server FQDN certificate, followed by any necessary intermediate certificates, and concluding with the root CA certificate.

To change the certificate, perform the following steps.

Create a secret that contains the certificate chain and private key in the openshift-config project.

    
     $ oc create secret tls <secret> --cert=</path/to/cert/chain.crt>
--key=</path/to/private.key> -n openshift-config

    
   

Update the API server to reference the created secret.

    
     $ oc patch apiserver cluster --type=merge -p '{"spec":{"servingCerts": {"namedCertificates": [{"names": ["<API_SERVER_FQDN>"], "servingCertificate": {"name": "<secret>"}}]}}}' 
    
   

Verify that the newly created secret is now being referenced and that a new revision of the Kubernetes API server has been rolled out.

Updating the trusted CA bundle

In a locked-down enterprise environment, the cluster does not exist in isolation. It must frequently communicate with external, internally hosted resources such as private image registries, OIDC identity providers, or GitLab instances. Because these services are often secured by a private or custom certificate authority, the cluster would reject these connections as untrusted by default.

The platform addresses this trust gap by utilizing a cluster-wide trusted CA bundle, which is maintained through the Proxy resource. After an enterprise root CA is added to this central store, OpenShift automatically shares that trust with every part of the cluster. Platform components, such as build pods and operators, rely on this mechanism to establish secure, encrypted outbound connections. This also eases the burden on developers as they no longer need to manage certificates at the individual application level. Consequently, the cluster maintains a security posture that stays aligned with broader corporate requirements while simplifying the overall networking landscape.

To replace the CA bundle:

  1. Create a config map that includes the root CA certificate used to sign the wildcard certificate.
  2. Update the cluster-wide proxy configuration with the newly created config map.
    
     $ oc create configmap custom-ca
--from-file=ca-bundle.crt=</path/to/custom-ca.crt>
-n openshift-config
$ oc patch proxy/cluster --type=merge
--patch='{"spec":{"trustedCA":{"name":"custom-ca"}}}

    
   

Internal service CA

To simplify internal security, OpenShift leverages a built-in Service CA Operator. This operator automatically provisions and manages certificates for internal services using a dedicated internal root CA. When a developer creates a service, the operator can automatically inject the necessary certificates into the pod’s volume. This automation ensures that even the most granular internal pod-to-service communications are encrypted and trusted without requiring manual certificate handling by application teams.

Automate continuous compliance and vulnerability audits

Security does not end once a container is running. The platform must also ensure that the underlying infrastructure remains correctly configured and remains resistant to configuration drift over time.

Platform configuration scanning

While container images must be secure, it is equally essential to validate the cluster’s settings. Before any system moves into a production environment, it is often mandatory to have it configured to meet regulatory standards or compliance protocols. National laws, specific industry benchmarks, or internal corporate governance can drive this need.

OpenShift can use the Compliance Operator to perform automated checks against industry benchmarks, including the CIS and NIST standards. You can describe the required compliance state of the cluster, and the Compliance Operator can identify gaps and offer insights to remediate them. The Compliance Operator can be configured to audit cluster nodes and settings regularly, ensuring the cluster remains hardened. This provides a comprehensive picture of the cluster’s compliance posture and immediately highlights any areas that require attention.

    
     $ $ oc get -n openshift-compliance profile.compliance
NAME              AGE
ocp4-cis          8m4s
ocp4-cis-node     8m4s
ocp4-e8           8m4s
[.......]
$ $ oc get -n openshift-compliance profile.compliance ocp4-cis-node -o yaml
apiVersion: compliance.openshift.io/v1alpha1
description: |-
  This profile defines a baseline that aligns to the Center for Internet Security®
  Red Hat OpenShift Container Platform 4 Benchmark™, V0.3, currently unreleased.

  This profile includes Center for Internet Security®
  Red Hat OpenShift Container Platform 4 CIS Benchmarks™ content.
[.............]

    
   

To initiate a scan, a ScanSetting resource must first be established within the environment. The Compliance Operator includes a pre-configured ScanSetting resource named default that is ready for immediate use without requiring further customization.

    
     $ oc get -n openshift-compliance scansettings default -o yaml
    
   

The following manifest shows how to create a “ScanSettingBinding” resource to verify compliance with the rhcos4-moderate profile for nodes and the ocp4-cis profile for the cluster.

    
     apiVersion: compliance.openshift.io/v1alpha1
kind: ScanSettingBinding
metadata:
  name: Demo-Scan
profiles:
 - name: rhcos4-moderate
   kind: Profile
   apiGroup: compliance.openshift.io/v1alpha1
 - name: ocp4-cis
   kind: Profile
   apiGroup: compliance.openshift.io/v1alpha1
settingsRef:
  name: default
  kind: ScanSetting
  apiGroup: compliance.openshift.io/v1alpha1
    
   

Apply the manifest and check the status of the scan as follows:

    
     $ oc apply -n openshift-compliance -f myscan.yaml
$ oc get compliancescans -n openshift-compliance
NAME                     PHASE   RESULT
ocp4-cis                 DONE    NON-COMPLIANT
rhcos4-moderate-master   DONE    NON-COMPLIANT
rhcos4-moderate-worker   DONE    NON-COMPLIANT

    
   

To view the list of failed checks, run the following:

    
     $ oc get ComplianceCheckResult -n openshift-compliance | grep FAIL
ocp4-cis-api-server-encryption-provider-config         FAIL     medium
ocp4-cis-audit-log-forwarding-enabled                  FAIL     medium

    
   

Automated remediation

Beyond just identifying issues, the system provides a path toward rapid recovery. The Compliance Operator can be configured to generate and apply remediation objects that automatically correct configuration failures on the cluster nodes. When a node deviates from the required security standard, the operator can implement the appropriate fixes without requiring manual intervention from a cluster administrator. This automation reduces the risk of human error and significantly lowers the administrative effort needed to maintain infrastructure compliance with enterprise standards.

To auto apply remediations, set the autoApplyRemediations field to true in the ScanSetting definition, which enables automatic remediations for content updates.

    
     apiVersion: compliance.openshift.io/v1alpha1
autoApplyRemediations: true 1
autoUpdateRemediations: true 2
kind: ScanSetting
[.......]

    
   

Protect data at rest with native encryption

Securing a cluster also requires protecting the data itself, whether it is sitting in the system database or stored by an application. This involves a combination of encrypting information at rest and monitoring the files that make up the operating system.

Securing the cluster datastore (etcd)

The etcd datastore is the most critical component of any OpenShift cluster. In addition to storing cluster state, it also contains sensitive objects, such as tokens and configurations. By default, the etcd data is not encrypted, but you can enable etcd encryption for the cluster, providing an additional layer of data security and protecting it from unauthorized access. This ensures that even if the underlying disk is accessed or stolen, the sensitive data remains unreadable. While the platform manages these encryption keys automatically, it is essential to note that etcd encryption secures data at rest on the disk explicitly.

OpenShift Container Platform supports the following encryption types for securing etcd data:

  • AES-CBC: This method utilizes AES-CBC with PKCS#7 padding and a 32-byte key. The system automatically rotates the encryption keys on a weekly basis.
  • AES-GCM: This method employs AES-GCM with a random nonce and a 32-byte key. Similar to AES-CBC, these encryption keys undergo weekly rotation.

It is important to note that etcd resources should not be backed up until the initial encryption process has fully finished. If a backup is attempted before completion, the resulting data may be only partially encrypted, potentially compromising the security and integrity of the backup.

To enable encryption for etcd, set the “spec.encryption.type” field to aesgcm or aescbc.

    
     $ oc edit apiserver
[.....]
spec:
  encryption:
    type: aesgcm
[.....]

    
   

Once the changes have been applied, it can take some time for the data to be encrypted, depending on the size of the etcd database. Monitor the status of Kubernetes API and Oauth API server. Once encryption has been completed, the following commands will show a “EncryptionCompleted” status.

    
     $ oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?
(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}
$ oc get authentication.operator.openshift.io -o=jsonpath='{range
.items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}

    
   

Securing secrets management

A common misconception is that standard Kubernetes Secrets are inherently secure. However, by default, they are only Base64 encoded and not truly encrypted. Essentially, anyone with API access can pull or change these secrets. Furthermore, a user with permission to launch a pod in a specific namespace can easily use that access to view all secrets stored within that same namespace. 

OpenShift supports the Secrets Store CSI Driver to fill these gaps. It allows the cluster to retrieve sensitive credentials directly from external, enterprise-grade vaults (such as HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault) and store them in the pod’s volume. Alternatively, many teams now use the External Secrets Operator, which synchronizes data from external APIs directly into Kubernetes Secrets. By using these tools, organizations ensure that sensitive passwords and API keys never actually live in the cluster’s permanent storage, significantly reducing the “blast radius” if a cluster is ever compromised.

The Secrets Store CSI Driver Operator is verified for compatibility with several major industry vault solutions. The following secrets store providers are supported:

  • AWS Secrets Manager
  • AWS Systems Manager Parameter Store
  • Azure Key Vault
  • Google Secret Manager
  • HashiCorp Vault

The following configuration defines a SecretProviderClass used to integrate an application with an external Azure Key Vault. It specifies the target vault name, the tenant identity, and the exact secret objects to be fetched for the production-apps namespace.

    
     apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: app-vault-config
  namespace: production-apps
spec:
  provider: azure
  parameters:
    usePodIdentity: "false"
    useVMManagedIdentity: "false"
    userAssignedIdentityID: ""
    keyvaultName: "prod-keyvault-01"
    objects: |
      array:
        - |
          objectName: app-encryption-cert
          objectType: secret
    tenantId: "72f988bf-86f1-41af-91ab-2d7cd011db47"
    
   

Persistent volume encryption

While etcd is responsible for storing the cluster state, applications can be configured to store their data in persistent volumes (PVs). OpenShift supports PV encryption using storage classes that are configured for either hardware or software-based encryption. This setup ensures that application data is protected as it sits on the underlying storage devices. Implementing PV encryption is an involved process that requires integrating with an external key management system (KMS) and configuring specific secrets within the storage provider. Persistent storage solutions for OpenShift, such as OpenShift Data Foundation support encrypting data at rest.

Implement node-level file integrity monitoring

In addition to encrypting data at rest, the cluster must also watch for unauthorized changes to its own system files. The File Integrity Operator continuously monitors critical files on the cluster nodes by running privileged Advanced Intrusion Detection Environment (AIDE) containers on each node. It can detect a wide range of file and directory changes, including modifications to permissions, file content (via checksums), modification times, and inode details. If any unexpected or malicious changes are detected, which could indicate a security breach or unauthorized tampering, the operator immediately alerts administrators.

By default, the File Integrity Operator is configured to check the integrity of the following directories: /root, /boot, /usr, and /etc. To include other directories in the configurations, such as /bin, you can create a custom configuration.

First, extract the default configuration from the configmap.

    
     $ oc extract cm/worker-fileintegrity --keys=aide.conf
    
   

Add any directories that need to be monitored.

    
     $ vi aide.conf
@@define DBDIR /hostroot/etc/kubernetes
@@define LOGDIR /hostroot/etc/kubernetes
database=file:@@{DBDIR}/aide.db.gz
[.....]
!/hostroot/root/\.kube
!/hostroot/usr/src/
!/hostroot/usr/tmp/

/hostroot/usr/    CONTENT_EX
# Add /bin
/hostroot/bin/    CONTENT_EX
[.....]

    
   

Create the configmap with the updated AIDE configuration.

    
     $ oc create cm my-custom-conf --from-file=aide.conf
    
   

Create a FileIntegrity manifest that references the newly created configmap.

    
     apiVersion: fileintegrity.openshift.io/v1alpha1
kind: FileIntegrity
metadata:
  name: master-fileintegrity
  namespace: openshift-file-integrity
spec:
  nodeSelector:
    node-role.kubernetes.io/master: ""
  config:
    name: my-custom-conf
    namespace: openshift-file-integrity
    
   

Create the FileIntegrity resource and verify that the changes have been made.

    
     $ oc apply -f fileintegrity.yaml
$ oc describe cm/master-fileintegrity | grep "/bin"
    
   

Enhancing OpenShift security with application-centric backups

A complete security strategy must include a recovery plan. While security best practices, such as RBAC, OS hardening, and encryption protect the cluster, backups serve as the ultimate safeguard against ransomware, data corruption, or accidental deletion. In a cloud-native environment, a simple file backup is not enough; the system must capture the entire application state, including its data, configuration, and metadata.

Trilio for OpenShift

One of the most popular solutions for application-centric backup is Trilio. Unlike traditional backup tools, Trilio captures the entire application, including data, metadata, and all associated OpenShift  objects, to ensure application consistency. It integrates directly into the OpenShift console, allowing users to back up entire namespaces, Helm charts, or Operators with a single click.

Some of the key features offered by Trilio that enhance OpenShift Security include:

  • Immutable backups: Trilio can store backups in an immutable format, meaning that once they are written, they cannot be altered or deleted by a malicious actor or ransomware.
  • Continuous restore: This feature enables the near-instantaneous replication of data to a secondary cluster, ensuring that business operations can continue even if the primary site is wholly unavailable.
  • Native RBAC Integration: Since it is built for OpenShift, Trilio adheres to the same security rules as the cluster. Only authorized users can trigger a restore, preventing unauthorized people from accessing sensitive historical data.

Learn How To Best Backup & Restore Virtual Machines Running on OpenShift

Conclusion

OpenShift security shifts from traditional perimeter-based hardware protection to a cloud-native model where defenses are built into the orchestration layer. In legacy systems, security relies on manual server hardening and static firewalls that exist outside the application. OpenShift employs a distinct approach by offering automated, policy-driven isolation that protects workloads at the container level.

Trilio completes this architecture by ensuring that your security posture remains intact even after a restore. Instead of just backing up data, it captures the entire application metadata and security logic. As a result, your organization can maintain continuous compliance and fast recovery times, turning OpenShift’s native security into a truly resilient, production-ready environment.

Book a demo to see how Trilio can help.

Table Of Contents

Like This Article?

Subscribe to our LinkedIn Newsletter to receive more educational content