MySQL 8.4 Reference Manual Including MySQL NDB Cluster 8.4
The MySQL server authenticates client connections using authentication plugins. The plugin that authenticates a given connection may request that the connecting (external) user be treated as a different user for privilege-checking purposes. This enables the external user to be a proxy for the second user; that is, to assume the privileges of the second user:
The external user is a “proxy user” (a user who can impersonate or become known as another user).
The second user is a “proxied user” (a user whose identity and privileges can be assumed by a proxy user).
This section describes how the proxy user capability works. For general information about authentication plugins, see Section 8.2.17, “Pluggable Authentication”. For information about specific plugins, see Section 8.4.1, “Authentication Plugins”. For information about writing authentication plugins that support proxy users, see Implementing Proxy User Support in Authentication Plugins.
One administrative benefit to be gained by proxying is that the DBA can set up a single account with a set of privileges and then enable multiple proxy users to have those privileges without having to assign the privileges individually to each of those users. As an alternative to proxy users, DBAs may find that roles provide a suitable way to map users onto specific sets of named privileges. Each user can be granted a given single role to, in effect, be granted the appropriate set of privileges. See Section 8.2.10, “Using Roles”.
For proxying to occur for a given authentication plugin, these conditions must be satisfied:
Proxying must be supported, either by the plugin itself, or by the MySQL server on behalf of the plugin. In the latter case, server support may need to be enabled explicitly; see Server Support for Proxy User Mapping.
            The account for the external proxy user must be set up to be
            authenticated by the plugin. Use the
            CREATE USER statement to
            associate an account with an authentication plugin, or
            ALTER USER to change its
            plugin.
          
            The account for the proxied user must exist and be granted
            the privileges to be assumed by the proxy user. Use the
            CREATE USER and
            GRANT statements for this.
          
Normally, the proxied user is configured so that it can be used only in proxying scenarios and not for direct logins.
            The proxy user account must have the
            PROXY privilege for the
            proxied account. Use the
            GRANT statement for this.
          
For a client connecting to the proxy account to be treated as a proxy user, the authentication plugin must return a user name different from the client user name, to indicate the user name of the proxied account that defines the privileges to be assumed by the proxy user.
            Alternatively, for plugins that are provided proxy mapping
            by the server, the proxied user is determined from the
            PROXY privilege held by the
            proxy user.
          
The proxy mechanism permits mapping only the external client user name to the proxied user name. There is no provision for mapping host names:
When a client connects to the server, the server determines the proper account based on the user name passed by the client program and the host from which the client connects.
If that account is a proxy account, the server attempts to determine the appropriate proxied account by finding a match for a proxied account using the user name returned by the authentication plugin and the host name of the proxy account. The host name in the proxied account is ignored.
Consider the following account definitions:
-- create proxy account
CREATE USER 'employee_ext'@'localhost'
  IDENTIFIED WITH my_auth_plugin
  AS 'my_auth_string';
-- create proxied account and grant its privileges;
-- use mysql_no_login plugin to prevent direct login
CREATE USER 'employee'@'localhost'
  IDENTIFIED WITH mysql_no_login;
GRANT ALL
  ON employees.*
  TO 'employee'@'localhost';
-- grant to proxy account the
-- PROXY privilege for proxied account
GRANT PROXY
  ON 'employee'@'localhost'
  TO 'employee_ext'@'localhost';
        When a client connects as employee_ext from
        the local host, MySQL uses the plugin named
        my_auth_plugin to perform authentication.
        Suppose that my_auth_plugin returns a user
        name of employee to the server, based on the
        content of
        '
        and perhaps by consulting some external authentication system.
        The name my_auth_string'employee differs from
        employee_ext, so returning
        employee serves as a request to the server to
        treat the employee_ext external user, for
        purposes of privilege checking, as the
        employee local user.
      
        In this case, employee_ext is the proxy user
        and employee is the proxied user.
      
        The server verifies that proxy authentication for
        employee is possible for the
        employee_ext user by checking whether
        employee_ext (the proxy user) has the
        PROXY privilege for
        employee (the proxied user). If this
        privilege has not been granted, an error occurs. Otherwise,
        employee_ext assumes the privileges of
        employee. The server checks statements
        executed during the client session by
        employee_ext against the privileges granted
        to employee. In this case,
        employee_ext can access tables in the
        employees database.
      
        The proxied account, employee, uses the
        mysql_no_login authentication plugin to
        prevent clients from using the account to log in directly. (This
        assumes that the plugin is installed. For instructions, see
        Section 8.4.1.9, “No-Login Pluggable Authentication”.) For
        alternative methods of protecting proxied accounts against
        direct use, see
        Preventing Direct Login to Proxied Accounts.
      
        When proxying occurs, the USER()
        and CURRENT_USER() functions can
        be used to see the difference between the connecting user (the
        proxy user) and the account whose privileges apply during the
        current session (the proxied user). For the example just
        described, those functions return these values:
      
mysql> SELECT USER(), CURRENT_USER();
+------------------------+--------------------+
| USER()                 | CURRENT_USER()     |
+------------------------+--------------------+
| employee_ext@localhost | employee@localhost |
+------------------------+--------------------+
        In the CREATE USER statement that
        creates the proxy user account, the IDENTIFIED
        WITH clause that names the proxy-supporting
        authentication plugin is optionally followed by an AS
        ' clause
        specifying a string that the server passes to the plugin when
        the user connects. If present, the string provides information
        that helps the plugin determine how to map the proxy (external)
        client user name to a proxied user name. It is up to each plugin
        whether it requires the auth_string'AS clause. If so, the
        format of the authentication string depends on how the plugin
        intends to use it. Consult the documentation for a given plugin
        for information about the authentication string values it
        accepts.
      
Proxied accounts generally are intended to be used only by means of proxy accounts. That is, clients connect using a proxy account, then are mapped onto and assume the privileges of the appropriate proxied user.
There are multiple ways to ensure that a proxied account cannot be used directly:
            Associate the account with the
            mysql_no_login authentication plugin. In
            this case, the account cannot be used for direct logins
            under any circumstances. This assumes that the plugin is
            installed. For instructions, see
            Section 8.4.1.9, “No-Login Pluggable Authentication”.
          
            Include the ACCOUNT LOCK option when you
            create the account. See Section 15.7.1.3, “CREATE USER Statement”. With
            this method, also include a password so that if the account
            is unlocked later, it cannot be accessed with no password.
            (If the validate_password component is
            enabled, creating an account without a password is not
            permitted, even if the account is locked. See
            Section 8.4.3, “The Password Validation Component”.)
          
Create the account with a password but do not tell anyone else the password. If you do not let anyone know the password for the account, clients cannot use it to connect directly to the MySQL server.
        The PROXY privilege is needed to
        enable an external user to connect as and have the privileges of
        another user. To grant this privilege, use the
        GRANT statement. For example:
      
GRANT PROXY ON 'proxied_user' TO 'proxy_user';
        The statement creates a row in the
        mysql.proxies_priv grant table.
      
        At connect time, proxy_user must
        represent a valid externally authenticated MySQL user, and
        proxied_user must represent a valid
        locally authenticated user. Otherwise, the connection attempt
        fails.
      
        The corresponding REVOKE syntax
        is:
      
REVOKE PROXY ON 'proxied_user' FROM 'proxy_user';
        MySQL GRANT and
        REVOKE syntax extensions work as
        usual. Examples:
      
-- grant PROXY to multiple accounts GRANT PROXY ON 'a' TO 'b', 'c', 'd'; -- revoke PROXY from multiple accounts REVOKE PROXY ON 'a' FROM 'b', 'c', 'd'; -- grant PROXY to an account and enable the account to grant -- PROXY to the proxied account GRANT PROXY ON 'a' TO 'd' WITH GRANT OPTION; -- grant PROXY to default proxy account GRANT PROXY ON 'a' TO ''@'';
        The PROXY privilege can be
        granted in these cases:
      
            By a user that has GRANT PROXY ... WITH GRANT
            OPTION for
            proxied_user.
          
            By proxied_user for itself: The
            value of USER() must exactly
            match CURRENT_USER() and
            proxied_user, for both the user
            name and host name parts of the account name.
          
        The initial root account created during MySQL
        installation has the
        PROXY ... WITH GRANT
        OPTION privilege for ''@'', that
        is, for all users and all hosts. This enables
        root to set up proxy users, as well as to
        delegate to other accounts the authority to set up proxy users.
        For example, root can do this:
      
CREATE USER 'admin'@'localhost'
  IDENTIFIED BY 'admin_password';
GRANT PROXY
  ON ''@''
  TO 'admin'@'localhost'
  WITH GRANT OPTION;
        Those statements create an admin user that
        can manage all GRANT PROXY mappings. For
        example, admin can do this:
      
GRANT PROXY ON sally TO joe;
        To specify that some or all users should connect using a given
        authentication plugin, create a “blank” MySQL
        account with an empty user name and host name
        (''@''), associate it with that plugin, and
        let the plugin return the real authenticated user name (if
        different from the blank user). Suppose that there exists a
        plugin named ldap_auth that implements LDAP
        authentication and maps connecting users onto either a developer
        or manager account. To set up proxying of users onto these
        accounts, use the following statements:
      
-- create default proxy account CREATE USER ''@'' IDENTIFIED WITH ldap_auth AS 'O=Oracle, OU=MySQL'; -- create proxied accounts; use -- mysql_no_login plugin to prevent direct login CREATE USER 'developer'@'localhost' IDENTIFIED WITH mysql_no_login; CREATE USER 'manager'@'localhost' IDENTIFIED WITH mysql_no_login; -- grant to default proxy account the -- PROXY privilege for proxied accounts GRANT PROXY ON 'manager'@'localhost' TO ''@''; GRANT PROXY ON 'developer'@'localhost' TO ''@'';
Now assume that a client connects as follows:
$>mysql --user=myuser --password ...Enter password:myuser_password
        The server does not find myuser defined as a
        MySQL user, but because there is a blank user account
        (''@'') that matches the client user name and
        host name, the server authenticates the client against that
        account. The server invokes the ldap_auth
        authentication plugin and passes myuser and
        myuser_password to it as the user
        name and password.
      
        If the ldap_auth plugin finds in the LDAP
        directory that myuser_password is not
        the correct password for myuser,
        authentication fails and the server rejects the connection.
      
        If the password is correct and ldap_auth
        finds that myuser is a developer, it returns
        the user name developer to the MySQL server,
        rather than myuser. Returning a user name
        different from the client user name of myuser
        signals to the server that it should treat
        myuser as a proxy. The server verifies that
        ''@'' can authenticate as
        developer (because ''@''
        has the PROXY privilege to do so)
        and accepts the connection. The session proceeds with
        myuser having the privileges of the
        developer proxied user. (These privileges
        should be set up by the DBA using
        GRANT statements, not shown.) The
        USER() and
        CURRENT_USER() functions return
        these values:
      
mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER()           | CURRENT_USER()      |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+
        If the plugin instead finds in the LDAP directory that
        myuser is a manager, it returns
        manager as the user name and the session
        proceeds with myuser having the privileges of
        the manager proxied user.
      
mysql> SELECT USER(), CURRENT_USER();
+------------------+-------------------+
| USER()           | CURRENT_USER()    |
+------------------+-------------------+
| myuser@localhost | manager@localhost |
+------------------+-------------------+
        For simplicity, external authentication cannot be multilevel:
        Neither the credentials for developer nor
        those for manager are taken into account in
        the preceding example. However, they are still used if a client
        tries to connect and authenticate directly as the
        developer or manager
        account, which is why those proxied accounts should be protected
        against direct login (see
        Preventing Direct Login to Proxied Accounts).
      
If you intend to create a default proxy user, check for other existing “match any user” accounts that take precedence over the default proxy user because they can prevent that user from working as intended.
        In the preceding discussion, the default proxy user account has
        '' in the host part, which matches any host.
        If you set up a default proxy user, take care to also check
        whether nonproxy accounts exist with the same user part and
        '%' in the host part, because
        '%' also matches any host, but has precedence
        over '' by the rules that the server uses to
        sort account rows internally (see
        Section 8.2.6, “Access Control, Stage 1: Connection Verification”).
      
Suppose that a MySQL installation includes these two accounts:
-- create default proxy account CREATE USER ''@'' IDENTIFIED WITH some_plugin AS 'some_auth_string'; -- create anonymous account CREATE USER ''@'%' IDENTIFIED BY 'anon_user_password';
        The first account (''@'') is intended as the
        default proxy user, used to authenticate connections for users
        who do not otherwise match a more-specific account. The second
        account (''@'%') is an anonymous-user
        account, which might have been created, for example, to enable
        users without their own account to connect anonymously.
      
        Both accounts have the same user part (''),
        which matches any user. And each account has a host part that
        matches any host. Nevertheless, there is a priority in account
        matching for connection attempts because the matching rules sort
        a host of '%' ahead of ''.
        For accounts that do not match any more-specific account, the
        server attempts to authenticate them against
        ''@'%' (the anonymous user) rather than
        ''@'' (the default proxy user). As a result,
        the default proxy account is never used.
      
To avoid this problem, use one of the following strategies:
Remove the anonymous account so that it does not conflict with the default proxy user.
            Use a more-specific default proxy user that matches ahead of
            the anonymous user. For example, to permit only
            localhost proxy connections, use
            ''@'localhost':
          
CREATE USER ''@'localhost'
  IDENTIFIED WITH some_plugin
  AS 'some_auth_string';
            In addition, modify any GRANT PROXY
            statements to name ''@'localhost' rather
            than ''@'' as the proxy user.
          
            Be aware that this strategy prevents anonymous-user
            connections from localhost.
          
            Use a named default account rather than an anonymous default
            account. For an example of this technique, consult the
            instructions for using the
            authentication_windows plugin. See
            Section 8.4.1.6, “Windows Pluggable Authentication”.
          
Create multiple proxy users, one for local connections and one for “everything else” (remote connections). This can be useful particularly when local users should have different privileges from remote users.
Create the proxy users:
-- create proxy user for local connections CREATE USER ''@'localhost' IDENTIFIED WITH some_plugin AS 'some_auth_string'; -- create proxy user for remote connections CREATE USER ''@'%' IDENTIFIED WITH some_plugin AS 'some_auth_string';
Create the proxied users:
-- create proxied user for local connections CREATE USER 'developer'@'localhost' IDENTIFIED WITH mysql_no_login; -- create proxied user for remote connections CREATE USER 'developer'@'%' IDENTIFIED WITH mysql_no_login;
            Grant to each proxy account the
            PROXY privilege for the
            corresponding proxied account:
          
GRANT PROXY ON 'developer'@'localhost' TO ''@'localhost'; GRANT PROXY ON 'developer'@'%' TO ''@'%';
Finally, grant appropriate privileges to the local and remote proxied users (not shown).
            Assume that the
            some_plugin/'
            combination causes some_auth_string'some_plugin to map the
            client user name to developer. Local
            connections match the ''@'localhost'
            proxy user, which maps to the
            'developer'@'localhost' proxied user.
            Remote connections match the ''@'%' proxy
            user, which maps to the 'developer'@'%'
            proxied user.
          
        Some authentication plugins implement proxy user mapping for
        themselves (for example, the PAM and Windows authentication
        plugins). Other authentication plugins do not support proxy
        users by default. Of these, some can request that the MySQL
        server itself map proxy users according to granted proxy
        privileges: mysql_native_password
        (deprecated), sha256_password (deprecated).
        If the check_proxy_users system
        variable is enabled, the server performs proxy user mapping for
        any authentication plugins that make such a request:
      
            By default,
            check_proxy_users is
            disabled, so the server performs no proxy user mapping even
            for authentication plugins that request server support for
            proxy users.
          
            If check_proxy_users is
            enabled, it may also be necessary to enable a
            plugin-specific system variable to take advantage of server
            proxy user mapping support:
          
                For the deprecated
                mysql_native_password plugin, enable
                mysql_native_password_proxy_users.
              
                For the deprecated sha256_password
                plugin, enable
                sha256_password_proxy_users.
              
        For example, to enable all the preceding capabilities, start the
        server with these lines in the my.cnf file:
      
[mysqld] check_proxy_users=ON mysql_native_password_proxy_users=ON sha256_password_proxy_users=ON
        Assuming that the relevant system variables have been enabled,
        create the proxy user as usual using CREATE
        USER, then grant it the
        PROXY privilege to a single other
        account to be treated as the proxied user. When the server
        receives a successful connection request for the proxy user, it
        finds that the user has the PROXY
        privilege and uses it to determine the proper proxied user.
      
-- create proxy account
CREATE USER 'proxy_user'@'localhost'
  IDENTIFIED WITH mysql_native_password
  BY 'password';
-- create proxied account and grant its privileges;
-- use mysql_no_login plugin to prevent direct login
CREATE USER 'proxied_user'@'localhost'
  IDENTIFIED WITH mysql_no_login;
-- grant privileges to proxied account
GRANT ...
  ON ...
  TO 'proxied_user'@'localhost';
-- grant to proxy account the
-- PROXY privilege for proxied account
GRANT PROXY
  ON 'proxied_user'@'localhost'
  TO 'proxy_user'@'localhost';
To use the proxy account, connect to the server using its name and password:
$>mysql -u proxy_user -pEnter password:(enter proxy_user password here)
        Authentication succeeds, the server finds that
        proxy_user has the
        PROXY privilege for
        proxied_user, and the session proceeds with
        proxy_user having the privileges of
        proxied_user.
      
Proxy user mapping performed by the server is subject to these restrictions:
            The server does not proxy to or from an anonymous user, even
            if the associated PROXY
            privilege is granted.
          
When a single account has been granted proxy privileges for more than one proxied account, server proxy user mapping is nondeterministic. Therefore, granting to a single account proxy privileges for multiple proxied accounts is discouraged.
Two system variables help trace the proxy login process:
            proxy_user: This value is
            NULL if proxying is not used. Otherwise,
            it indicates the proxy user account. For example, if a
            client authenticates through the ''@''
            proxy account, this variable is set as follows:
          
mysql> SELECT @@proxy_user;
+--------------+
| @@proxy_user |
+--------------+
| ''@''        |
+--------------+
            external_user: Sometimes
            the authentication plugin may use an external user to
            authenticate to the MySQL server. For example, when using
            Windows native authentication, a plugin that authenticates
            using the windows API does not need the login ID passed to
            it. However, it still uses a Windows user ID to
            authenticate. The plugin may return this external user ID
            (or the first 512 UTF-8 bytes of it) to the server using the
            external_user read-only session variable.
            If the plugin does not set this variable, its value is
            NULL.