Conversation
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
This PR makes PostgreSQL SSL/TLS configurable (instead of hardcoded sslmode=disable) across Bucketeer services, defaulting connections to sslmode=require and updating local environments to serve TLS so the encrypted path is exercised.
Changes:
- Add a PostgreSQL TLS configuration surface (
sslmode,sslrootcert,sslcert,sslkey) with client-side mode validation and DSN building vianet/url(fixing reserved-character credential escaping). - Wire new SSL/TLS flags/env vars into api/web/batch/subscriber and extend data-warehouse Postgres configs to carry SSL/TLS settings.
- Update Helm localenv and Docker Compose to serve PostgreSQL over TLS using a development certificate, plus Make targets to generate/install the cert and create Kubernetes secrets.
Reviewed changes
Copilot reviewed 28 out of 30 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tools/dev/postgres.config | Adds OpenSSL config for generating a dev Postgres TLS cert with required SANs. |
| tools/dev/Makefile | Adds targets to generate the Postgres TLS certificate and create a minikube secret from it. |
| tools/dev/cert/postgres-tls.crt | Commits the dev Postgres certificate used by local TLS setups. |
| tools/dev/cert/postgres-tls.key | Dev Postgres private key (content excluded from review by policy). |
| pkg/storage/v2/postgres/client.go | Introduces SSLConfig + DSN builder using net/url, validates sslmode, defaults to require. |
| pkg/storage/v2/postgres/client_test.go | Adds unit tests for DSN building, credential escaping, and SSL defaulting behavior. |
| pkg/api/cmd/server.go | Adds Postgres SSL/TLS CLI flags and passes SSLConfig into Postgres client creation. |
| pkg/web/cmd/server/server.go | Adds Postgres SSL/TLS CLI flags and extends DWH Postgres config to include SSL/TLS fields. |
| pkg/batch/cmd/server/server.go | Adds Postgres SSL/TLS CLI flags and passes SSLConfig into Postgres client creation. |
| pkg/subscriber/cmd/server/server.go | Adds Postgres SSL/TLS CLI flags and passes SSLConfig into Postgres client creation (incl. DWH). |
| pkg/subscriber/cmd/server/datawarehouse_config.go | Extends subscriber onDemandProcessors Postgres DWH JSON schema to include SSL/TLS fields. |
| manifests/bucketeer/values.yaml | Adds operational + data warehouse Postgres SSL/TLS values (incl. secret mount hook). |
| manifests/bucketeer/values.dev.yaml | Configures dev values to use verify-full and mount the dev Postgres cert secret; switches migration image repo. |
| manifests/bucketeer/charts/api/values.yaml | Exposes Postgres SSL/TLS values for the api chart. |
| manifests/bucketeer/charts/api/templates/deployment.yaml | Plumbs Postgres SSL/TLS env vars and mounts the optional Postgres cert secret. |
| manifests/bucketeer/charts/web/values.yaml | Exposes Postgres SSL/TLS values for the web chart. |
| manifests/bucketeer/charts/web/templates/deployment.yaml | Plumbs Postgres SSL/TLS env vars and mounts the optional Postgres cert secret. |
| manifests/bucketeer/charts/web/templates/datawarehouse-configmap.yaml | Adds Postgres SSL/TLS fields into the web datawarehouse configmap when DWH type is postgres. |
| manifests/bucketeer/charts/batch/values.yaml | Exposes Postgres SSL/TLS values for the batch chart. |
| manifests/bucketeer/charts/batch/templates/deployment.yaml | Plumbs Postgres SSL/TLS env vars and mounts the optional Postgres cert secret. |
| manifests/bucketeer/charts/subscriber/values.yaml | Exposes Postgres SSL/TLS values for subscriber operational DB and on-demand processor DWH configs. |
| manifests/bucketeer/charts/subscriber/templates/deployment.yaml | Plumbs Postgres SSL/TLS env vars and mounts the optional Postgres cert secret. |
| manifests/bucketeer/charts/subscriber/templates/subscribers-configmap.yaml | Includes Postgres SSL/TLS fields when rendering onDemandProcessors.json from Helm values. |
| manifests/localenv/dependencies/postgresql/values.yaml | Enables TLS for the localenv Postgres chart and references a Kubernetes TLS secret. |
| manifests/localenv/dependencies/postgresql/templates/statefulset.yaml | Installs TLS key/cert via init container (correct permissions/ownership) and enables Postgres SSL. |
| Makefile | Adds default Postgres SSL envs and ensures local compose/minikube flows create the Postgres cert secret / generate certs. |
| hack/create-postgres-event-tables/command.go | Adds Postgres SSL/TLS flags to the helper command and passes SSLConfig to the client. |
| docker-compose/config/subscriber-config/onDemandProcessors.json | Updates compose subscriber on-demand processor DWH Postgres config to include sslMode. |
| docker-compose/compose.yml | Adds a cert-install helper service + mounts certs and configures services to use verify-full locally. |
Files excluded by content exclusion policy (1)
- tools/dev/cert/postgres-tls.key
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
… from The comment referred to an sslSecretName field below it, but that field only exists under operationalDatabase.postgres. Name it explicitly so operators know which value provides the mounted files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Copilot reviewed 28 out of 30 changed files in this pull request and generated 2 comments.
Files excluded by content exclusion policy (1)
- tools/dev/cert/postgres-tls.key
Suppressed comments (4)
manifests/bucketeer/charts/web/templates/deployment.yaml:54
- Kubernetes Secret volumes default to mode
0644, butlib/pqrejects ansslkeythat is group/world-readable. As a result, configuring the newly exposed client certificate and key makes this service fail to connect. Set a restrictive default mode on this secret volume.
secret:
secretName: {{ .Values.global.operationalDatabase.postgres.sslSecretName }}
manifests/bucketeer/charts/batch/templates/deployment.yaml:49
- Kubernetes Secret volumes default to mode
0644, butlib/pqrejects ansslkeythat is group/world-readable. As a result, configuring the newly exposed client certificate and key makes this service fail to connect. Set a restrictive default mode on this secret volume.
secret:
secretName: {{ .Values.global.operationalDatabase.postgres.sslSecretName }}
manifests/bucketeer/charts/subscriber/templates/deployment.yaml:52
- Kubernetes Secret volumes default to mode
0644, butlib/pqrejects ansslkeythat is group/world-readable. As a result, configuring the newly exposed client certificate and key makes this service fail to connect. Set a restrictive default mode on this secret volume.
secret:
secretName: {{ .Values.global.operationalDatabase.postgres.sslSecretName }}
manifests/bucketeer/charts/api/templates/deployment.yaml:48
- Kubernetes Secret volumes default to mode
0644, butlib/pqrejects ansslkeythat is group/world-readable. As a result, configuring the newly exposed client certificate and key makes this service fail to connect. Set a restrictive default mode on this secret volume.
secret:
secretName: {{ .Values.global.operationalDatabase.postgres.sslSecretName }}
The Atlas job runs as a pre-install hook before any service starts, so a migration URL using verify-ca or verify-full with an sslrootcert under /usr/local/certs/postgres failed: the secret was only mounted into the service deployments. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
t-kikuc
left a comment
There was a problem hiding this comment.
LGTM
Let's consider MySQL later.
Fixes #2763
What this PR does
Makes the PostgreSQL SSL/TLS connection configurable instead of hardcoded to
sslmode=disable, and defaults it torequireso connections are encrypted unless a deployment explicitly opts out. Local development (Docker Compose and minikube) now serves TLS with a development certificate so it exercises the same path.Background / Why this PR is needed
postgres.NewClientbuilt its DSN with?sslmode=disablehardcoded, so there was no way to reach a PostgreSQL server that mandates TLS — the reporter of #2763 could not deploy against Amazon RDS without forking or putting a proxy in front of it.Rather than only making it configurable, the default is now
require:preferwould silently fall back to plaintext, which leaves operators believing a connection is encrypted when it may not be. Failing loudly is the safer default while PostgreSQL support is still marked in development, so this is the right moment to change it.Points
sslMode: disableon upgrade, otherwise the services fail to connect at startup. Needs a release note.sslmode,sslrootcert,sslcert,sslkey) via--postgres-ssl-*flags on api/web/batch/subscriber, plus the data warehouse configs, which are a separate connection.global.operationalDatabase.postgres.sslSecretNamemounts a secret at/usr/local/certs/postgresin every service, sinceverify-ca/verify-fullneed the CA file for servers like RDS whose CA is not in the system trust store.net/url. This also fixes a latent bug: a password containing URL-reserved characters (@,/,?,%) previously produced a broken DSN.tools/dev/cert/postgres-tls.*, generated bymake -C tools/dev generate-postgres-tls-certificate). It isCA:TRUE, so the same file is both the server certificate and the root that clients verify, and its SANs coverpostgres,localhost,127.0.0.1and*.default.svc.cluster.local. SANs are required: Go rejects CN-only certificates.0600), norfsGroupcan guarantee — the localenv image is overridden totimescale/timescaledb, where postgres is uid 70, not the 999 the chart'sfsGroupassumes. Both Compose and the chart therefore copy the files withinstall -o postgresfrom the postgres image itself, which is correct for any image variant.manifests/localenv/charts/postgresql-0.1.0.tgzis repackaged and must stay in sync withdependencies/postgresql/. Helm deploys the packaged copy, so editing only the source has no effect. The diff is a binary blob, so it is invisible in review.pg_hba.confuntouched). Plaintext still works, sohack/delete-e2e-data-postgresandhack/delete-postgres-data-warehousekeep working — those two are separate Go modules whose vendored dependencies are already out of sync with theirgo.modon main, so they cannot reference the new API until they are re-vendored.require, notverify-full, because the minikube targets reach PostgreSQL over the node IP and the certificate cannot name it. The Compose targets go overlocalhostand verify in full.