Cloud Computing and Data Centers

How to Run OpenBao on Kubernetes Using CloudNativePG as a PostgreSQL Backend

The EnterpriseDB and ControlPlane teams present a practical recipe for running OpenBao on Kubernetes with a PostgreSQL cluster managed by CloudNativePG, using synchronous replication and TLS certificates instead of passwords. The recipe also explains the design's limitations, particularly the need to restart OpenBao after certificate renewal and the backup and recovery requirements if the cluster is lost.

2026-09-16
6 min read
7 views
فريق تحرير certi.news
How to Run OpenBao on Kubernetes Using CloudNativePG as a PostgreSQL Backend

The CNCF blog presents an operational recipe for building an open-source secrets-management stack on Kubernetes that combines OpenBao and CloudNativePG. OpenBao is the open-source fork of HashiCorp Vault under the Linux Foundation, while CloudNativePG turns a PostgreSQL cluster into a self-healing service with synchronous replication and certificate-based authentication. The recipe benefits from Kubernetes, a CNCF graduated project, and CloudNativePG, a Sandbox project undergoing evaluation by the CNCF Technical Oversight Committee for progression to the Incubation stage.

The core idea is not merely to use PostgreSQL as a conventional store, but to make OpenBao depend on a highly available PostgreSQL backend without relying on a cloud database owned by a specific provider. The recipe uses three CloudNativePG instances with quorum-based synchronous replication, so the availability of one synchronous standby is sufficient to ensure data durability. Conversely, write operations may stop if no standby meeting the required durability condition is available.

What changes in the design?

OpenBao uses its native PostgreSQL storage with the high-availability lock table enabled through the option ha_enabled = true. The configuration creates two tables: openbao_kv_store for storing data, and openbao_ha_locks for storing high-availability lock records. The recipe disables the default local storage in the OpenBao chart because all state is expected to remain in CloudNativePG.

CloudNativePG runs a three-instance PostgreSQL cluster, directing them to dedicated nodes and achieving distribution across separate failure domains through node selectors, tolerations, and pod-affinity constraints. The recipe uses an image catalog that specifies a minimal PostgreSQL 18 version instead of manually writing a fixed image tag, and it also shows a test setup that used an image secured with a SHA digest.

Passwordless authentication

One of the recipe's most important aspects is removing passwords from OpenBao's database connection. CloudNativePG creates DatabaseRole objects for a schema-owning role and a restricted operating role named openbao-rw, and both receive a TLS client certificate. The pg_hba rules require a TLS connection and client certificate for these roles, while rejecting unencrypted connections.

This detail matters because creating the certificate alone does not automatically require its use; PostgreSQL rules determine, for each connection, whether authentication will occur using a certificate, a password, or be rejected. The recipe also sets the permissions of secret files mounted in the containers to 0640, because libpq rejects private keys that are readable by the group or by all users when mounted with the default value of 0644.

Because DatabaseRole does not currently manage table-level grants according to the article, a one-time Job runs commands to create the tables and grant SELECT, INSERT, UPDATE, and DELETE privileges to the restricted role. The Job also revokes CONNECT from PUBLIC and usage of the public schema from PUBLIC, then grants the minimum required privileges to openbao-rw. The skip_create_table option is enabled in the OpenBao configuration so that the operating role does not attempt to create the tables itself.

What does this mean in practice for Kubernetes operators?

The recipe provides a local testing path using the cnpg-playground repository, which creates a six-node Kind cluster and includes CloudNativePG configurations in advance. The experiment requires Docker, Kind, Helm, and kubectl. However, the node distribution in the test environment imposes an important constraint: PostgreSQL nodes are dedicated and labeled, leaving only two general-purpose nodes for scheduling three OpenBao replicas with mandatory affinity. Therefore, the recipe temporarily allows OpenBao to use a control-plane node in the Kind environment, with an explicit warning against carrying this toleration into production. In a production cluster with three unlabeled worker nodes, this workaround is not necessary.

After installing the OpenBao chart, the cluster must be initialized and each instance unsealed separately using three of the five required Shamir keys. Unsealing the first instance does not unseal the other two, and the default OrderedReady StatefulSet policy delays creation of the next instance until the previous one is ready. Therefore, unseal keys and the root token should be stored securely, and the keys should then be entered for each instance in order.

After initialization, OpenBao stores its bootstrap state and keys inside the openbao_kv_store table, and the test secret value is stored as encrypted BYTEA data rather than clear text, even when accessing the PostgreSQL table directly. The article confirms a successful secret write and read test using KV v2 and the restricted PostgreSQL role.

Operational limitations and what the recipe does not cover

Certificates are renewed automatically by CloudNativePG: the CNPG client certificate has a validity period of 90 days and is usually renewed about one week before expiration. However, OpenBao does not automatically reread certificate files; the PostgreSQL storage interface opens the connection pool when the process starts. Therefore, a rolling restart of OpenBao instances must be planned after renewal, preferably within the 83-day renewal window before the old certificate expires.

High availability within a Kubernetes cluster is also not equivalent to a complete disaster-recovery plan. The recipe does not automatically create backups or recover from the loss of the entire cluster. For production use, the article recommends adding the Barman Cloud Plugin with an object store such as Amazon S3, Google Cloud Storage, or Azure Blob Storage, and using Backup and ScheduledBackup resources to archive WAL and base backups and enable point-in-time recovery. RTO and RPO objectives requiring survival of a complete cluster loss need an asynchronous PostgreSQL cluster in a second cluster or region.

News source
ف
Author

فريق تحرير certi.news

In the same category

You may also like

View all news