#Security#PostgreSQL#Kubernetes#Database

CloudNativePG CVE-2026-55765: Auditing Managed Role Passwords on Kubernetes PostgreSQL

webhani·

CVE-2026-55765 affects CloudNativePG, the Kubernetes operator many teams use to run PostgreSQL. It was published on August 20, 2026 with a High severity score of 8.5. According to the advisory data, versions before 1.28.4 and 1.29.2 wrote cleartext role passwords into role-creation statements. A tenant with certain monitoring privileges could potentially recover those passwords and, from there, run operating system commands inside the database pod. The fixes shipped in 1.28.4, 1.29.2, and 1.30.0.

It has been a few weeks, which is exactly why it deserves a second look. Operator upgrades are easy to defer, and a Postgres cluster that "has been running fine" is the kind that does not get touched.

Why this class of bug matters

Nothing here is specific to CloudNativePG. The pattern is general: a credential passes through a place where it can be read by someone who was never meant to see it. Here that place is a SQL statement, and statements can end up in logs, in statistics views, or in monitoring output.

Cleartext passwords in SQL are a long-known hazard. PostgreSQL lets you supply a pre-computed SCRAM-SHA-256 verifier instead of a password in CREATE ROLE ... PASSWORD. The server stores the verifier, and the plaintext never has to appear. According to the advisory, clusters whose managed-role Secrets contained SCRAM-SHA-256 verifiers were not affected, which fits this reasoning.

Step 1: Find out what you run

Check the operator version and the cluster inventory first.

# Operator image tag
kubectl get deployment -n cnpg-system cnpg-controller-manager \
  -o jsonpath='{.spec.template.spec.containers[0].image}'
 
# Clusters that declare managed roles
kubectl get clusters.postgresql.cnpg.io -A \
  -o jsonpath='{range .items[?(@.spec.managed.roles)]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'

Namespace and deployment names depend on how you installed the operator, so adjust them. If you are below the fixed versions in your release line, schedule the upgrade. Read the project's release notes for your target version first, since operator upgrades can trigger rolling restarts of instances.

Step 2: Decide whether credentials need rotation

Upgrading stops new exposure. It does not undo past exposure. Ask these questions:

  • Did untrusted users or tenants hold a monitoring role on the cluster?
  • Are database logs or statement statistics shipped to a system that more people can read than should have database access?
  • Do managed roles use passwords that are shared with other systems?

If the answer to any is yes, rotate the affected role passwords after upgrading. Treat the old values as known.

Step 3: Move to verifier-based secrets

For managed roles, you can store a SCRAM-SHA-256 verifier in the role's Secret rather than a plaintext password. Generating one is straightforward with PostgreSQL's own tooling, for example by setting a password on a throwaway instance with password_encryption = 'scram-sha-256' and reading the stored value from pg_authid, or with a small script using a standard SCRAM implementation.

Applications still need the real password to connect, so the verifier is only for the operator's role-creation path. Keep the application-facing credential in a separate Secret, ideally synced from your secret manager. Check the operator documentation for the exact Secret layout and key names your version expects, because they differ across versions.

Step 4: Reduce who can see what

A fix for one leak path does not remove the next one. Tighten the surrounding controls:

  • Grant monitoring roles only the privileges they need. Avoid giving tenants broad built-in monitoring roles unless required.
  • Review logging settings such as log_statement and log_min_duration_statement, so that statements containing credentials are not retained longer than necessary.
  • Use Kubernetes RBAC to limit who can read Secrets and exec into database pods.
  • Apply NetworkPolicies so that only expected clients reach the database service.

Step 5: Make operator upgrades routine

The underlying problem for many teams is not this CVE but the process. A stateful operator tends to get upgraded only when something breaks.

  • Subscribe to the project's security advisories, for example through GitHub's repository watch settings for security alerts.
  • Track operator versions alongside application dependencies in your inventory.
  • Rehearse upgrades in a staging cluster with realistic data, so that a production upgrade is a known quantity.
  • Keep supported-version windows in mind. Older release lines stop receiving fixes, and the advisory fixed only specific lines.

What we recommend

  1. Confirm your CloudNativePG version today and upgrade to a fixed release.
  2. Rotate managed-role passwords where untrusted monitoring access or broad log access existed.
  3. Prefer SCRAM-SHA-256 verifiers for managed-role Secrets where your operator version supports them.
  4. Review monitoring privileges, log retention, and Secret access as a single exercise.
  5. Add the operator to your regular patching schedule.

For authoritative details on affected versions and mitigations, consult the project's security advisory itself. This post is a practical checklist, not a replacement for it.