Skip to content

Commit f8b9d7d

Browse files
authored
Add description for tidb_auth_token authentication (#15979) (#16655)
1 parent 557e1c2 commit f8b9d7d

6 files changed

+136
-14
lines changed

basic-features.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ You can try out TiDB features on [TiDB Playground](https://play.tidbcloud.com/?u
181181
| [Certificate-based authentication](/certificate-authentication.md) | Y | Y | Y | Y | Y | Y | Y | Y | Y |
182182
| [`caching_sha2_password` authentication](/system-variables.md#default_authentication_plugin) | Y | Y | Y | Y | Y | Y | N | N | N |
183183
| [`tidb_sm3_password` authentication](/system-variables.md#default_authentication_plugin) | Y | Y | N | N | N | N | N | N | N |
184-
| [`tidb_auth_token` authentication](/system-variables.md#default_authentication_plugin) | Y | Y | N | N | N | N | N | N | N |
184+
| [`tidb_auth_token` authentication](/security-compatibility-with-mysql.md#tidb_auth_token) | Y | Y | N | N | N | N | N | N | N |
185185
| [`authentication_ldap_sasl` authentication](/system-variables.md#default_authentication_plugin) | Y | N | N | N | N | N | N | N | N |
186186
| [`authentication_ldap_simple` authentication](/system-variables.md#default_authentication_plugin) | Y | N | N | N | N | N | N | N | N |
187187
| [Password management](/password-management.md) | Y | Y | N | N | N | N | N | N | N |

security-compatibility-with-mysql.md

+121-2
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ The implementation mechanisms are consistent between TiDB and MySQL. Both use th
107107

108108
## Authentication plugin status
109109

110-
TiDB supports multiple authentication methods. These methods can be specified on a per user basis using [`CREATE USER`](/sql-statements/sql-statement-create-user.md) and [`ALTER USER`](/sql-statements/sql-statement-create-user.md). These methods are compatible with the authentication methods of MySQL with the same names.
110+
TiDB supports multiple authentication methods. These methods can be specified on a per user basis using [`CREATE USER`](/sql-statements/sql-statement-create-user.md) and [`ALTER USER`](/sql-statements/sql-statement-alter-user.md). These methods are compatible with the authentication methods of MySQL with the same names.
111111

112-
You can use one of the following supported authentication methods in the table. To specify a default method that the server advertises when the client-server connection is being established, set the [`default_authentication_plugin`](/system-variables.md#default_authentication_plugin) variable. `tidb_sm3_password` is the SM3 authentication method only supported in TiDB. Therefore, to authenticate using this method, you must connect to TiDB using [TiDB-JDBC](https://github.com/pingcap/mysql-connector-j/tree/release/8.0-sm3). `tidb_auth_token` is a JSON Web Token (JWT) based authentication method used only in TiDB Cloud.
112+
You can use one of the following supported authentication methods in the table. To specify a default method that the server advertises when the client-server connection is being established, set the [`default_authentication_plugin`](/system-variables.md#default_authentication_plugin) variable. `tidb_sm3_password` is the SM3 authentication method only supported in TiDB. Therefore, to authenticate using this method, you must connect to TiDB using [TiDB-JDBC](https://github.com/pingcap/mysql-connector-j/tree/release/8.0-sm3). `tidb_auth_token` is a JSON Web Token (JWT)-based authentication method used in TiDB Cloud, and you can also configure it for use in TiDB Self-Hosted.
113113

114114
<CustomContent platform="tidb">
115115

@@ -139,3 +139,122 @@ The support for TLS authentication is configured differently. For detailed infor
139139
| ed25519 (MariaDB) | No |
140140
| GSSAPI (MariaDB) | No |
141141
| FIDO | No |
142+
143+
### `tidb_auth_token`
144+
145+
`tidb_auth_token` is a passwordless authentication method based on [JSON Web Token (JWT)](https://datatracker.ietf.org/doc/html/rfc7519). In v6.4.0, `tidb_auth_token` is only used for user authentication in TiDB Cloud. Starting from v6.5.0, you can also configure `tidb_auth_token` as a user authentication method for TiDB Self-Hosted. Different from password-based authentication methods such as `mysql_native_passsword` and `caching_sha2_password`, when you create users using `tidb_auth_token`, there is no need to set or store custom passwords. To log into TiDB, users only need to use a signed token instead of a password, which simplifies the authentication process and improves security.
146+
147+
#### JWT
148+
149+
JWT consists of three parts: Header, Payload, and Signature. After being encoded using base64, they are concatenated into a string separated by dots (`.`) for transmission between the client and server.
150+
151+
The Header describes the metadata of the JWT, including 3 parameters:
152+
153+
* `alg`: the algorithm for signature, which is `RS256` by default.
154+
* `typ`: the type of token, which is `JWT`.
155+
* `kid`: the key ID for generating token signature.
156+
157+
Here is an example for Header:
158+
159+
```json
160+
{
161+
"alg": "RS256",
162+
"kid": "the-key-id-0",
163+
"typ": "JWT"
164+
}
165+
```
166+
167+
Payload is the main part of JWT, which stores the user information. Each field in the Payload is called a claim. The claims required for TiDB user authentication are as follows:
168+
169+
* `iss`: if `TOKEN_ISSUER` is not specified or set to empty when [`CREATE USER`](/sql-statements/sql-statement-create-user.md), this claim is not required; otherwise, `iss` should use the same value as `TOKEN_ISSUER`.
170+
* `sub`: this claim is required to be the same as the username to be authenticated.
171+
* `iat`: it means `issued at`, the timestamp when the token is issued. In TiDB, this value must not be later than the authentication time or earlier than 15 minutes before authentication.
172+
* `exp`: the timestamp when the token expires. If it is earlier than the time of authentication, the authentication fails.
173+
* `email`: the email can be specified when creating a user by `ATTRIBUTE '{"email": "[email protected]"}`. If no email is specified when a user is created, this claim must be set as an empty string; otherwise, this claim must be the same as the specified value when the user is created.
174+
175+
Here is an example for Payload:
176+
177+
```json
178+
{
179+
"email": "[email protected]",
180+
"exp": 1703305494,
181+
"iat": 1703304594,
182+
"iss": "issuer-abc",
183+
184+
}
185+
```
186+
187+
Signature is used to sign the Header and Payload data.
188+
189+
> **Warning:**
190+
>
191+
> - The encoding of the Header and Payload in base64 is reversible. Do **Not** attach any sensitive information to them.
192+
> - The `tidb_auth_token` authentication method requires clients to support the [`mysql_clear_password`](https://dev.mysql.com/doc/refman/8.0/en/cleartext-pluggable-authentication.html) plugin to send the token to TiDB in plain text. Therefore, you need to [enale TLS between clients and servers](/enable-tls-between-clients-and-servers.md) before using `tidb_auth_token`.
193+
194+
#### Usage
195+
196+
To configure and use `tidb_auth_token` as the authentication method for TiDB Self-Hosted users, take the following steps:
197+
198+
1. Configure [`auth-token-jwks`](/tidb-configuration-file.md#auth-token-jwks-new-in-v640) and [`auth-token-refresh-interval`](/tidb-configuration-file.md#auth-token-refresh-interval-new-in-v640) in the TiDB configuration file.
199+
200+
For example, you can get an example JWKS using the following command:
201+
202+
```bash
203+
wget https://raw.githubusercontent.com/CbcWestwolf/generate_jwt/master/JWKS.json
204+
```
205+
206+
Then, configure the path of the example JWKS in `config.toml`:
207+
208+
```toml
209+
[security]
210+
auth-token-jwks = "JWKS.json"
211+
```
212+
213+
2. Start `tidb-server` and periodically update and save the JWKS to the path specified by `auth-token-jwks`.
214+
215+
3. Create a user with `tidb_auth_token`, and specify `iss` and `email` as needed using `REQUIRE TOKEN_ISSUER` and `ATTRIBUTE '{"email": "[email protected]"}`.
216+
217+
For example, create a user `[email protected]` with `tidb_auth_token`:
218+
219+
```sql
220+
CREATE USER '[email protected]' IDENTIFIED WITH 'tidb_auth_token' REQUIRE TOKEN_ISSUER 'issuer-abc' ATTRIBUTE '{"email": "[email protected]"}';
221+
```
222+
223+
4. Generate and sign a token for authentication, and authenticate using the `mysql_clear_text` plugin of the MySQL client.
224+
225+
Install the JWT generation tool via `go install github.com/cbcwestwolf/generate_jwt` (this tool is only used for testing `tidb_auth_token`). For example:
226+
227+
```text
228+
generate_jwt --kid "the-key-id-0" --sub "[email protected]" --email "[email protected]" --iss "issuer-abc"
229+
```
230+
231+
It prints the public key and token as follows:
232+
233+
```text
234+
-----BEGIN PUBLIC KEY-----
235+
MIIBCgKCAQEAq8G5n9XBidxmBMVJKLOBsmdOHrCqGf17y9+VUXingwDUZxRp2Xbu
236+
LZLbJtLgcln1lC0L9BsogrWf7+pDhAzWovO6Ai4Aybu00tJ2u0g4j1aLiDdsy0gy
237+
vSb5FBoL08jFIH7t/JzMt4JpF487AjzvITwZZcnsrB9a9sdn2E5B/aZmpDGi2+Is
238+
f5osnlw0zvveTwiMo9ba416VIzjntAVEvqMFHK7vyHqXbfqUPAyhjLO+iee99Tg5
239+
AlGfjo1s6FjeML4xX7sAMGEy8FVBWNfpRU7ryTWoSn2adzyA/FVmtBvJNQBCMrrA
240+
hXDTMJ5FNi8zHhvzyBKHU0kBTS1UNUbP9wIDAQAB
241+
-----END PUBLIC KEY-----
242+
243+
eyJhbGciOiJSUzI1NiIsImtpZCI6InRoZS1rZXktaWQtMCIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InVzZXJAcGluZ2NhcC5jb20iLCJleHAiOjE3MDMzMDU0OTQsImlhdCI6MTcwMzMwNDU5NCwiaXNzIjoiaXNzdWVyLWFiYyIsInN1YiI6InVzZXJAcGluZ2NhcC5jb20ifQ.T4QPh2hTB5on5xCuvtWiZiDTuuKvckggNHtNaovm1F4RvwUv15GyOqj9yMstE-wSoV5eLEcPC2HgE6eN1C6yH_f4CU-A6n3dm9F1w-oLbjts7aYCl8OHycVYnq609fNnb8JLsQAmd1Zn9C0JW899-WSOQtvjLqVSPe9prH-cWaBVDQXzUJKxwywQzk9v-Z1Njt9H3Rn9vvwwJEEPI16VnaNK38I7YG-1LN4fAG9jZ6Zwvz7vb_s4TW7xccFf3dIhWTEwOQ5jDPCeYkwraRXU8NC6DPF_duSrYJc7d7Nu9Z2cr-E4i1Rt_IiRTuIIzzKlcQGg7jd9AGEfGe_SowsA-w
244+
```
245+
246+
Copy the preceding token in the last line for login:
247+
248+
```Shell
249+
mycli -h 127.0.0.1 -P 4000 -u '[email protected]' -p '<the-token-generated>'
250+
```
251+
252+
Ensure that the MySQL client here supports the `mysql_clear_password` plugin. [mycli](https://www.mycli.net/) supports and enables this plugin by default. If you are using the [mysql command-line client](https://dev.mysql.com/doc/refman/8.0/en/mysql.html), you need to use the `--enable-cleartext-plugin` option to enable this plugin:
253+
254+
```Shell
255+
mysql -h 127.0.0.1 -P 4000 -u '[email protected]' -p'<the-token-generated>' --enable-cleartext-plugin
256+
```
257+
258+
If an incorrect `--sub` is specified when the token is generated (such as `--sub "[email protected]"`), the authentication using this token would fail.
259+
260+
You can encode and decode a token using the debugger provided by [jwt.io](https://jwt.io/).

sql-statements/sql-statement-alter-user.md

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ UserSpecList ::=
1919
UserSpec ::=
2020
Username AuthOption
2121
22+
RequireClauseOpt ::=
23+
( 'REQUIRE' 'NONE' | 'REQUIRE' 'SSL' | 'REQUIRE' 'X509' | 'REQUIRE' RequireList )?
24+
25+
RequireList ::=
26+
( "ISSUER" stringLit | "SUBJECT" stringLit | "CIPHER" stringLit | "SAN" stringLit | "TOKEN_ISSUER" stringLit )*
27+
2228
Username ::=
2329
StringName ('@' StringName | singleAtIdentifier)? | 'CURRENT_USER' OptionalBraces
2430

sql-statements/sql-statement-create-user.md

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ IfNotExists ::=
1919
UserSpecList ::=
2020
UserSpec ( ',' UserSpec )*
2121
22+
RequireClauseOpt ::=
23+
( 'REQUIRE' 'NONE' | 'REQUIRE' 'SSL' | 'REQUIRE' 'X509' | 'REQUIRE' RequireList )?
24+
25+
RequireList ::=
26+
( "ISSUER" stringLit | "SUBJECT" stringLit | "CIPHER" stringLit | "SAN" stringLit | "TOKEN_ISSUER" stringLit )*
27+
2228
UserSpec ::=
2329
Username AuthOption
2430

system-variables.md

-1
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,6 @@ mysql> SELECT * FROM t1;
397397
- Type: Enumeration
398398
- Default value: `mysql_native_password`
399399
- Possible values: `mysql_native_password`, `caching_sha2_password`, `tidb_sm3_password`, `tidb_auth_token`, `authentication_ldap_sasl`, and `authentication_ldap_simple`.
400-
- The `tidb_auth_token` authentication method is used only for the internal operation of TiDB Cloud. **DO NOT** set the variable to this value.
401400
- This variable sets the authentication method that the server advertises when the server-client connection is being established.
402401
- To authenticate using the `tidb_sm3_password` method, you can connect to TiDB using [TiDB-JDBC](https://github.com/pingcap/mysql-connector-j/tree/release/8.0-sm3).
403402

tidb-configuration-file.md

+2-10
Original file line numberDiff line numberDiff line change
@@ -401,20 +401,12 @@ Configuration items related to security.
401401

402402
### `auth-token-jwks` <span class="version-mark">New in v6.4.0</span>
403403

404-
> **Warning:**
405-
>
406-
> The `tidb_auth_token` authentication method is used only for the internal operation of TiDB Cloud. **DO NOT** change the value of this configuration.
407-
408-
- Set the local file path of the JSON Web Key Sets (JWKS) for the `tidb_auth_token` authentication method.
404+
- Set the local file path of the JSON Web Key Sets (JWKS) for the [`tidb_auth_token`](/security-compatibility-with-mysql.md#tidb_auth_token) authentication method.
409405
- Default value: `""`
410406

411407
### `auth-token-refresh-interval` <span class="version-mark">New in v6.4.0</span>
412408

413-
> **Warning:**
414-
>
415-
> The `tidb_auth_token` authentication method is used only for the internal operation of TiDB Cloud. **DO NOT** change the value of this configuration.
416-
417-
- Set the JWKS refresh interval for the `tidb_auth_token` authentication method.
409+
- Set the JWKS refresh interval for the [`tidb_auth_token`](/security-compatibility-with-mysql.md#tidb_auth_token) authentication method.
418410
- Default value: `1h`
419411

420412
### `disconnect-on-expired-password` <span class="version-mark">New in v6.5.0</span>

0 commit comments

Comments
 (0)