OpenShift Security Context Constraints (SCCs)#
OpenShift's Security Context Constraints (SCCs) govern which security attributes pods may request. The restricted and restricted-v2 SCCs — the defaults for most namespaces — prohibit pods from specifying runAsUser, runAsGroup, or fsGroup, instead assigning dynamic UID/GID values from a per-namespace range at admission time.
This creates a direct conflict with CloudNativePG components that hard-code numeric UID/GID values in their pod security contexts.
CloudNativePG Operator: OpenShift Detection#
The operator auto-detects OpenShift by querying the Kubernetes discovery API for the security.openshift.io/v1 API group (DetectSecurityContextConstraints() in pkg/utils/discovery.go). When SCCs are present, GetPodSecurityContext() returns nil for all PostgreSQL instance pods, delegating full control to the SCC.
The same HaveSecurityContextConstraints() guard applies to PGBouncer deployments and certain plugin commands.
Limitation: This detection is API-resource-based and fails in vcluster environments. A vcluster inside an OpenShift cluster presents as vanilla Kubernetes and does not expose security.openshift.io/v1, so the operator incorrectly assigns UID/GID 26, causing SCC admission rejection .
Fix: -1 Sentinel for UID/GID (PR #11243)#
PR #11243 adds an explicit opt-in for SCC-compatible behavior :
- Set
spec.postgresUID: -1→runAsUseris omitted from the pod security context - Set
spec.postgresGID: -1→ bothrunAsGroupandfsGroupare omitted
This allows OpenShift (or any platform using dynamic UID assignment) to inject its own values, regardless of whether the API-based detection succeeds. It also fixes cloudnative-pg#11245 for vcluster deployments.
Default values (RunAsUser: 26, RunAsGroup: 26, FSGroup: 26) are documented in the Pod Security Context knowledge base article.
plugin-barman-cloud: Manifest Incompatibilities#
The Barman Cloud plugin manifests ship with two OpenShift-incompatible assumptions:
1. Hard-coded UID/GID#
kubernetes/deployment.yaml and the generated manifest.yaml both specify :
securityContext:
runAsGroup: 10001
runAsUser: 10001
OpenShift's restricted SCC rejects pods that declare an explicit runAsUser outside the namespace's allowed UID range. No OpenShift SCC override files exist in the repository.
2. Hard-coded cnpg-system Namespace#
kubernetes/kustomization.yaml pins the namespace to cnpg-system , and this is baked into manifest.yaml in a dozen locations . RBAC bindings also reference cnpg-system explicitly . This blocks deployments where the operator runs in a different namespace, a common pattern in OpenShift.
Status#
As of mid-2026, the E2E test plan for plugin-barman-cloud explicitly excludes OpenShift because of these issues :
"OpenShift is excluded given that the manifest installation of plugin-barman-cloud is not compatible with OpenShift by default (fixed securityContext
runAsGroup/runAsUser1001, fixedcnpg-systemnamespace), and an OLM installation for plugin-barman-cloud is not yet available."
An OLM-based distribution (tracked in plugin-barman-cloud issue #554) is the intended long-term path for proper OpenShift support.
Workarounds & Mitigations#
| Scenario | Mitigation |
|---|---|
| vcluster on OpenShift (operator) | Set spec.postgresUID: -1 and spec.postgresGID: -1 (requires PR #11243) |
| vcluster — temporary hack | Create a fake SecurityContextConstraints CRD inside the vcluster to trigger OpenShift auto-detection |
| plugin-barman-cloud on OpenShift | Patch manifests to remove runAsUser/runAsGroup and change the target namespace; no upstream-supported path yet |
Key Source References#
| File | What it Contains |
|---|---|
pkg/utils/discovery.go | OpenShift detection via SCC API lookup |
pkg/specs/pods.go | GetPodSecurityContext() — nil-on-SCC logic and UID/GID backfill |
api/v1/cluster_types.go | spec.postgresUID / spec.postgresGID fields |
kubernetes/deployment.yaml | plugin-barman-cloud deployment with hard-coded UID/GID |
manifest.yaml | Generated plugin-barman-cloud manifest with hard-coded namespace + UID/GID |