Skip to content

feat(auth): support client-pinned caching SHA-2 RSA authentication - #6032

Merged
renecannao merged 6 commits into
v3.0from
feature/caching-sha2-server-public-key-path
Aug 11, 2026
Merged

feat(auth): support client-pinned caching SHA-2 RSA authentication#6032
renecannao merged 6 commits into
v3.0from
feature/caching-sha2-server-public-key-path

Conversation

@renecannao

@renecannao renecannao commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • support Oracle MySQL clients using --server-public-key-path for non-TLS caching_sha2_password full authentication
  • retain the existing --get-server-public-key request/response flow
  • keep an immutable per-exchange RSA key snapshot so key rotation cannot mix the advertised public key with a different private key
  • gate all new protocol behavior with PROXYSQL31, making it available in ProxySQL 3.1 and 4.0 but not 3.0
  • document operational security and coordinated key rotation requirements

This is a follow-up to #6017. That work supports clients that request ProxySQL's public key in-band. Oracle MySQL clients configured with --server-public-key-path skip that request and send the RSA ciphertext immediately, which previously caused ProxySQL to reject the authentication packet.

Validation

  • deterministic RED: the focused TAP failed only the pinned-key success assertion before the implementation
  • ProxySQL 3.1 DEBUG build and focused TAP: 13/13
  • ProxySQL 4.0 DEBUG build and focused TAP: 13/13
  • ProxySQL 3.0 DEBUG build: new helper symbols and option string absent
  • ProxySQL 3.1 pass-through, X.509, COM_CHANGE_USER, and authentication regression suites passed
  • ProxySQL 3.0 COM_CHANGE_USER, tier-gate, and authentication regression suites passed
  • relevant unit suites: 48/48 and 55/55
  • source lint and TAP group lint passed

The focused test checks both --get-server-public-key and --server-public-key-path, rejects an incorrect pinned-key password with 1045, and verifies that the recovered password is not exposed through internal-session output.

Summary by CodeRabbit

  • New Features

    • Added non-TLS caching_sha2_password RSA authentication with requested or client-pinned public keys.
    • Preserved a consistent RSA key throughout each authentication exchange, including during key rotation.
    • Added support for applicable ProxySQL 3.1 and 4.0 configurations.
  • Bug Fixes

    • Replaced rejection of non-TLS RSA authentication with validated, secure decryption.
  • Documentation

    • Expanded guidance on configuration, authentication modes, supported versions, key rotation, security, and failures.
  • Tests

    • Added coverage for requested and pinned keys, incorrect passwords, missing keys, and validation errors.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02ab92db-5571-4d45-a72b-ee24bea73b77

📥 Commits

Reviewing files that changed from the base of the PR and between a05ac0e and 58e5193.

📒 Files selected for processing (4)
  • docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md
  • docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md
  • lib/MySQL_Protocol.cpp
  • test/tap/tests/unit/protocol_unit-t.cpp
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md
  • docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md
  • lib/MySQL_Protocol.cpp
📜 Recent review details
⏰ Context from checks skipped due to timeout. (5)
  • GitHub Check: CI-builds / builds (ubuntu24,-tap-genai-gcov)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap)
  • GitHub Check: CI-builds / builds (debian12,-dbg)
  • GitHub Check: run / trigger
  • GitHub Check: build
🧰 Additional context used
📓 Path-based instructions (3)
test/tap/tests/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

test/tap/tests/**/*.cpp: Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp.
To add a new TAP test, add the <testname>-t.cpp file and register it in test/tap/tests/Makefile/groups.json; no special Makefile target is needed because make <testname>-t is generated by pattern rule.

Files:

  • test/tap/tests/unit/protocol_unit-t.cpp
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names must use PascalCase with protocol prefixes such as MySQL_, PgSQL_, and ProxySQL_.
Member variables must use snake_case.
Constants and macros must use UPPER_SNAKE_CASE.
Use C++17, and gate conditional code with #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, and #ifdef PROXYSQLCLICKHOUSE; PROXYSQLGENAI must not guard core code outside plugins/genai/.
Consider performance implications when changing hot paths or other performance-critical code.
Use RAII for resource management and jemalloc for allocation.
Use pthread mutexes for synchronization and std::atomic<> for counters.

Files:

  • test/tap/tests/unit/protocol_unit-t.cpp
test/tap/tests/unit/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in test/tap/tests/unit/ must use test_globals.h and test_init.h with the custom unit-test harness.

Files:

  • test/tap/tests/unit/protocol_unit-t.cpp
🧠 Learnings (2)
📚 Learning: 2026-01-20T09:34:19.124Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:39-48
Timestamp: 2026-01-20T09:34:19.124Z
Learning: In ProxySQL's TAP test suite, resource leaks (e.g., not calling mysql_close() on early return paths) are commonly tolerated because test processes are short-lived and OS frees resources on exit. This pattern applies to all C++ test files under test/tap/tests. When reviewing, recognize this as a project-wide test convention and focus on test correctness and isolation rather than insisting on fixing such leaks in these test files.

Applied to files:

  • test/tap/tests/unit/protocol_unit-t.cpp
📚 Learning: 2026-04-01T21:27:00.297Z
Learnt from: wazir-ahmed
Repo: sysown/proxysql PR: 5557
File: test/tap/tests/unit/gtid_set_unit-t.cpp:14-17
Timestamp: 2026-04-01T21:27:00.297Z
Learning: In ProxySQL unit tests under test/tap/tests/unit/, include test_globals.h and test_init.h only for tests that depend on ProxySQL runtime globals/initialization (i.e., tests that exercise components linked against libproxysql.a). For “pure” data-structure/utility tests (e.g., ezoption_parser_unit-t.cpp, gtid_set_unit-t.cpp, gtid_trxid_interval_unit-t.cpp) that do not require runtime globals/initialization, it is correct to omit test_globals.h and test_init.h and instead include only tap.h plus the relevant project header(s).

Applied to files:

  • test/tap/tests/unit/protocol_unit-t.cpp
🔇 Additional comments (1)
test/tap/tests/unit/protocol_unit-t.cpp (1)

259-292: LGTM!

Also applies to: 301-322, 528-528, 547-547


📝 Walkthrough

Walkthrough

The change adds client-pinned RSA key support for non-TLS caching_sha2_password authentication in ProxySQL 3.1 and 4.0. It snapshots keys per exchange, extracts shared decryption logic, expands regression coverage, and updates documentation and implementation plans.

Changes

Caching SHA-2 RSA authentication

Layer / File(s) Summary
Authentication design and verification plan
docs/superpowers/specs/..., docs/superpowers/plans/...
Defines immutable RSA key snapshots, requested-key and pinned-key flows, failure handling, tier gating, regression coverage, and verification steps.
RSA snapshot and response decryption
include/MySQL_Protocol.h, lib/MySQL_Protocol.cpp
Adds private PROXYSQL31 helpers, captures RSA keys during full and pass-through authentication, and decrypts client responses with the captured snapshot.
Client modes and operational documentation
test/tap/tests/reg_test_5988-caching_sha2_rsa-t.cpp, doc/caching_sha2_password_rsa.md
Tests requested-key and --server-public-key-path modes, incorrect passwords, cleanup, supported versions, rotation behavior, and failure semantics.
Protocol validation tests
test/tap/tests/unit/protocol_unit-t.cpp
Tests stage-specific responses, missing RSA keys, bounded payloads, and updated TAP counts.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MySQLCLI
  participant ProxySQL
  participant MySQLProtocol
  participant RSAKeySnapshot
  MySQLCLI->>ProxySQL: Start caching_sha2_password authentication
  ProxySQL->>MySQLProtocol: Process 0x04 challenge
  MySQLProtocol->>RSAKeySnapshot: Capture active RSA key
  MySQLProtocol-->>MySQLCLI: Send requested public key when requested
  MySQLCLI->>MySQLProtocol: Send key-request or pinned-key ciphertext
  MySQLProtocol->>RSAKeySnapshot: Decrypt response with snapshot
  MySQLProtocol-->>ProxySQL: Advance authentication or report failure
Loading

Possibly related issues

Possibly related PRs

  • sysown/proxysql#6017 — Both changes update the RSA authentication implementation, documentation, and regression tests.
  • sysown/proxysql#5810 — Both changes modify caching_sha2_password authentication handling in MySQL_Protocol.
  • sysown/proxysql#5991 — Both changes modify the caching_sha2_password RSA flow in lib/MySQL_Protocol.cpp.

Poem

A rabbit guards the RSA key,
Through challenge, cipher, hop, and flee.
One snapshot stays from start to end,
While pinned keys guide the flow.
Tests thump their paws with glee.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: support for client-pinned caching SHA-2 RSA authentication.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/caching-sha2-server-public-key-path

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread lib/MySQL_Protocol.cpp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/MySQL_Protocol.cpp`:
- Around line 2883-2885: Move capture_caching_sha2_rsa_snapshot() before
generate_one_byte_pkt() in both authentication paths at
lib/MySQL_Protocol.cpp:2883-2885 and 2953-2955, and reset the snapshot whenever
packet generation fails. Update the challenge-ordering requirement in
docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md:63-72
and the implementation sequence and failure-cleanup guidance in
docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md:255-277.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4fc9a5e1-a8ab-4366-b2cc-354c4e1bfaba

📥 Commits

Reviewing files that changed from the base of the PR and between efa624d and a05ac0e.

📒 Files selected for processing (6)
  • doc/caching_sha2_password_rsa.md
  • docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md
  • docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md
  • include/MySQL_Protocol.h
  • lib/MySQL_Protocol.cpp
  • test/tap/tests/reg_test_5988-caching_sha2_rsa-t.cpp
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: Gitar
  • GitHub Check: run / trigger
  • GitHub Check: build
🧰 Additional context used
📓 Path-based instructions (3)
include/**/*.h

📄 CodeRabbit inference engine (CLAUDE.md)

Header include guards use the #ifndef __CLASS_*_H convention.

Files:

  • include/MySQL_Protocol.h
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names must use PascalCase with protocol prefixes such as MySQL_, PgSQL_, and ProxySQL_.
Member variables must use snake_case.
Constants and macros must use UPPER_SNAKE_CASE.
Use C++17, and gate conditional code with #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, and #ifdef PROXYSQLCLICKHOUSE; PROXYSQLGENAI must not guard core code outside plugins/genai/.
Consider performance implications when changing hot paths or other performance-critical code.
Use RAII for resource management and jemalloc for allocation.
Use pthread mutexes for synchronization and std::atomic<> for counters.

Files:

  • include/MySQL_Protocol.h
  • test/tap/tests/reg_test_5988-caching_sha2_rsa-t.cpp
  • lib/MySQL_Protocol.cpp
test/tap/tests/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

test/tap/tests/**/*.cpp: Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp.
To add a new TAP test, add the <testname>-t.cpp file and register it in test/tap/tests/Makefile/groups.json; no special Makefile target is needed because make <testname>-t is generated by pattern rule.

Files:

  • test/tap/tests/reg_test_5988-caching_sha2_rsa-t.cpp
🧠 Learnings (4)
📚 Learning: 2026-01-20T09:34:19.124Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:39-48
Timestamp: 2026-01-20T09:34:19.124Z
Learning: In ProxySQL's TAP test suite, resource leaks (e.g., not calling mysql_close() on early return paths) are commonly tolerated because test processes are short-lived and OS frees resources on exit. This pattern applies to all C++ test files under test/tap/tests. When reviewing, recognize this as a project-wide test convention and focus on test correctness and isolation rather than insisting on fixing such leaks in these test files.

Applied to files:

  • test/tap/tests/reg_test_5988-caching_sha2_rsa-t.cpp
📚 Learning: 2026-04-11T13:17:55.508Z
Learnt from: renecannao
Repo: sysown/proxysql PR: 5607
File: doc/GH-Actions/README.md:13-18
Timestamp: 2026-04-11T13:17:55.508Z
Learning: When using GitHub-flavored Markdown headings, be aware that an em-dash surrounded by spaces (written as ` — `) affects the generated anchor/slug: GitHub replaces spaces with hyphens and removes non-alphanumeric punctuation, which can produce double hyphens (e.g., `## Foo — bar` → anchor `#foo--bar`, not `#foo-bar`). If you reference these anchors (e.g., internal links), ensure the expected slug matches this behavior.

Applied to files:

  • docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md
  • doc/caching_sha2_password_rsa.md
  • docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md
📚 Learning: 2026-04-11T13:17:55.509Z
Learnt from: renecannao
Repo: sysown/proxysql PR: 5607
File: doc/GH-Actions/README.md:13-18
Timestamp: 2026-04-11T13:17:55.509Z
Learning: When reviewing GitHub-flavored Markdown links/anchors, remember that heading-to-anchor slug generation treats spaces as hyphens and removes punctuation. If a heading contains an em-dash surrounded by spaces (e.g. ` — `), the slugs can legitimately include a double hyphen where the two surrounding space-runs become `-` on either side of the removed em-dash (e.g. `...vocabulary--read...`). Do not flag double-hyphens in anchor links for em-dash-containing headings as errors; they reflect GitHub’s correct slug behavior.

Applied to files:

  • docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md
  • doc/caching_sha2_password_rsa.md
  • docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md
📚 Learning: 2026-04-11T13:16:05.854Z
Learnt from: renecannao
Repo: sysown/proxysql PR: 5607
File: doc/GH-Actions/README.md:13-18
Timestamp: 2026-04-11T13:16:05.854Z
Learning: When validating GitHub-rendered Markdown in this repository (e.g., links that use heading anchors), account for GitHub slug behavior for headings containing an em-dash (—) surrounded by spaces: GitHub strips the em-dash and converts each surrounding space into a hyphen independently, which can produce a double hyphen (--) in the generated anchor. Therefore, do NOT flag as broken links any anchors whose expected slug contains a double hyphen specifically attributable to an em-dash surrounded by spaces in the source heading. (Example: `...vocabulary — read...` -> `...vocabulary--read...`.)

Applied to files:

  • doc/caching_sha2_password_rsa.md
🪛 LanguageTool
docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md

[style] ~16-~16: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...-keyand--server-public-key-path. - ProxySQL 4.0 must support both paths because PR...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md

[style] ~16-~16: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...PROXYSQL40=1impliesPROXYSQL31=1`. - ProxySQL Stable 3.0 must not expose or execute t...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (12)
docs/superpowers/specs/2026-08-11-caching-sha2-server-public-key-path-design.md (1)

1-60: LGTM!

Also applies to: 74-200

docs/superpowers/plans/2026-08-11-caching-sha2-server-public-key-path.md (1)

1-254: LGTM!

Also applies to: 279-550

include/MySQL_Protocol.h (1)

232-241: LGTM!

lib/MySQL_Protocol.cpp (1)

1954-2025: LGTM!

Also applies to: 2027-2031, 2051-2066, 2098-2110

test/tap/tests/reg_test_5988-caching_sha2_rsa-t.cpp (5)

11-32: LGTM!


79-114: LGTM!


132-167: LGTM!

Also applies to: 222-264


366-371: LGTM!


331-363: 🎯 Functional Correctness

Remove this comment. test/tap/groups/groups.json excludes reg_test_5988-caching_sha2_rsa-t below ProxySQL 3.1 through @proxysql_min_version:3.1.

			> Likely an incorrect or invalid review comment.
doc/caching_sha2_password_rsa.md (3)

3-8: LGTM!

Also applies to: 18-18


73-88: LGTM!


90-138: LGTM!

Comment thread lib/MySQL_Protocol.cpp Outdated
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 41.97531% with 47 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.42%. Comparing base (efa624d) to head (58e5193).
⚠️ Report is 229 commits behind head on v3.0.

Files with missing lines Patch % Lines
lib/MySQL_Protocol.cpp 30.18% 37 Missing ⚠️
...est/tap/tests/reg_test_5988-caching_sha2_rsa-t.cpp 64.28% 4 Missing and 6 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             v3.0    #6032      +/-   ##
==========================================
+ Coverage   53.39%   53.42%   +0.02%     
==========================================
  Files         492      492              
  Lines      146280   146307      +27     
  Branches    36965    36972       +7     
==========================================
+ Hits        78113    78159      +46     
+ Misses      50995    50968      -27     
- Partials    17172    17180       +8     
Flag Coverage Δ
integration-tests 49.39% <22.22%> (+0.02%) ⬆️
unit-tests 15.70% <31.37%> (+0.01%) ⬆️

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

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@renecannao
renecannao marked this pull request as ready for review August 11, 2026 09:35
@sonarqubecloud

Copy link
Copy Markdown

@renecannao

Copy link
Copy Markdown
Contributor Author

Gitar fix CI

@gitar-bot

gitar-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

Gitar fix CI

On it — working on fixing the CI failure now.

@gitar-bot

gitar-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Adds client-pinned caching SHA-2 RSA authentication support with isolated key snapshots for safe rotation, addressing the inconsistent RSA-unavailable error handling. No issues found.

✅ 1 resolved
Quality: RSA-unavailable error set inconsistently across reject paths

📄 lib/MySQL_Protocol.cpp:2098-2102 📄 lib/MySQL_Protocol.cpp:1976-1983
In the stage-5 dispatch, frontend_auth_error_ = MySQLFrontendAuthError::CACHING_SHA2_RSA_UNAVAILABLE is set at the call site before invoking PPHR_decrypt_caching_sha2_rsa_response, but the equivalent "no snapshot" case reached through the stage-6 path (or a size-mismatch/decrypt failure) leaves frontend_auth_error_ at its prior value, so clients receive a generic access-denied rather than the RSA-unavailable guidance. Consider setting the error inside the helper's null-snapshot branch so the diagnostic is uniform regardless of which stage dispatched the response.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@renecannao
renecannao merged commit 7b0d92f into v3.0 Aug 11, 2026
82 of 84 checks passed
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.

1 participant