User Management and Authentication
Vitess uses its own mechanism for managing users and their permissions through
VTGate. As a result, the CREATE USER....
and
GRANT...
statements will not work if sent through VTGate.
Authentication #
The Vitess VTGate component takes care of authentication for requests so we will need to add any users that should have access to the Keyspaces via the command-line options to VTGate.
The simplest way to configure users is using a static
auth method and we
can define the users in a JSON formatted file or string.
$ cat > users.json << EOF
{
"vitess": [
{
"UserData": "vitess",
"Password": "supersecretpassword"
}
],
"myuser1": [
{
"UserData": "myuser1",
"Password": "password1"
}
],
"myuser2": [
{
"UserData": "myuser2",
"Password": "password2"
}
]
}
EOF
Then we can load this into VTGate with the additional commandline parameters:
vtgate $(cat <<END_OF_COMMAND
--mysql_auth_server_impl=static
--mysql_auth_server_static_file=users.json
...
...
...
END_OF_COMMAND
)
Now we can test our new users:
$ mysql -h 127.0.0.1 -u myuser1 -ppassword1 -e "select 1"
+---+
| 1 |
+---+
| 1 |
+---+
$ mysql -h 127.0.0.1 -u myuser1 -pincorrect_password -e "select 1"
ERROR 1045 (28000): Access denied for user 'myuser1'
Password format #
In the above example we used plaintext passwords. Vitess supports the MySQL mysql_native_password hash format, and you should always specify your passwords using this in a non-test or external environment. Vitess does not yet support the caching_sha2_password format that became the default for MySQL in 8.0.
To use a mysql_native_password
hash, your user section in your static
JSON authentication file would look something like this instead:
{
"vitess": [
{
"UserData": "vitess",
"MysqlNativePassword": "*9E128DA0C64A6FCCCDCFBDD0FC0A2C967C6DB36F"
}
]
}
You can extract a mysql_native_password
hash from an existing MySQL
install by looking at the authentication_string
column of the relevant
user's row in the mysql.user
table. An alternate way to generate this
hash is to SHA1 the cleartext password string twice, e.g. doing it in
MySQL for the cleartext password password
:
mysql> SELECT UPPER(SHA1(UNHEX(SHA1("password")))) as hash;
+------------------------------------------+
| hash |
+------------------------------------------+
| 2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
+------------------------------------------+
1 row in set (0.01 sec)
So, you would use *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19
as the
MysqlNativePassword
hash value for the cleartext password password
.
UserData #
In the static authentication JSON file, the UserData
string is not
the username; the username is the string key for the list. The UserData
string does not need to correspond to the username, and is used by the
authorization mechanism when referring to a user. It is
usually however simpler if you make the UserData
string and the username
the same.
The UserData
feature can be leveraged to create multiple users that are
equivalent to the authorization layer (i.e. multiple users having the same
UserData
strings), but are different in the authentication layer (i.e.
have different usernames and passwords).
Multiple passwords #
A very convenient feature of the VTGate authorization is that, as can be
seen in the example JSON authentication files, you have a list of
UserData
and Password
/MysqlNativePassword
pairs associated with
a user. You can optionally leverage this to assign multiple different
passwords to a single user, and VTGate will allow a user to authenticate
with any of the defined passwords. This makes password rotation
much easier; and less likely to require or cause downtime.
An example could be:
{
"vitess": [
{
"UserData": "vitess_old",
"MysqlNativePassword": "*9E128DA0C64A6FCCCDCFBDD0FC0A2C967C6DB36F"
},
{
"UserData": "vitess_new",
"MysqlNativePassword": "*B3AD996B12F211BEA47A7C666CC136FB26DC96AF"
}
]
}
This feature also allows different UserData
strings
to be associated with a user depending on the password used. This can
be used in concert with the authorization mechanism to
migrate an application gracefully from one set of ACLs (or no ACLs)
to another set of ACLs, by just changing the password used by the
application.
In the example above, the username vitess
has two different passwords
that would be allowed, each resulting in different UserData
strings
(vitess_old
or vitess_new
) being passed to the VTTablet layer that can
be used for authorization/ACL enforcement.
Other authentication methods #
Other than the static authentication file method above, other authentication mechanisms are also provided:
- LDAP-based authentication
- TLS client certificate-based authentication