Security#

Security for EDB CloudNativePG Global Cluster is analyzed at three layers: code, container, and cluster.

Warning

In addition to security practices described here, you must perform regular InfoSec duties on your Kubernetes cluster. Familiarize yourself with Overview of Cloud Native Security

in the Kubernetes documentation.

blog article for a better understanding and context of the approach EDB takes with security in EDB CloudNativePG Global Cluster.

Code#

Source code of EDB CloudNativePG Global Cluster is systematically scanned for static analysis purposes, including security problems. EDB uses a popular open-source linter for Go called GolangCI-Lint directly in the CI/CD pipeline. GolangCI-Lint can run several linters on the same source code.

One of these is Golang Security Checker , or gosec . gosec is a linter that scans the abstract syntactic tree of the source against a set of rules aimed at discovering well-known vulnerabilities, threats, and weaknesses hidden in the code. These threads include hard-coded credentials, integer overflows, SQL injections, and others.

Important

A failure in the static code analysis phase of the CI/CD pipeline is a blocker for the entire delivery of EDB CloudNativePG Global Cluster, meaning that each commit is validated against all the linters defined by GolangCI-Lint.

Container#

Every container image that’s part of EDB CloudNativePG Global Cluster is built by way of CI/CD pipelines following every commit. Such images include not only those of the operator but also of the operands, specifically every supported PostgreSQL version. In the pipelines, images are scanned with:

  • Dockle for best practices in terms of the container build process

  • Clair for vulnerabilities found in both the underlying operating system and libraries and applications that they run

Important

All operand images are rebuilt once a day by our pipelines in case of security updates at the base image and package level, providing patch level updates for the container images that EDB distributes.

The following guidelines and frameworks were taken into account for container-level security:

blog article for more information about the approach that EDB takes on security at the container level in EDB CloudNativePG Global Cluster.

Cluster#

Security at the cluster level takes into account all Kubernetes components that form both the control plane and the nodes as well as the applications that run in the cluster, including PostgreSQL.

Role-based access control (RBAC)#

The operator interacts with the Kubernetes API server with a dedicated service account called pgd-operator-controller-manager. In Kubernetes this account is installed by default in the pgd-operator-system namespace. A cluster role binds between this service account and the pgd-operator-controller-manager cluster role that defines the set of rules, resources, and verbs granted to the operator.

RedHat OpenShift directly manages the operator RBAC entities by way of OperatorLifecycleManager (OLM) . OLM allows you to grant permissions only where they’re required, implementing the principle of least privilege.

Important

These permissions are exclusively reserved for the operator's service account to interact with the Kubernetes API server. They aren't directly accessible by the users of the operator that interact only with PGDGroup and PGDGroupCleanup resources.

The following are some examples and, most importantly, the reasons why EDB CloudNativePG Global Cluster requires full or partial management of standard Kubernetes namespaced resources.

jobs : The operator needs to handle jobs to manage different PGDGroup phases.

poddisruptionbudgets : The operator uses pod disruption budgets to make sure enough PGD nodes are kept active during maintenance operations.

pods : The operator needs to manage PGD nodes as a Cluster resource.

secrets : Unless you provide certificates and passwords to your data nodes, the operator adopts the “convention over configuration” paradigm by self-provisioning random-generated passwords and TLS certificates and by storing them in secrets.

serviceaccounts : The operator needs to create a service account to enable the PGDGroup recovery job to retrieve the backup objects from the object store where they reside.

services : The operator needs to control network access to the PGD cluster from applications and properly manage failover/switchover operations in an automated way.

statefulsets : The operator needs to manage PGD proxies.

validatingwebhookconfigurations and mutatingwebhookconfigurations : The operator injects its self-signed webhook CA into both webhook configurations, which are needed to validate and mutate all the resources it manages. For more details, see the Kubernetes documentation .

To see all the permissions required by the operator, you can run kubectl describe clusterrole pgd-operator-manager-role .

EDB CloudNativePG Global Cluster internally manages the PGD nodes using the Cluster resource as defined by EDB Postgres for Kubernetes. See the :ref:` EDB CloudNativePG Cluster documentation <Security>`

for the list of permissions used by the EDB CloudNativePG Cluster operator service account.

Calls to the API server made by the instance manager#

The instance manager, which is the entry point of the operand container, needs to make some calls to the Kubernetes API server to ensure that the status of some resources is correctly updated and to access the config maps and secrets that are associated with that Postgres cluster. Such calls are performed through a dedicated ServiceAccount created by the operator that shares the same PostgreSQL Cluster resource name.

Important

The operand can access only a specific and limited subset of resources through the API server. A service account is the recommended way to access the API server from within a pod. See the Kubernetes documentation for details.

See the :ref:` EDB CloudNativePG Cluster documentation <Security>`

for more information on the instance manager.

Pod security policies#

A pod security policy

is the Kubernetes way to define security rules and specifications that a pod needs to meet to run in a cluster. For InfoSec reasons, every Kubernetes platform must implement them.

EDB CloudNativePG Global Cluster doesn’t require privileged mode for containers execution. The PostgreSQL containers run as the postgres system user. No component requires running as root.

Likewise, volumes access doesn’t require privileged mode or root privileges. Proper permissions must be assigned by the Kubernetes platform or administrators. The PostgreSQL containers run with a read-only root filesystem, that is, no writable layer.

The operator explicitly sets the required security contexts.

On Red Hat OpenShift, Cloud Native PostgreSQL runs in the restricted security context constraint, the most restrictive one. The goal is to limit the execution of a pod to a namespace allocated UID and SELinux context.

See also

For more information on security context constraints (SCC) in OpenShift, see the Managing SCC in OpenShift

article.

Exposed ports#

EDB CloudNativePG Global Cluster exposes ports at operator, instance manager, and operand levels, as shown in the table.

System

Port number

Exposing

Name

Certificates

Authentication

operator

9443

webhook server

webhook-server

TLS

Yes

operator

8080

metrics

metrics

no TLS

No

instance manager

9187

metrics

metrics

no TLS

No

instance manager

8000

status

status

no TLS

No

operand

5432

PostgreSQL instance

postgresql

optional TLS

Yes

PGD#

The current implementation of EDB CloudNativePG Global Cluster creates passwords for the postgres superuser and the database owner.

As far as encryption of passwords is concerned, EDB CloudNativePG Global Cluster follows the default behavior of PostgreSQL: starting with PostgreSQL 14, password_encryption is by default set to scram-sha-256 . On earlier versions, it’s set to md5 .

Important

See Connection DSNs and SSL

in the PGD documentation for details.

EDB CloudNativePG Global Cluster uses the postgres role to maintain PGD nodes. Due to this, it is not allowed to disable postgres user access by setting enableSuperuserAccess to false in the cnp section of the spec.

Storage#

EDB CloudNativePG Global Cluster delegates encryption at rest to the underlying storage class. For data protection in production environments, we highly recommend that you choose a storage class that supports encryption at rest.