Skip to content

feat: authentication_openid_connect_client plugin support#1221

Open
nytai wants to merge 1 commit into
PyMySQL:mainfrom
nytai:feat/oidc-jwt-auth
Open

feat: authentication_openid_connect_client plugin support#1221
nytai wants to merge 1 commit into
PyMySQL:mainfrom
nytai:feat/oidc-jwt-auth

Conversation

@nytai
Copy link
Copy Markdown

@nytai nytai commented Jan 22, 2026

Implements MySQL's OpenID Connect authentication protocol for JWT-based authentication. The protocol sends:
[1 byte capability][length-encoded token length][token]

This enables connecting to MySQL servers using OIDC tokens passed as the password parameter.

@nytai nytai changed the title add authentication_openid_connect_client plugin support feat: authentication_openid_connect_client plugin support Jan 22, 2026
Implements MySQL's OpenID Connect authentication protocol for
JWT-based authentication. The protocol sends:
[1 byte capability][length-encoded token length][token]

This enables connecting to MySQL servers using OIDC
tokens passed as the password parameter.
@nytai nytai force-pushed the feat/oidc-jwt-auth branch from c9b7675 to dbc9854 Compare January 23, 2026 00:14
@nytai
Copy link
Copy Markdown
Author

nytai commented Feb 19, 2026

@methane could we consider this PR? The core work is few lines, most of the diff in this PR is testing related.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds client-side support in PyMySQL for MySQL’s authentication_openid_connect_client OpenID Connect authentication plugin by generating the required JWT auth payload during the initial handshake and during auth-switch, and introduces unit tests that mock the network layer to validate auth packet formatting across several plugins.

Changes:

  • Implement authentication_openid_connect_client auth response formatting in Connection._request_authentication() and Connection._process_auth().
  • Add initial-handshake support for mysql_clear_password in _request_authentication().
  • Add a new mocked-socket test suite covering native, caching_sha2, cleartext, OIDC, auth-switch flows, and _lenenc_int() encoding.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
pymysql/connections.py Adds OIDC and cleartext auth response generation paths in handshake and auth-switch handling.
pymysql/tests/test_auth_protocol.py Adds mocked unit tests validating auth protocol message formatting and length-encoding behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pymysql/connections.py
else:
authresp = b"\0" # empty password
elif self._auth_plugin_name == "mysql_clear_password":
plugin_name = b"mysql_clear_password"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@nytai Is "mysql_clear_password" necessary for oidc? I still don't fully understand this authentication flow. I also haven't been able to try it out or capture packets.

Comment thread pymysql/connections.py
Comment on lines +935 to +940
elif self._auth_plugin_name == "authentication_openid_connect_client":
plugin_name = b"authentication_openid_connect_client"
# OpenID Connect: [1 byte capability][length-encoded token length][token]
capability = b"\x01"
token_len = len(self.password)
authresp = capability + _lenenc_int(token_len) + self.password
Comment thread pymysql/connections.py
Comment on lines +1028 to +1035
elif plugin_name == b"authentication_openid_connect_client":
# OpenID Connect authentication
# Protocol: [1 byte capability][length-encoded token length][token]
# Based on MySQL's authentication_openid_connect_client_plugin.cc
_ = auth_packet.read_all() # discard auth switch data
capability = b"\x01" # capability flag
token_len = len(self.password)
data = capability + _lenenc_int(token_len) + self.password
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That issue is also present in other auth plugins, right? I'll ignore it for now and resolve it later in this PR.

Comment on lines +60 to +66
"""Extract the last packet's data (without header)."""
if len(self.sent_data) < 4:
return b""
# Skip the 4-byte header (3 bytes length + 1 byte seq)
return bytes(self.sent_data[4:])


@villebro
Copy link
Copy Markdown

@methane any chance we could merge+release this? OIDC/JWT based auth is increasingly becoming the norm, so the feature introduced by this PR would be very valuable for the entire MySQL ecosystem once released.

@methane
Copy link
Copy Markdown
Member

methane commented May 13, 2026

OIDC/JWT based auth is increasingly becoming the norm, so the feature introduced by this PR would be very valuable for the entire MySQL ecosystem once released.

Where and whom?
It is an enterprise only feature. It is not an OSS.
I cannot use it. I cannot test it. I cannot maintain it. I am out of "the entire MySQL ecosystem."

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.

4 participants