feat(openbao): add OpenBao role as external KMS for Percona pg_tde - #776
Open
alemacci wants to merge 9 commits into
Open
feat(openbao): add OpenBao role as external KMS for Percona pg_tde#776alemacci wants to merge 9 commits into
alemacci wants to merge 9 commits into
Conversation
alemacci
force-pushed
the
feat/openbao-pgtde
branch
11 times, most recently
from
August 19, 2026 15:03
bab1a6b to
9757124
Compare
alemacci
force-pushed
the
feat/openbao-pgtde
branch
from
August 19, 2026 15:08
9757124 to
c0eb2bd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a new
openbaomodule/role to Pigsty, adding OpenBao (Apache-2.0 licensed, open-source fork of HashiCorp Vault) as an external Key Management Service (KMS) that backs PostgreSQL Transparent Data Encryption via Percona'spg_tdeextension.With
pg_tde, PostgreSQL encrypts heap data and WAL at rest, but the master/principal key must never live on the database host.This role deploys and manages an OpenBao cluster so that PostgreSQL fetches its principal key over TLS at startup and on key rotation, keeping encrypted data (on PGSQL nodes) and key material (in the KMS) properly separated, which is what most at-rest encryption compliance regimes actually require.
What's included
roles/openbao- deploy an OpenBao cluster:pg_tdeKV v2 mount, policy, and long-lived token, persisted to the admin node/v1/sys/metricsas a VictoriaMetrics scrape targetroles/openbao_remove- clean removal of an OpenBao clusteropenbao.yml/openbao-rm.yml- top-level playbooksroles/pgsql/tasks/tde.yml- installs the pg_tde key-provider token issued by OpenBao on the PGSQL node before Patroni startsroles/pgsql/tasks/patroni.yml- a new task sets pg_tde GUCs after running prerequisites, then restarts Patroniconf/pgtde.yml- ready-to-use single-node config template wiring a Percona PostgreSQL cluster (withpg_tdepreloaded) to a single OpenBao instanceconf/ha/pgtde.yml- 3-node HA variant: 3-node etcd, 3-node OpenBao cluster, and HAProxy in front of OpenBao, for production-like setups where the KMS itself must not be a SPOFroles/ca/tasks/main.yml- adds a dedicated directory to hold OpenBao's TLS material, isolated from other CA consumersroles/node_id- registers theopenbaopackage across all supported distro/arch package lists (currently only EL-distros are tested)deploy.yml- wires theopenbaorole into the main deploy playbookfiles/grafana/infra/openbao-overview.json), updates to the sharedfiles/grafana/pigsty.jsonoverview dashboard, and VictoriaMetrics alerting rules for OpenBao cluster monitoring (files/victoria/rules/openbao.yml)Why
Percona's PostgreSQL distribution ships
pg_tdefor at-rest encryption, but it requires an external key management backend to hold the principal key. Pigsty currently has no first-class way to stand up and manage such a KMS. OpenBao is a natural fit: it's open source, Apache-2.0 licensed (no HashiCorp BSL concerns), API-compatible with Vault, prometheus-style metrics and fits Pigsty's existing patterns for CA/cert issuance, systemd-managed services, and Ansible-driven provisioning.Beyond tooling fit, this addresses a gap that TDE alone does not close.
Storing the principal key on the same host as the data it encrypts means a single host compromise defeats the encryption entirely, the key and the ciphertext fail together.
An external, dedicated KMS is what turns "encryption" into an actual security control:
though the data itself is intact. The 3-node cluster with quorum-based consensus removes this failure mode.
cluster rebuilds reuse the existing seal key unless an operator explicitly removes it. Rotation and rebuild are deliberate actions, not incidental side effects of routine maintenance.
This lines up with how at-rest encryption is actually evaluated under common compliance frameworks: GDPR Art. 32 names encryption as an example technical measure assessed against risk and state of the art, and sector-specific cloud/infrastructure security baselines typically scale encryption and key-management requirements with data sensitivity: external key management with enforced separation of duties is what distinguishes a defensible control from encryption-as-checkbox.
Implementation notes
A few non-obvious sequencing/compatibility decisions worth flagging for review:
GUCs must stay off during bootstrap, then get enabled on-the-fly.
default_table_access_method,pg_tde.enforce_encryption, andpg_tde.wal_encryptcannot be turned on before thepg_tdeextension exists and the key provider chain has run (pg_tde_add_global_key_provider_vault_v2→pg_tde_create_key_using_global_key_provider→pg_tde_set_default_key_using_global_key_provider).Enabling them earlier blocks cluster bootstrap outright. The new
apply pgtde GUCs and restarttask inroles/pgsql/tasks/patroni.ymlsets these GUCs after the prerequisites have run, not before.This ordering is intentional, not an oversight.
pg-initintentionally does notCREATE EXTENSION pg_tdeontemplate1.Instead,
pg_tdeis expected to be declared through each database's ownextensions:list, and it must be first in that list and mandatory whereverpg_tdeis in use. If it's missing or ordered after other extensions,default_table_access_method = tde_heapcombined withpg_tde.enforce_encryption = onblocks anyCREATE TABLE, including ones issued during database provisioning itself, not just by the hosted application later.pgBackRest parameters were adjusted for pg_tde compatibility
as Percona's documentation:
Without these, backups are not reliably compatible with the Percona pg_tde kernel.
Tags / usage
The role is fully tag-driven (
openbao_install,openbao_config,openbao_cert,openbao_seal,openbao_launch,openbao_init,openbao_provision,openbao_register, ...), consistent with the tag hierarchy used by other Pigsty roles (pgsql,etcd,minio, etc.).Quickstart (single-node):
curl https://repo.pigsty.io/get | bash ./configure -c pgtde ./deploy.ymlQuickstart (3-node HA, OpenBao and etcd both clustered):
curl https://repo.pigsty.io/get | bash ./configure -c ha/pgtde ./deploy.ymlTesting
pg_tdeusing theconf/pgtde.ymltemplate and confirmed encrypted tables/WALopenbao-rm.ymlcleanly removes the clusterRelated
pg_tde: https://docs.percona.com/pg-tde/