Skip to content

Enforce configured database TLS for PHP connections - #545

Merged
rmcdaniel merged 11 commits into
mainfrom
fix/database-tls-540
Oct 20, 2026
Merged

rmcdaniel merged 11 commits into
mainfrom
fix/database-tls-540

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Problem

Fixes the PHP configuration and connection-enforcement portion of #540. The chart's TLS mode currently never reaches the MySQL/MariaDB connection, while PostgreSQL uses a literal prefer.

Implementation

  • Prepare Server 2.9.10 / Helm 0.2.0 after the separately qualified 2.9.9 source. The optional trust-bundle values follow the chart's minor-version policy. Generated product-train/content-hash and image defaults change; no dependency, package reference or schema changes.
  • Canonical DB_SSLMODE / DB_SSLROOTCERT, preserving chart aliases DB_SSL_MODE / DB_SSL_ROOT_CERT and the existing MySQL CA option.
  • Refuse conflicting modes/CA paths, unsupported modes, unverifiable CA files and required TLS over Unix sockets before connecting. MySQL/MariaDB explicitly support disable, require and verify-full; chain-only verification is refused rather than reported as supported.
  • libpq and mysqlnd enforce the selected connection mode. Failed required connections receive a named refusal. PHP ownership guards and normal bound-query readiness remain intact.
  • Readiness describes the successful connection's configured security guarantee, with unknown status for opportunistic/unconfigured TLS. Its scope is PHP to the configured endpoint, not a pooler's separate backend leg.

Evidence and remaining work

Four test-first configuration cases fail on the preceding implementation. The current focused TLS selection passes 18 tests / 39 assertions; the full TLS/readiness/ownership selection passes 76 tests / 469 assertions with 12 explicit environment-dependent ownership skips. Real PostgreSQL 17.11, MySQL 8.0.46 and MariaDB 10.11.19 controls exercise the HTTP kernel and independently inspect each direct backend connection; these are source fixtures, not a published image or physical network-HTTP qualification.

All 18 actual backend/kernel controls pass: trusted CA/hostname, encryption-only, wrong CA and wrong hostname on each of the three database families; explicit plaintext success followed by required-TLS refusal on separate TLS-disabled PostgreSQL and MySQL servers; and missing/unreadable verifying CA refusals. Verified direct connections independently report TLSv1.3 / TLS_AES_256_GCM_SHA384. Initial database-cache readiness failures remain unsuccessful fixture observations; their cache cause is not established. Fresh Redis fixtures pass. The first plaintext MySQL CLI connection was refused by its caching_sha2_password authentication policy; the separately configured fixture user permits a real plaintext positive control before testing required TLS. This is a fixture-only authentication change, not a PHP product change or rescued original.

The complete source integrates qualified main 6a3c67f0 at merge 9f9a9b5c; metadata head 51cda78ea / tree 1b971066 has retained failed Sonar/boundary originals. Its prospective CI correction is now 3fd9cfe4c25c3217e5a9ff1688b1041037271121. Runtime/configuration bytes remain unchanged from the independently tested f880b864f component: 52 focused TLS/readiness tests / 337 assertions; all 18 actual backend/kernel controls using normal locked Composer installation in a separate committed-source copy; three Helm controls; four linted fixtures; 26 chart-release tests and release-consumer/version checks. These component passes do not qualify the new whole head. The earlier complete 76-test ownership selection remains its own result.

The CI-only correction generates per-run fixture passwords, installs PyYAML as a binary wheel, uses a native bounded Actions step, and makes scoped always-cleanup explicit for partial setup. Its directory deletion refuses foreign/traversal targets. The actual ownership checker, all 72 existing policy controls and both new cleanup process controls pass locally. Sonar at 3fd passes with zero unresolved issues, independently of the remaining source checks.

Reviewing the workflow run itself then found an additional failed original: the PHP feature workflow at 3fd was rejected before any jobs were created. Its job-level environment used the unavailable runner context. Check-run inventory alone had omitted that invalid workflow. The corrected workflow moves those paths into executing steps, where GitHub supports that context. Official actionlint 1.7.12 reproduces the old context failure and passes both current modified workflows; the actual isolation checker and both cleanup controls also pass. GitHub's context availability reference confirms the distinction.

Current head e272b6f7a7de461203ab8022a7aab6bec4da9a80 / whole 24a077b1c39b62002e8dc755b955e61a1d20f48f also retires the preceding feature database/pooler stack before starting the TLS controls. It incorporates current main ef728, whose intervening change is benchmark documentation/data. Fresh PHP feature run 39469849200 now materializes normally; new normal source, TLS-backend, chart and Sonar gates remain pending. Earlier component passes do not qualify this whole head. No rule/threshold/exclusion tuning is used to hide findings.

The original 7f1eb04e5 Sonar gate correctly fails new-code duplication (12 repeated configuration lines) and reports two valid nested-condition findings. The prepared source shares the common configuration and extracts those conditionals, without threshold/profile changes. Fresh analysis must establish their disposition; no analyzer-resolution claim is made from source edits alone.

Exact head e272b6f7a7de461203ab8022a7aab6bec4da9a80 now passes all 17 applicable check runs (16 successful and one explicit conditional skip), including the PHP feature and performance source aggregates, actual TLS-backend controls, rolling-upgrade controls, HTTP topology, both chart jobs, boundaries and Sonar. All eight workflow runs for this exact commit are terminal successful, including PHP feature 39469849200. Review found no native/shared/runner/frozen or dependency-reference diff. The PR is ready for normal merge and fresh-main qualification. Protected immutable Server 2.9.10 / Helm 0.2.0 publication and installed-image TLS/business acceptance remain pending; candidate results are not published-artifact acceptance.

Rollback is the prior qualified immutable Server 2.9.9 image and Helm 0.1.185, with the prior explicitly recorded configuration; this change introduces no database migration. Original failed fixture observations, invalid workflow and failed Sonar analyses remain retained. No native/shared/runner/frozen, package resolution, OpenAPI or migration/catalog change is included. No customer/Cloud incident or historical cause is inferred.

Normal merge then correctly refused strict ancestry after main advanced through native PRs #499/#510. New combined head b4c8bb37d589b93a51b1a4c15cd91501da727f52 / whole 1d4cd63c05c9839c8d65e7dde565154535b83fe3 merges main 9c10bd0eb, preserving its exact Rust subtree 258e8d4b31d4f4e20f880e4120b01c14d0aac616. Fresh whole-head checks are pending; e272 results do not qualify this tree. No strict-ancestry or test gate was bypassed.

@rmcdaniel
rmcdaniel marked this pull request as ready for review October 20, 2026 18:41
@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel
rmcdaniel merged commit 3785364 into main Oct 20, 2026
17 checks passed
@rmcdaniel

Copy link
Copy Markdown
Member Author

Source checkpoint: #545 merged normally at 3785364cbee7785bd7907b1c516544f49994a33f, whole tree 1d4cd63c05c9839c8d65e7dde565154535b83fe3, identical to reviewed candidate b4c8bb37d589b93a51b1a4c15cd91501da727f52. The Rust subtree remains 258e8d4b31d4f4e20f880e4120b01c14d0aac616; no native/shared/frozen adoption.

The required PHP feature suite passed, including actual required-TLS and certificate-refusal qualification. Candidate Sonar, chart lint/kind install, rolling database upgrade, HTTP topology, polling-growth and boundary checks also passed. The final optional candidate workflow aggregate remains queued, so a terminal full-workflow pass is not claimed. Existing strict branch protection and required checks were preserved.

Fresh-main feature 39491510884, Sonar 39491510863, performance 39491510876, HTTP topology 39491510887, rolling upgrade 39491510902, boundary 39491510799 and chart 39491510929 are independent and pending. Server 2.9.10 / Helm 0.2.0 publication, immutable image/chart proof and normally installed TLS business acceptance remain to be completed. The existing published 2.9.9 identity is separate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants