Skip to main content

CloudNativePG 1.30's DatabaseRole CRD and Lease Election: What Changes for a Self-Hosted PaaS's Postgres Layer

8 min readDora NodaDora Noda
Share
On this page

CloudNativePG's 1.28.x line went end-of-life on June 30, 2026. If a fleet is still running it, that's not a "should probably upgrade soon" — it's already unpatched and unsupported, with two CVE fixes sitting in every release since. CloudNativePG 1.30.0, released the same month, doesn't just carry those fixes forward. It ships two new primitives — a DatabaseRole CRD and a Kubernetes Lease-based primary election — that change what a self-hosted PaaS running CNPG as its own managed-Postgres engine can build on top of the operator, not just what it has to patch.

That distinction matters here specifically. bex doesn't just recommend CloudNativePG to self-hosters — bex's own Render-compatible managed-Postgres product is a Database custom resource that projects to a CNPG Cluster in the tenant's namespace, the same mechanism this post is about. So "what changes in 1.30" isn't abstract operator trivia; it's a direct question about bex's own Database controller. Here's what actually shipped, what it changes for that controller today, and what a fleet still on 1.28.x needs to check before bumping.

What actually shipped in CloudNativePG 1.30

Four changes matter for anyone running CNPG as a managed-database backend, not just as a single-cluster HA tool.

DatabaseRole CRD. Until 1.30, CNPG's Cluster spec could declare roles inline, but they lived and died with the cluster's own reconciliation loop — there was no independent resource for a role's lifecycle. DatabaseRole gives roles their own CRD and their own reconciler, mirroring the existing Database CRD pattern. Two fields do the real work: databaseRoleReclaimPolicy (retain or delete) controls whether deleting the Kubernetes resource drops the underlying Postgres role, and an optional clientCertificate block has the operator auto-generate and renew a TLS client certificate off the cluster's client CA, stored in a <databaserole-name>-client-cert Secret — enabling password-free cert authentication instead of a password Secret.

Lease-based primary election. CNPG now creates a Kubernetes Lease object named after the cluster that acts as a mutex on primary promotion: the instance manager must hold the lease before it's allowed to act as primary, and it releases the lease cleanly on shutdown so a replica can promote without waiting out the full lease TTL. Timing is configurable through a new .spec.primaryLease stanza. CNPG's own docs are explicit that this is a promotion gate, not a fence — primary isolation (STONITH-style fencing) is still what prevents an unreachable-but-still-running old primary from serving writes. The Lease closes a narrower, specific gap: the window during a coordinated transition where two instances could both believe they're allowed to promote.

In-place major-version upgrades for Image Volume extension clusters. Clusters using CNPG's Image Volume extensions feature (extensions packaged as OCI images, mounted read-only via the Kubernetes ImageVolume feature and PostgreSQL 18's extension_control_path) can now run pg_upgrade in place to PostgreSQL 19+, with the source- and target-version extension images mounted side by side during the upgrade job — so a failed upgrade reverts cleanly instead of leaving a cluster with half-upgraded extension libraries.

Two CVE fixes, both about what a role-management layer can leak. CVE-2026-55769 is a privilege-escalation path (CWE-426, untrusted search path): a database owner could plant overloaded operators in the public schema and have them silently invoked by operator-issued queries. 1.30 pins search_path = pg_catalog, public, pg_temp on the operator's own pooled connections, closing that. CVE-2026-55765 is a credential-exposure bug: the operator now SCRAM-SHA-256 encodes a cleartext password before issuing CREATE ROLE/ALTER ROLE, so the SCRAM verifier — not the cleartext secret — is what could ever end up in query logs or extension capture output. Both are fixed as far back as the 1.28.x and 1.29.x backport branches, but only fully supported releases keep getting the backport; 1.28.x's last patch, 1.28.4, is the final one it will ever get.

What DatabaseRole changes for bex's own Database controller

Here's the part that's specific to running CNPG as a product backend rather than a single cluster: bex's Database CRD provisions a per-tenant CNPG Cluster, and CNPG creates a <name>_user owner role for that cluster during bootstrap — imperatively, as part of the cluster's own reconciliation, the same way most CNPG deployments handle roles today. There's no independent role resource in that path; the role's lifecycle is implicitly tied to the cluster's.

DatabaseRole is a genuinely new option there, not something bex was already doing under a different name. Two concrete places it would slot in:

  • Reclaim policy matches a decision bex's own ADR already flags as open. bex's managed-Postgres design doc lists "optionally a final backup first" as a deferred nice-to-have on Database deletion — right now, deleting a Database drops the Cluster, Service, Secret, and role together, no separate step. A DatabaseRole with databaseRoleReclaimPolicy: retain gives that a mechanism: the role (and its credentials) can outlive the Cluster teardown instead of being deleted atomically with it, which is what a "delete the compute, keep the credential trail for one more billing cycle" flow would need without hand-rolling a pre-delete backup step.
  • clientCertificate is a path toward the external connection bex hasn't built yet. bex's external Postgres endpoint (the <id>.db.bex.co SNI route) currently targets sslmode=require with a password — cert-based auth for external tenant connections isn't part of the shipped MVP. DatabaseRole's auto-renewed client cert is the operator-native version of that, without bex's control plane having to run its own cert issuance and rotation logic on top of CNPG.

Neither of these is live in bex today — this is what the primitive makes available, not a retrofit bex has already shipped. It's also where the CVE fixes land directly on that same controller: CVE-2026-55765 means any CNPG version bex runs older than the patched 1.28.x/1.29.x/1.30.x lines was writing tenant role passwords to CREATE ROLE/ALTER ROLE statements in the clear, visible to anything capturing operator query logs — worth an explicit log audit on upgrade, not just a version bump. CVE-2026-55769's search_path fix matters the same way: any tenant with schema-creation rights on their own database could otherwise plant an operator that operator-issued maintenance queries would silently execute.

What the Lease buys — and doesn't buy yet

The honest scope of the Lease matters as much as what it does. It shortens and hardens the coordinated promotion path — clean shutdown releases the lease immediately, so a replica doesn't sit waiting on a TTL it doesn't need to wait on, and two instances can't both hold "I'm allowed to be primary" at once during that handoff. It does not replace fencing for the uncoordinated case: a primary that's unreachable but still running still needs isolation to stop serving writes, and CNPG's docs are direct that the Lease is a promotion gate, not a fence.

Where this actually lands for bex: the Pro tier — instances: 3 with real failover — is explicitly deferred to post-MVP in bex's own managed-Postgres ADR. Every shipped bex tier today (free, basic-256mb, basic-1gb) is instances: 1, so there's no promotion race to gate yet. That's not a reason to shrug off the Lease — it's the opposite: it's a safety primitive that will already be sitting under bex's HA tier by the time that tier ships, instead of being a gap the team would otherwise have to design around later. Building Pro on a CNPG version that already has lease-gated promotion is strictly better than building it on one that doesn't and back-porting the operator upgrade under pressure once HA customers exist.

The EOL clock and the upgrade checklist

CloudNativePG 1.28.x's EOL was June 30, 2026 — ten days before this post. 1.28.4 was its final release. 1.29.x has runway to September 29, 2026; 1.30.x is the only line that will keep receiving new features. For a fleet still on 1.28.x, "upgrade eventually" isn't the framing anymore — it's unpatched against two real CVEs on an unsupported branch. The concrete checklist before bumping:

  • Kubernetes version. 1.30's Image Volume extensions path assumes Kubernetes 1.35+ (where ImageVolume is enabled by default); confirm the cluster's Kubernetes version before assuming that feature is usable, even if the operator upgrade itself succeeds on older Kubernetes.
  • Image catalog compatibility. 1.30.0's default PostgreSQL image moved to 18.4 — check any custom ImageCatalog pins against that baseline rather than assuming the default carries forward unchanged.
  • Query-log audit for the CVE-2026-55765 window. If logs or metrics capture were ever pointed at operator connections on a pre-fix version, treat any captured CREATE ROLE/ALTER ROLE statements from that window as having held cleartext passwords, and rotate those specific credentials — the fix stops new exposure, it doesn't retroactively scrub old logs.
  • Role-provisioning scripts. Anything doing imperative role creation outside CNPG's own bootstrap (init containers, migration jobs) should get re-evaluated against DatabaseRole now that it exists as a first-class alternative, rather than carried forward by default.

None of this is exotic operator work, which is the actual point: a minor-version bump on the database operator underneath a PaaS's managed-database product is exactly the kind of dependency upgrade that's easy to defer because nothing's visibly broken — right up until the EOL date passes and the next CVE lands on an unsupported branch instead of a supported one.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, with Render-compatible managed Postgres built on CloudNativePG. Star the repo on GitHub or deploy your first database today.

Sources

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex