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.
See also
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:
The Container Image Creation and Deployment Guide , developed by the Defense Information Systems Agency (DISA) of the United States Department of Defense (DoD)
The CIS Benchmark for Docker , developed by the Center for Internet Security (CIS)
See also
See the Security and Containers in EDB CloudNativePG Global Cluster
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#
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
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.