Skip to content

Comments

ROX-33303: Env-based TLS profile configuration for PostgreSQL services#19160

Open
vladbologa wants to merge 1 commit intomasterfrom
vb/pg-tls-settings
Open

ROX-33303: Env-based TLS profile configuration for PostgreSQL services#19160
vladbologa wants to merge 1 commit intomasterfrom
vb/pg-tls-settings

Conversation

@vladbologa
Copy link
Contributor

@vladbologa vladbologa commented Feb 24, 2026

Description

Follow-up of #19110 for PostgreSQL services.

ROX-32095 requires StackRox components to adhere to the cluster-wide TLS profile configured by the OpenShift API server. The Operator will read this profile and propagate it to all components via environment variables. This PR adds the receiving end for PostgreSQL deployments (central-db and scanner-v4-db).

I used the docker-entrypoint.sh scripts in order to pass these values directly to PostgreSQL, overriding any setting that might be present in postgresql.conf (even if this file was overridden by the user).

Why env vars + -c flags instead of postgresql.conf: Users can replace postgresql.conf entirely via configOverride. The -c command-line flags have the highest precedence in PostgreSQL, ensuring the cluster-wide TLS profile is enforced regardless of user customizations. When the env vars are not set (non-Operator installs, or clusters without a TLS profile), nothing changes (Postgres uses its defaults, or the values from a user customized postgresql.conf).

This change does not cover Scanner V2. We will request an exception for TLS settings adherence due to it being deprecated.

More context: design doc, OpenShift enhancement proposal

User-facing documentation

Testing and quality

  • the change is production ready: the change is GA, or otherwise the functionality is gated by a feature flag
  • CI results are inspected

Automated testing

  • added unit tests
  • added e2e tests
  • added regression tests
  • added compatibility tests
  • modified existing tests

How I validated my change

Manual tests with various settings (did similar tests for both central-db and scanner-v4-indexer)

kubectl port-forward svc/central-db -n "$NS" 15432:5432 &

kubectl set env deployment/central-db -n "$NS" \
  ROX_TLS_MIN_VERSION=TLSv1.3 \
  ROX_TLS_OPENSSL_CIPHERS-

# Should FAIL (TLS 1.2 rejected)
openssl s_client -connect localhost:15432 -starttls postgres -tls1_2
# Should SUCCEED
openssl s_client -connect localhost:15432 -starttls postgres -tls1_3

kubectl set env deployment/central-db -n "$NS" \
  ROX_TLS_MIN_VERSION=TLSv1.2 \
  ROX_TLS_OPENSSL_CIPHERS=ECDHE-ECDSA-AES256-GCM-SHA384

# Should SUCCEED (matching cipher + ECDSA key)
openssl s_client -connect localhost:15432 -starttls postgres -tls1_2 \
  -cipher ECDHE-ECDSA-AES256-GCM-SHA384

# Should FAIL (cipher not in allowed list)
openssl s_client -connect localhost:15432 -starttls postgres -tls1_2 \
  -cipher ECDHE-ECDSA-AES128-GCM-SHA256

kubectl set env deployment/central-db -n "$NS" \
  ROX_TLS_MIN_VERSION=TLSv1.3 \
  ROX_TLS_OPENSSL_CIPHERS=ECDHE-ECDSA-AES256-GCM-SHA384

# Should SUCCEED (TLS 1.3 works, ssl_ciphers only affects <=1.2)
openssl s_client -connect localhost:15432 -starttls postgres -tls1_3

# Should FAIL (TLS 1.2 rejected by min version)
openssl s_client -connect localhost:15432 -starttls postgres -tls1_2

# Invalid values -> pods crash
kubectl set env deployment/central-db -n "$NS" \
  ROX_TLS_MIN_VERSION=bogus \
  ROX_TLS_OPENSSL_CIPHERS=NOT_A_CIPHER

@openshift-ci
Copy link

openshift-ci bot commented Feb 24, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@rhacs-bot
Copy link
Contributor

rhacs-bot commented Feb 24, 2026

Images are ready for the commit at 6da9db2.

To use with deploy scripts, first export MAIN_IMAGE_TAG=4.11.x-165-g6da9db2a0f.

@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 49.52%. Comparing base (43bd44d) to head (6da9db2).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #19160      +/-   ##
==========================================
- Coverage   49.52%   49.52%   -0.01%     
==========================================
  Files        2672     2672              
  Lines      201667   201667              
==========================================
- Hits        99878    99871       -7     
- Misses      94330    94337       +7     
  Partials     7459     7459              
Flag Coverage Δ
go-unit-tests 49.52% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@vladbologa vladbologa marked this pull request as ready for review February 24, 2026 15:56
@vladbologa vladbologa requested a review from a team as a code owner February 24, 2026 15:56
@erthalion
Copy link
Contributor

This PR introduces a way to configure TLS settings in the PostgreSQL deployments (central-db and scanner-v4-db) via environment variables (that will be set by the Operator in the future). If the environment variables are not set, the default configuration is used.

Do you expect this configuration to change often? If not, why not put it into the postgresql.conf instead?

I used the docker-entrypoint.sh scripts in order to pass these values directly to PostgreSQL, overriding any setting that might be present in postgresql.conf (even if this file was overridden by the user). I think this is the right way, as compliance with OpenShift TLS settings should have precedence.

I disagree with the enforcing approach, there could be users running in environments other than OpenShift. Is there anything that prevents us keeping the defaults compliant with the OpenShift TLS, but still overridable?

@vladbologa
Copy link
Contributor Author

vladbologa commented Feb 25, 2026

This PR introduces a way to configure TLS settings in the PostgreSQL deployments (central-db and scanner-v4-db) via environment variables (that will be set by the Operator in the future). If the environment variables are not set, the default configuration is used.

Do you expect this configuration to change often? If not, why not put it into the postgresql.conf instead?

This has to be inherited from the OpenShift cluster, and can change dynamically. There's more context here:

postgresql.conf can be overriden by the user, that's why I'm not appending the settings there. Although that was my original intention.

I used the docker-entrypoint.sh scripts in order to pass these values directly to PostgreSQL, overriding any setting that might be present in postgresql.conf (even if this file was overridden by the user). I think this is the right way, as compliance with OpenShift TLS settings should have precedence.

I disagree with the enforcing approach, there could be users running in environments other than OpenShift. Is there anything that prevents us keeping the defaults compliant with the OpenShift TLS, but still overridable?

These env vars are only set by the Operator, which retrieves the TLS profile from the OpenShift API server.

If the cluster has no TLS profile (non-OpenShift, or OpenShift with default/legacy settings), the env vars are simply not set, and PostgreSQL uses its built-in defaults (or whatever the user configured in postgresql.conf, exactly as it does today.

The enforcement is intentional and mandated. When a cluster administrator configures a TLS profile, it's a cluster-wide compliance requirement and individual components should not be able to weaken it.

@erthalion
Copy link
Contributor

I see. To summarize, it means that the only case, when this would be enforced, is if there is an OpenShift TLS profile, but user actively doesn't want to use it. Makes sense to me.

Just to clarify about this one:

postgresql.conf can be overriden by the user, that's why I'm not appending the settings there. Although that was my original intention.

AFAICT currently the relevant postgresql.conf bits could be overwritten only using overlays in the SecuredClusterCR. Btw, what will happen if one adds ROX_TLS_MIN_VERSION/ROX_TLS_OPENSSL_CIPHERS into the overlays with values that differs from the operator, what will win?

### ROX_TLS_MIN_VERSION: passed to ssl_min_protocol_version (e.g. "TLSv1.2", "TLSv1.3").
### ROX_TLS_OPENSSL_CIPHERS: colon-separated OpenSSL cipher names
### (e.g. "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384").
### Only affects TLS 1.2; TLS 1.3 ciphers are not configurable in PostgreSQL 15.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI, they will be configurable in PG18, there is ssl_tls13_ciphers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, but the current OpenShift design is that ciphers are not being passed at all for TLS 1.3. So it doesn't affect us, for now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PG18 will probably be upon us sooner than we think due to other Red Hat/OpenShift requirements. So something to keep in the back of our head.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we actually need the ssl_groups setting for another issue (enabling PQC key exchange algos) and that's only available in PG18 right now.

But because Go doesn't allow customizing ciphers when using TLS 1.3, the TLS adherence API from OpenShift doesn't allow ciphers in that case. So for now we're not required to set ciphers when using TLS 1.3.

@vladbologa
Copy link
Contributor Author

Just to clarify about this one:

postgresql.conf can be overriden by the user, that's why I'm not appending the settings there. Although that was my original intention.

AFAICT currently the relevant postgresql.conf bits could be overwritten only using overlays in the SecuredClusterCR. Btw, what will happen if one adds ROX_TLS_MIN_VERSION/ROX_TLS_OPENSSL_CIPHERS into the overlays with values that differs from the operator, what will win?

Good question. Overlays would win, I think. That's already the case with env vars like ROX_INSTALL_METHOD, POD_NAMESPACE etc - users could break the installation by overriding these.

Anyway, I think it's OK to allow overlays as an escape hatch for overriding TLS settings.

@vladbologa vladbologa requested review from a team, GrimmiMeloni, mclasmeier and porridge and removed request for a team February 25, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants