役割ベースのアクセス制御

TiDB の役割ベースのアクセス制御 (RBAC) システムの実装は、MySQL 8.0 の実装と似ています。 TiDB は、MySQL のほとんどの RBAC 構文と互換性があります。

このドキュメントでは、TiDB RBAC 関連の操作と実装について紹介します。

RBAC 操作

ロールは、一連の権限の集合です。次の操作を実行できます。

  • ロールを作成します。
  • 役割を削除します。
  • ロールに権限を付与します。
  • 別のユーザーに役割を付与します。そのユーザーは、ロールを有効にした後、ロールに関連する権限を取得できます。

役割を作成する

たとえば、次のステートメントを使用して、ロールapp_developerapp_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に対するすべての権限を持つ開発者ロールを持っているとします。 2 人のユーザーread_user1read_user2app_dbに対する読み取り専用権限を持っています。また、ユーザーrw_user1app_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 GRANTSUSINGオプションを使用して、ロールの権限を確認できます。

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()を使用して、現在のユーザーの権限を確認できます。 SHOW GRANTSSHOW GRANTS FOR CURRENT_USER()は、次の点で異なります。

  • 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_readapp_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_readapp_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_readapp_writeを削除できます。

DROP ROLE 'app_read', 'app_write';

この操作により、 mysql.userテーブルのapp_readapp_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_HOSTFROM_USERは、それぞれ役割のホスト名とユーザー名を示します。
  • TO_HOSTTO_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)
  • HOSTUSERは、それぞれユーザーのホスト名とユーザー名を示します。
  • DEFAULT_ROLE_HOSTDEFAULT_ROLE_USERは、それぞれデフォルト ロールのホスト名とユーザー名を示します。

参考文献

RBAC、ユーザー管理、および権限管理は密接に関連しているため、次のリソースで操作の詳細を参照できます。