ロールベースアクセス制御
TiDB のロールベースアクセス制御 (RBAC) システムの実装は、MySQL 8.0 のものと似ています。TiDB は、MySQL のほとんどの RBAC 構文と互換性があります。
このドキュメントでは、TiDB RBAC 関連の操作と実装について説明します。
RBAC操作
ロールとは、一連の権限の集合です。以下の操作を行うことができます。
- ロールを作成します。
- ロールを削除します。
- ロールに権限を付与します。
- 別のユーザーにロールを付与します。ロールを有効化すると、そのユーザーはロールに関連する権限を取得できます。
ロールを作成する
たとえば、次のステートメントを使用して、ロールapp_developer 、 app_read 、およびapp_write作成できます。
CREATE ROLE 'app_developer', 'app_read', 'app_write';
ロールの命名形式と規則については、 TiDB ユーザーアカウント管理参照してください。
ロールはmysql.userテーブルに保存され、ロール名のホスト名部分(省略されている場合)はデフォルトで'%'になります。作成しようとしているロール名は一意である必要があります。一意でない場合はエラーが報告されます。
ロールを作成するには、 CREATE ROLEまたはCREATE USER権限が必要です。
ロールに権限を付与する
ロールに権限を付与する操作は、ユーザーに権限を付与する操作と同じです。詳細はTiDB権限管理参照してください。
たとえば、次のステートメントを使用して、 app_readロールにapp_dbデータベースを読み取る権限を付与できます。
GRANT SELECT ON app_db.* TO 'app_read'@'%';
次のステートメントを使用して、 app_writeロールにapp_dbデータベースにデータを書き込む権限を付与できます。
GRANT INSERT, UPDATE, DELETE ON app_db.* TO 'app_write'@'%';
次のステートメントを使用して、 app_developerロールにapp_dbデータベースのすべての権限を付与できます。
GRANT ALL ON app_db.* TO 'app_developer';
ユーザーにロールを付与する
ユーザーdev1 app_dbに対するすべての権限を持つ開発者ロールを持ち、ユーザーread_user1とread_user2 app_dbに対する読み取り専用権限を持ち、ユーザーrw_user1 app_dbに対する読み取り権限と書き込み権限を持っているとします。
CREATE USER使用してユーザーを作成します。
CREATE USER 'dev1'@'localhost' IDENTIFIED BY 'dev1pass';
CREATE USER 'read_user1'@'localhost' IDENTIFIED BY 'read_user1pass';
CREATE USER 'read_user2'@'localhost' IDENTIFIED BY 'read_user2pass';
CREATE USER 'rw_user1'@'localhost' IDENTIFIED BY 'rw_user1pass';
次にGRANT使用してユーザーにロールを付与します
GRANT 'app_developer' TO 'dev1'@'localhost';
GRANT 'app_read' TO 'read_user1'@'localhost', 'read_user2'@'localhost';
GRANT 'app_read', 'app_write' TO 'rw_user1'@'localhost';
別のユーザーにロールを付与したり、ロールを取り消したりするには、 SUPER権限が必要です。
ユーザーにロールを付与しても、そのロールがすぐに有効になるわけではありません。ロールの有効化は別の操作です。
次の操作は「関係ループ」を形成する可能性があります。
CREATE USER 'u1', 'u2';
CREATE ROLE 'r1', 'r2';
GRANT 'u1' TO 'u1';
GRANT 'r1' TO 'r1';
GRANT 'r2' TO 'u2';
GRANT 'u2' TO 'r2';
TiDBはこの多段階の認可関係をサポートしています。これを利用して権限の継承を実装できます。
ロールの権限を確認する
SHOW GRANTSステートメントを使用して、ユーザーに付与されている権限を確認できます。
他のユーザーの権限関連情報を確認するには、 mysqlデータベースに対するSELECT権限が必要です。
SHOW GRANTS FOR 'dev1'@'localhost';
+-------------------------------------------------+
| Grants for dev1@localhost |
+-------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+-------------------------------------------------+
SHOW GRANTSのUSINGオプションを使用して、ロールの権限を確認できます。
SHOW GRANTS FOR 'dev1'@'localhost' USING 'app_developer';
+----------------------------------------------------------+
| Grants for dev1@localhost |
+----------------------------------------------------------+
| GRANT USAGE ON *.* TO `dev1`@`localhost` |
| GRANT ALL PRIVILEGES ON `app_db`.* TO `dev1`@`localhost` |
| GRANT `app_developer`@`%` TO `dev1`@`localhost` |
+----------------------------------------------------------+
SHOW GRANTS FOR 'rw_user1'@'localhost' USING 'app_read', 'app_write';
+------------------------------------------------------------------------------+
| Grants for rw_user1@localhost |
+------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `rw_user1`@`localhost` |
| GRANT SELECT, INSERT, UPDATE, DELETE ON `app_db`.* TO `rw_user1`@`localhost` |
| GRANT `app_read`@`%`,`app_write`@`%` TO `rw_user1`@`localhost` |
+------------------------------------------------------------------------------+
SHOW GRANTS FOR 'read_user1'@'localhost' USING 'app_read';
+--------------------------------------------------------+
| Grants for read_user1@localhost |
+--------------------------------------------------------+
| GRANT USAGE ON *.* TO `read_user1`@`localhost` |
| GRANT SELECT ON `app_db`.* TO `read_user1`@`localhost` |
| GRANT `app_read`@`%` TO `read_user1`@`localhost` |
+--------------------------------------------------------+
現在のユーザーの権限を確認するには、 SHOW GRANTSまたはSHOW GRANTS FOR CURRENT_USER()使用します。5 とSHOW GRANTS FOR CURRENT_USER() SHOW GRANTSの点で異なります。
SHOW GRANTS、現在のユーザーに対して有効なロールの権限を示します。SHOW GRANTS FOR CURRENT_USER()場合、有効なロールの権限は表示されません。
デフォルトロールを設定する
ロールはユーザーに付与されてもすぐには有効になりません。ユーザーがこのロールを有効化した後にのみ、そのロールが持つ権限を利用できるようになります。
ユーザーにデフォルトのロールを設定できます。ユーザーがログインすると、デフォルトのロールが自動的に有効になります。
SET DEFAULT ROLE
{NONE | ALL | role [, role ] ...}
TO user [, user ]
たとえば、次のステートメントを使用して、 rw_user1@localhost ~ app_readおよびapp_writeのデフォルト ロールを設定できます。
SET DEFAULT ROLE app_read, app_write TO 'rw_user1'@'localhost';
次のステートメントを使用して、すべてのロールにデフォルトのロールdev1@localhostを設定できます。
SET DEFAULT ROLE ALL TO 'dev1'@'localhost';
次のステートメントを使用して、 dev1@localhostのすべてのデフォルト ロールを無効にすることができます。
SET DEFAULT ROLE NONE TO 'dev1'@'localhost';
注記:
このロールにデフォルト ロールを設定する前に、ユーザーにロールを付与する必要があります。
現在のセッションでロールを有効にする
現在のセッションでいくつかのロールを有効にすることができます。
SET ROLE {
DEFAULT
| NONE
| ALL
| ALL EXCEPT role [, role ] ...
| role [, role ] ...
}
たとえば、 rw_user1ログインした後、次のステートメントを使用して、現在のセッションでのみ有効なロールapp_readとapp_write有効にできます。
SET ROLE 'app_read', 'app_write';
現在のユーザーのデフォルト ロールを有効にするには、次のステートメントを使用できます。
SET ROLE DEFAULT
次のステートメントを使用して、現在のユーザーに付与されているすべてのロールを有効にできます。
SET ROLE ALL
すべてのロールを無効にするには、次のステートメントを使用できます。
SET ROLE NONE
app_read以外のロールを有効にするには、次のステートメントを使用できます。
SET ROLE ALL EXCEPT 'app_read'
注記:
SET ROLE使用してロールを有効にすると、このロールは現在のセッションでのみ有効になります。
現在有効なロールを確認する
現在のユーザーは、 CURRENT_ROLE()関数を使用して、現在のユーザーによって有効になっているロールを確認できます。
たとえば、 rw_user1'@'localhostにデフォルトのロールを付与できます。
SET DEFAULT ROLE ALL TO 'rw_user1'@'localhost';
rw_user1@localhost後、次のステートメントを実行できます。
SELECT CURRENT_ROLE();
+--------------------------------+
| CURRENT_ROLE() |
+--------------------------------+
| `app_read`@`%`,`app_write`@`%` |
+--------------------------------+
SET ROLE 'app_read'; SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| `app_read`@`%` |
+----------------+
役割を取り消す
次のステートメントを使用して、ユーザーread_user1@localhostおよびread_user2@localhostに付与されたapp_readロールを取り消すことができます。
REVOKE 'app_read' FROM 'read_user1'@'localhost', 'read_user2'@'localhost';
次のステートメントを使用して、 rw_user1@localhostユーザーに付与されたロールapp_readとapp_write取り消すことができます。
REVOKE 'app_read', 'app_write' FROM 'rw_user1'@'localhost';
ユーザーからロールを取り消す操作はアトミックです。ロールの取り消しに失敗した場合、この操作はロールバックされます。
権限を取り消す
REVOKE文はGRANTの逆です。 REVOKE使用するとapp_writeの権限を取り消すことができます。
REVOKE INSERT, UPDATE, DELETE ON app_db.* FROM 'app_write';
詳細はTiDB権限管理参照。
役割を削除する
次のステートメントを使用して、ロールapp_readとapp_write削除できます。
DROP ROLE 'app_read', 'app_write';
この操作により、 mysql.userテーブル内のapp_readとapp_writeロール レコードと、承認テーブル内の関連レコードが削除され、2 つのロールに関連する承認が終了します。
ロールを削除するには、 DROP ROLEまたはDROP USER権限が必要です。
承認テーブル
4 つのシステム権限テーブルに加えて、RBAC システムでは 2 つの新しいシステム権限テーブルが導入されています。
mysql.role_edges: ロールとユーザーの承認関係を記録します。mysql.default_roles: 各ユーザーのデフォルトのロールを記録します。
mysql.role_edges
mysql.role_edges次のデータが含まれます。
SELECT * FROM mysql.role_edges;
+-----------+-----------+---------+---------+-------------------+
| FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION |
+-----------+-----------+---------+---------+-------------------+
| % | r_1 | % | u_1 | N |
+-----------+-----------+---------+---------+-------------------+
1 row in set (0.00 sec)
FROM_HOSTとFROM_USERそれぞれロールのホスト名とユーザー名を示します。TO_HOSTとTO_USER、ロールが付与されるユーザーのホスト名とユーザー名を示します。
mysql.default_roles
mysql.default_roles 、各ユーザーに対してデフォルトで有効になっているロールを示します。
SELECT * FROM mysql.default_roles;
+------+------+-------------------+-------------------+
| HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER |
+------+------+-------------------+-------------------+
| % | u_1 | % | r_1 |
| % | u_1 | % | r_2 |
+------+------+-------------------+-------------------+
2 rows in set (0.00 sec)
HOSTとUSERそれぞれユーザーのホスト名とユーザー名を示します。DEFAULT_ROLE_HOSTとDEFAULT_ROLE_USER、それぞれデフォルト ロールのホスト名とユーザー名を示します。
参考文献
RBAC、ユーザー管理、権限管理は密接に関連しているため、操作の詳細については次のリソースを参照してください。