|
| 1 | +# TiDB Security Enhanced Mode (SEM) |
| 2 | + |
| 3 | +## Overview and Purpose |
| 4 | + |
| 5 | +Security Enhanced Mode (SEM) provides a mandatory access control layer that operates on top of TiDB's standard privilege system. Its primary purpose is to limit the capabilities of all users, including the `root` user. |
| 6 | + |
| 7 | +This feature is especially critical in Database-as-a-Service (DBaaS) environments. Service providers can offer tenants `root` access to their databases—ensuring compatibility with applications—while simultaneously preventing them from executing commands that could compromise the underlying cluster's security, stability, or data isolation. |
| 8 | + |
| 9 | +You can enable SEM in two ways: a default mode with a predefined set of restrictions, or a custom mode that uses a configuration file for a highly detailed security policy. |
| 10 | + |
| 11 | +## Enabling and Configuring SEM |
| 12 | + |
| 13 | +You enable SEM by setting `security.enable-sem = true` in your TiDB server's configuration file (`tidb.toml`). The specific behavior of SEM depends on whether you also provide a configuration file. |
| 14 | + |
| 15 | +You can verify which mode is active by checking the `tidb_enable_enhanced_security` system variable. |
| 16 | + |
| 17 | +```sql |
| 18 | +SHOW VARIABLES LIKE 'tidb_enable_enhanced_security'; |
| 19 | +``` |
| 20 | + |
| 21 | +### Mode 1: Default Restrictions |
| 22 | + |
| 23 | +This mode provides a baseline set of security enhancements that primarily reduce the broad power of the `SUPER` privilege, replacing it with fine-grained privileges. |
| 24 | + |
| 25 | + * Activation: Set `enable-sem = true` in `tidb.toml` without setting the `sem-config` path. |
| 26 | + * System Variable: `tidb_enable_enhanced_security` will be `ON`. |
| 27 | + |
| 28 | +In this mode, TiDB enforces the following restrictions: |
| 29 | + |
| 30 | +| Restricted Action | Required Privilege for Exemption | |
| 31 | +| :------------------------------------------------------------------------------------------------------------ | :------------------------------- | |
| 32 | +| Writing data to system tables in the `mysql` schema and viewing sensitive columns in `information_schema` tables. | `RESTRICTED_TABLES_ADMIN` | |
| 33 | +| Viewing sensitive variables in `SHOW STATUS`. | `RESTRICTED_STATUS_ADMIN` | |
| 34 | +| Viewing and setting sensitive system variables. | `RESTRICTED_VARIABLES_ADMIN` | |
| 35 | +| Dropping or modifying a user account that holds the `RESTRICTED_USER_ADMIN` privilege. | `RESTRICTED_USER_ADMIN` | |
| 36 | + |
| 37 | +### Mode 2: Custom Restrictions via Configuration File |
| 38 | + |
| 39 | +This mode enables a fully customizable security policy defined in a JSON file. It offers granular control over tables, variables, privileges, and SQL commands. |
| 40 | + |
| 41 | + * Activation: Set both `enable-sem = true` and `sem-config = '/path/to/your/sem-policy.json'` in `tidb.toml`. |
| 42 | + * System Variable: `tidb_enable_enhanced_security` will be `CONFIG`. |
| 43 | + |
| 44 | +You must restart your TiDB cluster for any configuration changes to take effect. |
| 45 | + |
| 46 | +## Custom Policy Feature Reference (Mode 2) |
| 47 | + |
| 48 | +The following sections detail the features available when using a custom configuration file (Mode 2). |
| 49 | + |
| 50 | +### Restricting Access to Tables and Databases |
| 51 | + |
| 52 | +This feature prevents access to specified databases or individual tables. |
| 53 | + |
| 54 | + * Configuration: |
| 55 | + * `restricted_databases`: An array of database names. All tables within these databases become inaccessible. |
| 56 | + * `restricted_tables`: An array of objects specifying a `schema` and `name`. The optional `"hidden": true` flag makes the table invisible. |
| 57 | + * Exemption Privilege: `RESTRICTED_TABLES_ADMIN` |
| 58 | + * Configuration Example: |
| 59 | + ```json |
| 60 | + { |
| 61 | + "version": "1", "tidb_version": "9.0.0", |
| 62 | + "restricted_databases": ["mysql"], |
| 63 | + "restricted_tables": [{"schema": "information_schema", "name": "columns", "hidden": true}] |
| 64 | + } |
| 65 | + ``` |
| 66 | + As a restricted user (e.g., `root`): |
| 67 | + ``` |
| 68 | + mysql> select * from information_schema.columns; |
| 69 | + ERROR 1142 (42000): SELECT command denied to user 'root'@'%' for table 'columns' |
| 70 | + mysql> use mysql; |
| 71 | + ERROR 1044 (42000): Access denied for user 'root'@'%' to database 'mysql' |
| 72 | + ``` |
| 73 | + |
| 74 | +### Restricting System Variables |
| 75 | + |
| 76 | +This feature controls interaction with system variables by hiding them, making them read-only, or masking their values. |
| 77 | + |
| 78 | + * Configuration: The `restricted_variables` key contains an array of variable objects with a control flag: |
| 79 | + * `"hidden": true`: The variable is inaccessible. |
| 80 | + * `"readonly": true`: The variable can be read but not modified. |
| 81 | + * `"value": "string"`: Overrides the variable's return value. Note: This option is only supported for local read-only variables. |
| 82 | + * Exemption Privilege: `RESTRICTED_VARIABLES_ADMIN` |
| 83 | + * Configuration Example: |
| 84 | + ```json |
| 85 | + { |
| 86 | + "version": "1", "tidb_version": "9.0.0", |
| 87 | + "restricted_variables": [ |
| 88 | + {"name": "tidb_config", "hidden": true}, |
| 89 | + {"name": "hostname", "hidden": false, "value": "testhostname"} |
| 90 | + ] |
| 91 | + } |
| 92 | + ``` |
| 93 | + As a restricted user (e.g., `root`): |
| 94 | + ``` |
| 95 | + mysql> SELECT @@tidb_config; |
| 96 | + ERROR 1227 (42000): Access denied; you need (at least one of) the RESTRICTED_VARIABLES_ADMIN privilege(s) for this operation |
| 97 | + mysql> SELECT @@hostname; |
| 98 | + +--------------+ |
| 99 | + | @@hostname | |
| 100 | + +--------------+ |
| 101 | + | testhostname | |
| 102 | + +--------------+ |
| 103 | + 1 row in set (0.00 sec) |
| 104 | + ``` |
| 105 | + |
| 106 | +### Restricting Privileges and User Management |
| 107 | + |
| 108 | +This feature prevents powerful privileges from being granted and protects administrative accounts from being altered or dropped. |
| 109 | + |
| 110 | + * Configuration: The `restricted_privileges` key contains an array of privilege names. Once listed, a privilege cannot be granted. Listing `RESTRICTED_USER_ADMIN` itself protects users who hold that privilege. |
| 111 | + * Exemption Privilege: `RESTRICTED_PRIV_ADMIN` |
| 112 | + * Configuration Example: |
| 113 | + ```json |
| 114 | + { |
| 115 | + "version": "1", "tidb_version": "9.0.0", |
| 116 | + "restricted_privileges": ["FILE"] |
| 117 | + } |
| 118 | + ``` |
| 119 | + As a restricted user (e.g., `root`): |
| 120 | + ``` |
| 121 | + mysql> GRANT FILE ON *.* TO 'some_user'@'%'; |
| 122 | + ERROR 1227 (42000): Access denied; you need (at least one of) the RESTRICTED_PRIV_ADMIN privilege(s) for this operation |
| 123 | + -- Assuming 'sem_admin' has the RESTRICTED_USER_ADMIN privilege, attempt to drop the user |
| 124 | + mysql> DROP USER 'sem_admin'@'%'; |
| 125 | + ERROR 1227 (42000): Access denied; you need (at least one of) the RESTRICTED_USER_ADMIN privilege(s) for this operation |
| 126 | + ``` |
| 127 | + |
| 128 | +### Restricting Status Variables |
| 129 | + |
| 130 | +This feature filters sensitive operational data from the output of `SHOW STATUS`. |
| 131 | + |
| 132 | + * Configuration: |
| 133 | + * `restricted_status_variables`: An array of status variable names to hide from `SHOW STATUS`. |
| 134 | + * Exemption Privilege: `RESTRICTED_STATUS_ADMIN` |
| 135 | + * Configuration Example: |
| 136 | + ```json |
| 137 | + { |
| 138 | + "version": "1", "tidb_version": "9.0.0", |
| 139 | + "restricted_status_variables": ["tidb_gc_leader_desc"] |
| 140 | + } |
| 141 | + ``` |
| 142 | + As a restricted user (e.g., `root`): |
| 143 | + ``` |
| 144 | + mysql> SHOW STATUS LIKE 'tidb_gc_leader_desc'; |
| 145 | + Empty set (0.01 sec) |
| 146 | + ``` |
| 147 | + |
| 148 | +### Restricting SQL Commands |
| 149 | + |
| 150 | +This feature blocks the execution of specific SQL statements or entire classes of commands. |
| 151 | + |
| 152 | + * Configuration: |
| 153 | + * `restricted_sql`: An object containing two arrays: |
| 154 | + * `sql`: A list of specific SQL commands to block (e.g., `BACKUP`, `RESTORE`). |
| 155 | + * `rule`: A list of predefined rule names that block specific classes of statements. Supported rules are: |
| 156 | + * `time_to_live`: Blocks DDL statements related to Table TTL. |
| 157 | + * `alter_table_attributes`: Blocks the `ALTER TABLE ... ATTRIBUTES="..."` statement. |
| 158 | + * `import_with_external_id`: Blocks `IMPORT INTO` statements that use an S3 `EXTERNAL_ID`. |
| 159 | + * `select_into_file`: Blocks `SELECT ... INTO OUTFILE` statements. |
| 160 | + * `import_from_local`: Blocks `LOAD DATA LOCAL INFILE` and `IMPORT INTO` from a local file path. |
| 161 | + * Exemption Privilege: `RESTRICTED_SQL_ADMIN` |
| 162 | + * Configuration Example: |
| 163 | + ```json |
| 164 | + { |
| 165 | + "version": "1", "tidb_version": "9.0.0", |
| 166 | + "restricted_sql": { |
| 167 | + "rule": ["time_to_live"], |
| 168 | + "sql": ["BACKUP"] |
| 169 | + } |
| 170 | + } |
| 171 | + ``` |
| 172 | + As a restricted user (e.g., `root`): |
| 173 | + ``` |
| 174 | + mysql> BACKUP DATABASE `test` TO 's3://bucket/backup'; |
| 175 | + ERROR 8132 (HY000): Feature 'BACKUP DATABASE `test` TO 's3://bucket/backup'' is not supported when security enhanced mode is enabled |
| 176 | + mysql> CREATE TABLE test.t1 (id INT, created_at TIMESTAMP) TTL = `created_at` + INTERVAL 1 DAY; |
| 177 | + ERROR 8132 (HY000): Feature 'CREATE TABLE test.t1 (id INT, created_at TIMESTAMP) TTL = `created_at` + INTERVAL 1 DAY' is not supported when security enhanced mode is enabled |
| 178 | + ``` |
0 commit comments