Repository navigation
CI: the SQL Server certificate pin test runs on the 2025 leg against a strict server, with the certificate untrusted and trusted (BACKLOG #3714 items 6, 8) - #2579
Conversation
…rver, trusted and untrusted BACKLOG #3714 slice B, items 6 and 8. The 2025 sqlserver-store leg now starts a second container from the same digest-pinned image on 127.0.0.1:14330, after the other suites. It mounts a generated test certificate (serverAuth EKU, CN and SAN localhost) and an mssql.conf with forceencryption and forcestrict. The service container stays: forcestrict refuses every non-strict login, which every other suite makes. A wait step needs the server's ready line and a TLS-first (TDS 8.0) handshake. The pin test then runs twice: certificate untrusted, then in the runner's OpenSSL store. Each step fails if the test did not run. The test gains strict_chain (strict, no pin). The trusted arm asserts it connected, so its refused wrong pin is told apart from a chain refusal. The 2022 leg is unchanged. Proposed PR title: CI: the SQL Server certificate pin test runs on the 2025 leg against a strict server, with the certificate untrusted and trusted (BACKLOG #3714 items 6, 8) Proposed banner: #3714 items 6 and 8 BUILT, NOT YET MEASURED: the 2025 sqlserver-store leg runs the pin test against a forcestrict server in two arms; read both BACKLOG-2223-PIN lines on the PR run before closing.
…sserts both arms' chain BACKLOG #3714 slice B, items 6 and 8: code-review round 1 fixes. - The test certificate is CA:FALSE, made from a config file. - The container publishes 14330 on all interfaces, the probes use localhost. - The wait is bounded at 180 s inside its cap, and ends with a strict login. - The second server's memory is capped at 2048 MB. - The pin steps' cap covers the retry wrapper's three attempts. - The untrusted arm asserts strict_chain REFUSED; the right pin is asserted first, and the trusted arm's message carries the driver's text. - ADR 0173 and the retry wrapper's header no longer state stale facts. Proposed PR title: CI: the SQL Server certificate pin test runs on the 2025 leg against a strict server, with the certificate untrusted and trusted (BACKLOG #3714 items 6, 8) Proposed banner: #3714 items 6 and 8 BUILT, NOT YET MEASURED: the 2025 sqlserver-store leg runs the pin test against a forcestrict server in two arms; read both BACKLOG-2223-PIN lines on the PR run before closing.
|
QA -- korus roles/BUILDER.md step 11 |
|
Manager (batch 342): do not merge yet. First reading from run 40524945884: the strict container works ( |
…ficate no longer reads as a pin Run 40524945884, job 122262048822 (sql server 2025): the strict server came up and a strict login connected, then the untrusted arm failed before it measured. Its guard, "ServerCertificate" not in unpinned_dsn, is also true of TrustServerCertificate=no;, which every verified string carries. The DSN was right; the guard was wrong. The test now reads the string as keyword=value pairs, brace-aware, and sets Encrypt by key instead of a substring replace. A new server-free test checks the reader on the builder's own strings, with a password holding the text a substring check trips on. It runs on both SQL Server legs ahead of the strict step. PR title: CI: the SQL Server certificate pin test runs on the 2025 leg against a strict server, with the certificate untrusted and trusted (BACKLOG #3714 items 6, 8) BACKLOG #3714
Dismissed because a newer commit was pushed; Greptile will re-review the current head.
|
Manager (batch 342): new reviewed head 92fdc73, one test-only commit fixing the substring guard that stopped run 40524945884 (details and six new findings in the body; the workflow is unchanged). Builder's QA line, verbatim: QA -- korus roles/BUILDER.md step 11 My hold stays until I post this run's two BACKLOG-2223-PIN readings. |
|
Manager (batch 342): the readings, from run 40535242435, job
What it shows: with the certificate trusted through the chain, a strict login with no pin connects, and a strict login pinning a different certificate is still refused with the driver's own pin-mismatch message. So on Linux ODBC Driver 18 against SQL Server 2025, the Proposed banner, replacing the one in the body: #3714 items 6 and 8 BUILT AND MEASURED on PR 2579's run 40535242435: under Encrypt=strict on Linux ODBC Driver 18 / SQL Server 2025, a wrong ServerCertificate pin is refused with the certificate trusted through the chain (strict_chain=CONNECTED, strict_wrong=REFUSED). My hold is lifted once |
|
Manager (batch 342): the head moved to fa5364b (Merge branch 'main' into b342-3714b, after PR 2583 landed). Checked: a fresh git merge-tree of the reviewed head 92fdc73 with main cf441c8 gives a tree identical to fa5364b's, so the new head adds only a clean merge of main. My readings comment stands; the hold lifts when the required checks are green on fa5364b. |
|
Manager (batch 342): re-ran the failed job once on head fa5364b. The red leg was |
|
Lander (session 8a04c9f3), 2026-10-28. Enqueuing at pinned head Review proof: the Builder's QA line (xhigh, two rounds) covers Open findings, each filed on vault
|
Merge danger
Reversible: yes -- a revert of this change on
mainundoes all of it.Blast radius: CI only, plus one test. In
.github/workflows/ci.yml, jobsqlserver-store, five new steps, all gatedif: matrix.label == '2025', after the privilege-preflight step: start a second SQL Server container (mssql-strict, same${{ matrix.image }}digest, port 14330) with a generated test certificate andnetwork.forcestrict = 1; wait for a TLS-first (TDS 8.0) handshake and a strict login (bounded at 180 s inside a 5-minute cap); run the pin test untrusted; trust the certificate withupdate-ca-certificates; run the pin test trusted. No job id, step orname:is renamed;services:, the matrix, the 2022 leg,.github/required-contexts.txt, the CI gate roll-up andchangesare untouched; there is nocontinue-on-error, and every new step fails closed. The leg is not a required context by name, but the requiredCI gaterolls it up, so a red here blocks a merge.tests/test_sqlserver_store.py: the pin test gains astrict_chainarm (strict, no pin) and names the arm in its warning line. ADR 0173: one "No CI job sets it" line corrected with a marker.scripts/ci/retry-native-crash.sh: one comment.Evidence
sql server (store + connector) 2022and... 2025SKIPPEDtest_server_certificate_pin_is_enforced_under_strict_encryption; it has never run in CI, so a green SQL Server leg said nothing about the pin.sql server (store + connector) 2025: the wait step'sBACKLOG-3714-STRICT-READY after <n>s: ...; strict login CONNECTED(or its::error::naming the stage it never passed);BACKLOG-2223-PIN arm=untrusted strict_right=... strict_wrong=... strict_chain=... yes_right=... yes_wrong=...(also a::notice); the trust step'sVerify return code: 0 (ok);BACKLOG-2223-PIN arm=trusted .... Item 6 closes on the trusted line showingstrict_chain=CONNECTEDandstrict_wrong=REFUSED; item 8 on either line printing. The 2022 leg should show none of these steps. Each pin step fails if noBACKLOG-2223-PINline prints, because a skip would read like a pass.BACKLOG #3714 slice B (items 6, 8) -- batch 342
Source branch
b342-3714b, head92fdc73da71d3ae5827294a2f59c0a412e9c60d9, baseorigin/main. Commits 956afd7 (build), 09bc22c (review round 1 repairs), 92fdc73 (fix after run 40524945884: the test's guard'ServerCertificate' not in unpinned_dsnmatched insideTrustServerCertificate=no;; the test now reads DSN keys with_odbc_pairs/_odbc_value/_odbc_with, plus a server-free test of that reader). The head is the reviewed head: the fix round's single review read it, and nothing was committed after.First reading (run 40524945884):
BACKLOG-3714-STRICT-READY after 4s: New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 ALPN protocol: tds/8.0; strict login CONNECTED. Linux SQL Server 2025 serves TDS 8.0 strict in hosted CI; the pin test then failed on its own guard before measuring.Whose decision
Decided 2026-10-27 by the batch 342 Manager under the owner's delegation of 2026-10-27 (decision
d20261027T133707051-2171e6). The question, as asked through AskUserQuestion: "#3714 items 6 and 8: the SQL Server pin test has never run in CI (both SQL Server legs skip it). Making it run is a CI workflow change. Adversarial review SPLIT: Linux SQL Server 2022 cannot force strict encryption (only 2025+ has network.forcestrict), the job's services: container would have to become a docker run step, and a flaky strict leg could block the merge queue. What should happen?" The owner's answer: "/driver". Decided: measure, then make the 2025 leg strict only.One departure from the brief: the brief said to replace the 2025 service container. The Builder kept it and added a separate strict container, because
forcestrictrefuses every non-strict login and every other suite on the leg connects withEncrypt=yes. That keeps all the constraints above.Checks (Builder's report)
bash -non all five new run bodies (with a broken-body control that exits 2); the certificate recipe on local OpenSSL 3.5 (a trusted self-signed leaf verifies; a wrong-hostname control is refused; Ubuntu's 3.0 not tried); ruff, mypy on the test file (linux); pre-commit including "Lint GitHub Actions workflow files"; pytest over every test reading the workflows, the retry wrapper or the ADRs, plustest_sqlserver_store.py: 6020 passed, 279 skipped, 71 xfailed (test_workflow_pipefail_screencaught one unguardeddocker logs | tailin the first draft, fixed);/simplify.Known open findings (shipped open; two rounds, cap reached)
Encrypt=yesreadings and confines the test to 2025. Both rounds say a server with onlytlscert/tlskeywould likely accept strict logins too, keeping the yes comparison with #3009 and possibly running on 2022. Kept because the decision names forcestrict and 2025; worth revisiting once this run's lines are read.strict_rightcontrol itself; a real right-pin failure surfaces as "not ready within 180 s" naming the stage and the driver's text, with no PIN line.bash -e(handshake=,logs="$(docker logs ...)") could end the step without its diagnostic.RETRY_NATIVE_CRASH_CAUSE: "". The "every database-leg call site" comment is a completeness claim (andtests/test_ci_retry_native_crash.py:128still says "Nine call sites").strict_chainREFUSED, so a local run with the strict variable against a trusted certificate fails unless it setsMEFOR_TEST_SQLSERVER_PIN_TRUSTED=1.!cancelled()would separate a flaky earlier suite from the pin lines.127.0.0.1would do.::noticetext is not escaped for%, CR or LF..crtat job end (matters only on a reused runner).strict_wrong, not only a certificate mismatch; the driver's message is in the line.From the fix round's review (new): 14. the new reader test's control
"ServerCertificate" in unpinnedalso passes on the password text alone; 15. the server-free reader test sits in the gated module, so the maintestjob never runs it; 16. the trust and trusted-arm steps run only if every earlier step passed, so a failed untrusted arm skips the one reading that separates a pin refusal from a chain refusal (!cancelled()plus the wait step's outcome suggested); 17. no step checks thatforcestricttook effect; 18. the second server starts beside the uncapped service container (memory pressure); 19. a pytest-timeout kill reports as "did not run".Proposed ledger banner (for the Lander)
#3714 items 6 and 8 BUILT, NOT YET MEASURED: the 2025 sqlserver-store leg runs the pin test against a forcestrict server in two arms; read both BACKLOG-2223-PIN lines on the PR run before closing. (The batch 342 Manager will post the readings here.)
Landing order
None required. Clean against
mainand against the open PRs that touchci.yml(2550, 2554, 2561, 2565, 2570), each merged onto currentmainfirst.