WL#17354: Non-Password Authentication and MFA
Background
MySQL accounts may use up to three authentication factors, including password, external, socket, and WebAuthn methods. Workbench previously did not expose the full factor configuration or the client options needed to use these methods.
User Stories
- As a user, I want to connect to MySQL using any of the authentication plugins and policies that can be configured in the server.
- As a user, I want to be prompted when to touch my USB key in order to use WebAuthn authentication
- As a user, I want to reset my current account password when the connection and account support it.
- As a DBA, I want to reset a selected account password while optionally retaining or discarding the old password.
- As a DBA, I want to create MySQL user accounts that require any of the supported MySQL authentication plugins, in a single or multi-factor configuration.
Summary
Add MFA and non-password authentication support to connection setup, the connection editor, and the user editor. The scope includes WebAuthn/FIDO, Kerberos, LDAP, PAM, Windows, OCI, OpenID Connect, socket, no-login, and password authentication methods, together with their method-specific options. It also provides a simple current-account password reset for the MySQL-managed password in factor 1, including retaining the old password and discarding it. Expired-password connections can enter the reset flow before completing setup. Passwordless WebAuthn account creation requests a temporary initial password for device registration.
Authentication Flow
In MySQL MFA, the user needs to know the authentication factors and their types beforehand and specify the necessary factors at connection time. The protocol does not offer a way to automatically determine that.
Therefore, it must be possible to proactively configure the authentication factors and their types for each stored connection. When a connection is opened, the required factors are looked up and prompted, if necessary.
Certain authentication plugins, like WebAuthn, require a specific user action instead of a password. In such cases, the plugin will prompt the user for the action at a specific point of the authentication handshake. That prompt must be surfaced through the GUI to the user. FIDO device registration for WebAuthn has a similar flow.
Connection Editor
CE-FR1 - The connection editor must let users select up to three authentication factors in factor order and omit unused factors.
CE-FR2 - The factor pickers must show client-supported authentication methods, including built-in methods and bundled plugins.
CE-FR3 - The connection editor must expose authentication-method options when required, including plugin directories, clear-text password mode, Kerberos client mode, WebAuthn device and privacy settings, OCI configuration and profile, and an OpenID Connect token file.
CE-FR3.1 - When any selected authentication factor requires a clear-text password, the connection editor must set SSL Mode to at least Required without downgrading Verify CA or Verify Identity.
CE-FR4 - The connection editor must provide a Register Factor action for a WebAuthn factor and start the WebAuthn registration flow using the configured connection.
Opening Connections
OC-FR1 - Connection setup must prompt only for credentials required by the configured factors, route password prompts to the corresponding factor, and surface WebAuthn prompts and messages in the GUI.
User Editor
UE-FR1 - The user editor must create accounts with one to three distinct authentication factors and must allow factors of existing accounts to be added, removed, reordered, or changed. Factor 1 may include a password, and factors may include authentication strings where supported.
UE-FR2 - The user editor must expose the supported authentication methods, including password, Kerberos, LDAP simple and SASL, PAM, Windows, WebAuthn, OCI, OpenID Connect, socket, and no-login authentication.
UE-FR3 - When creating a single-factor passwordless WebAuthn account, the user editor must request a temporary initial password required for device registration.
Password Reset
PR-FR1 - The GUI must allow users to reset the current MySQL account password when SSL Mode is Required, Verify CA, or Verify Identity, or when the connection uses a Unix socket, prompting for the current password only when the server requires it.
PR-FR2 - Password reset must update only the MySQL-managed password in factor 1. MySQL does not allow internally managed passwords for authentication factors 2 and 3, so do not participate in the operation.
PR-FR3 - The GUI must expose Reset Password, Reset Password and Retain Current, and Discard Old Password for the active connection and for selected user accounts in the user editor.
PR-FR4 - When a connection fails because its password is expired, the GUI must offer password reset before completing the connection workflow.
NF1 - Password values must not be assigned to non-password authentication factors.
Connection Editor
The connection editor stores authentication hints with an ordered factors
list and an optional client pluginDir. It adds method-specific connection
options for Kerberos, WebAuthn, OCI, OpenID Connect, and clear-text password
authentication, plus a register-factor request for WebAuthn registration.
Authentication method options
All selected methods are stored in factor order in
settings.authenticationHints.factors. The connection editor takes the
following additional values according to the selected methods:
| Authentication method | Editor input and stored option | Connection-time input or action |
|---|---|---|
password (caching_sha2_password, mysql_native_password, sha256_password) |
Store Password and Clear Password actions (credential store) | Prompts for the factor password when it is not available from the credential store. |
authentication_kerberos |
Client authentication plugin directory (settings.authenticationHints.pluginDir); Kerberos client mode (plugin-authentication-kerberos-client-mode: SSPI or GSSAPI) |
Uses a Kerberos ticket or credentials requested by the client plugin. |
authentication_ldap_sasl |
Client authentication plugin directory (settings.authenticationHints.pluginDir) |
Uses credentials requested by the LDAP SASL client plugin. |
authentication_ldap_simple |
Client authentication plugin directory (settings.authenticationHints.pluginDir); clear-text mode (auth-method=mysql_clear_password, set automatically) |
Prompts for the factor password. |
authentication_oci |
OCI configuration file (oci-config-file); OCI profile (authentication-oci-client-config-profile) |
Uses the credentials referenced by the selected OCI profile. |
authentication_openid_connect |
OpenID Connect token file (authentication-openid-connect-client-id-token-file) |
Uses the identity token from the configured file. |
authentication_pam |
Clear-text mode (auth-method=mysql_clear_password, set automatically) |
Prompts for the factor password. |
authentication_webauthn |
Device number (plugin-authentication-webauthn-device); preserve-privacy flag (plugin-authentication-webauthn-client-preserve-privacy); Register Factor action (register-factor: 2 or 3) |
Requests the required WebAuthn device action. Registration also prompts for the initial password. |
authentication_windows |
None. | Uses the current Windows credentials. |
auth_socket |
None. | Uses the local operating-system identity. |
The WebAuthn device number defaults to 0, and preserve privacy defaults to
false. OCI configuration file and profile are required when
authentication_oci is selected. The client plugin directory is stored once
for the connection and applied as the MySQL Shell mysqlPluginDir option.
gui.mysql.getBundledAuthenticationPlugins() -> list[str]
- Parameters: None.
- Result:
list[str]containing the client authentication plugins bundled with MySQL Shell. - Description: The editor combines this list with authentication methods that do not require a client plugin when populating the factor pickers.
Opening Connections
The connection backend consumes the ordered factor hints, supplies credentials only to password-based factors, and forwards authentication-plugin prompts and messages, including WebAuthn device requests, to the frontend.
gui.dbConnections.testConnection
- Description: Updated to accept optional additional passwords and consume the ordered
factor hints. For factors 1, 2, and 3, password credentials are represented
by
password,password2, andpassword3. A supplied password is assigned only to the first configured password-based factor and is removed from non-password factors. When the hints or factor list are absent, factor 1 defaults to password authentication. Aregister-factorrequest starts WebAuthn registration. Authentication plugin prompts and messages, including WebAuthn device requests, are returned through the existing connection event callbacks.
User Editor
The user editor exchanges an ordered authenticationFactors list. Each factor
contains an authentication plugin and an optional password or authentication
string. The backend maps the list to MySQL account creation and alteration
statements. Creating a passwordless WebAuthn account also collects a temporary
initial password before submission.
gui.mysql.listAuthenticationPlugins
- Description: Used by the user editor to retrieve the active authentication plugins reported by the connected server.
gui.mysql.getUser
- Description: Updated to return the account authentication plugins and
authentication strings as an ordered
authenticationFactorslist of up to three factors.
The authentication-related API types are:
class AuthenticationFactor:
plugin: str
password: str | None = None
authenticationString: str | None = None
class MySQLUser:
user: str
host: str
authenticationFactors: list[AuthenticationFactor]
plugin: str | None
authString: str | None
randomPassword: bool
class UserInfo:
generatedPassword: str | None
Only fields relevant to authentication are shown. The existing TLS, resource,
password-policy, account-lock, and comment fields of MySQLUser are unchanged.
authenticationFactors is ordered from factor 1 through factor 3. password
and authenticationString are mutually exclusive credentials. A None value
means that credential is not supplied; it is distinct from an empty string.
gui.mysql.createUser(options, session=None) -> UserInfo
optionsis aMySQLUser.user,host, and one to threeauthenticationFactorsare required.- Every factor requires a non-empty
pluginname. Plugin names must contain only ASCII letters, digits, and underscores, and the same plugin must not be used for more than one factor. - Only factor 1 may contain
passwordor userandomPassword=True. These inputs are accepted withcaching_sha2_password,mysql_native_password, orsha256_password. A singleauthentication_webauthnfactor is the creation-only exception:passwordsupplies its initial authentication password, orrandomPassword=Truerequests one from the server. One of the two is required. Factors 2 and 3 may containauthenticationStringfor plugins whose server configuration requires one. - A factor must not specify both
passwordandauthenticationString. Factor 1 must not combine either credential withrandomPassword=True. sessionis the MySQL session used to create the account. When omitted, the current global MySQL Shell session is used.- The result is
UserInfo.generatedPasswordcontains the generated password whenrandomPassword=True; otherwise it isNone.
The API rejects an empty factor list, more than three factors, malformed or duplicate plugin names, a password on factor 2 or 3, or conflicting credential inputs. No account is created when validation fails.
gui.mysql.updateUser(options, session=None) -> UserInfo
optionsis aMySQLUser.userandhostidentify the account to alter.authenticationFactorsis the desired factor configuration in factor order. The API adds, removes, reorders, or changes factors to match this list.- Factors follow the same plugin-name, uniqueness, and factor-count rules as
createUser.passwordandrandomPassword=Trueare accepted only for factor 1 usingcaching_sha2_password,mysql_native_password, orsha256_password. sessionis the MySQL session used to alter the account. When omitted, the current global MySQL Shell session is used.- The result is
UserInfo.generatedPasswordcontains the generated password whenrandomPassword=True; otherwise it isNone.
Password reset, password retention, and old-password discard are separate operations described below.
Password Reset
Password reset accepts a new password and, for the current account, an optional current password. It targets the account's factor-1 MySQL-managed password. The active connection and selected user-account interfaces expose reset, retain-current, and discard-old-password operations. An expired-password connection enters the same reset flow before completing setup.
Password reset is available when the connection SSL Mode is Required, Verify CA, or Verify Identity, or when the connection uses a Unix socket.
The password-reset capability types are:
class PasswordResetAccount:
user: str | None
host: str | None
class PasswordResetFactor:
plugin: str
kind: Literal["internalPassword", "externalPassword"]
passwordless: bool
requiresRegistration: bool | None
class PasswordResetCurrentPassword:
accountSetting: Literal["required", "optional", "default", "unknown"]
requiredByPolicy: bool | None
class PasswordResetInfo:
account: PasswordResetAccount
factors: list[PasswordResetFactor]
sqlResetSupported: bool | None
retainCurrentPasswordSupported: bool
currentPassword: PasswordResetCurrentPassword
gui.mysql.getPasswordResetInfo(user=None, host=None, session=None) -> PasswordResetInfo
userandhostidentify a selected account. They must either both be supplied or both be omitted. When omitted, the API inspectsCURRENT_USER.sessionis the MySQL session used to inspect the account. When omitted, the current global MySQL Shell session is used.accountcontains the canonical user and host returned by MySQL.factorscontains the account's authentication factors in factor order.kinddistinguishes MySQL-managed password plugins from external authentication plugins.sqlResetSupportedisTruewhen factor 1 uses a MySQL-managed password plugin and can be reset withALTER USER ... IDENTIFIED BY. It isFalsefor an external or passwordless factor 1.Nonemeans support could not be determined.retainCurrentPasswordSupportedisTruewhen SQL password reset is supported and the current session has sufficient privilege to retain the old password as a secondary password.currentPassword.accountSettingreports the account'sPASSWORD REQUIRE CURRENTsetting.requiredByPolicyresolves the account setting together with the server default;Nonemeans the requirement could not be determined.
The API raises an error when only one of user and host is supplied, the
account cannot be inspected, or the session is not a MySQL session. The GUI
uses the result to decide whether to offer reset, retain-current, and
discard-old-password operations and whether the reset dialog must request the
current password.
Password operations
The frontend performs password changes through the existing
gui.db.execute(moduleSessionId, sql, params, options) API. moduleSessionId
selects the SQL editor's service session. SQL values and account identifiers are
passed as parameters, and password parameters are marked for log redaction.
- Resetting the current account executes
ALTER USER USER() IDENTIFIED BY ?. When the current password is requested, it addsREPLACE ?; retaining the current password addsRETAIN CURRENT PASSWORD. - Resetting a selected account executes
ALTER USER ?@? IDENTIFIED BY ?and addsRETAIN CURRENT PASSWORDwhen selected. - Discarding the secondary password executes
ALTER USER USER() DISCARD OLD PASSWORDfor the current account orALTER USER ?@? DISCARD OLD PASSWORDfor a selected account.
For an expired-password connection, the frontend executes the current-account reset on the service session before completing connection setup.