

# RDS for MySQL のロールベースの権限モデル
<a name="Appendix.MySQL.CommonDBATasks.privilege-model"></a>

RDS for MySQL バージョン 8.0.36 以降では、`mysql` データベースのテーブルを直接変更することはできません。特に、`grant` テーブルに対してデータ操作言語 (DML) オペレーションを実行してデータベースユーザーを作成することはできません。代わりに、MySQL アカウント管理ステートメント (`CREATE USER`、`GRANT`、`REVOKE` など) を使用してロールベースの権限をユーザーに付与します。また、`mysql` データベースでストアドプロシージャなど、他の種類のオブジェクトを作成することはできません。`mysql` テーブルにクエリを実行することはできます。バイナリログのレプリケーションを使用する場合、ソース DB インスタンスの `mysql` テーブルに直接行った変更は、ターゲットクラスターにレプリケートされません。

場合によっては、`mysql` テーブルに挿入することで、アプリケーションがショートカットを使用して、ユーザーやその他のオブジェクトを作成する場合があります。その場合は、アプリケーションコードを変更して、`CREATE USER` などの対応したステートメントを使用します。

外部 MySQL データベースからの移行中にデータベースユーザーのメタデータをエクスポートするには、以下のいずれかの方法を使用します。
+ MySQL Shell のインスタンスダンプユーティリティを、ユーザー、ロール、権限を除外するフィルターと共に使用します。次の例は、使用するコマンド構文を示しています。`outputUrl` が空であることを確認します。

  ```
  mysqlsh user@host -- util.dumpInstance(outputUrl,{excludeSchemas:['mysql'],users: true})
  ```

  詳細については、MySQL リファレンスマニュアルの「[インスタンスダンプユーティリティ、スキーマダンプユーティリティ、およびテーブルダンプユーティリティ](https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-dump-instance-schema.html)」を参照してください。
+ `mysqlpump` クライアントユーティリティを使用します。この例には、`mysql` システムデータベース内のテーブルを除くすべてのテーブルが含まれています。これには移行されたデータベース内のすべての MySQL ユーザーを再現する `CREATE USER` や `GRANT` ステートメントも含まれます。

  ```
  mysqlpump --exclude-databases=mysql --users
  ```

  `mysqlpump` クライアントユーティリティは、MySQL 8.4 では使用できなくなりました。代わりに `mysqldump` を使用してください。

多くのユーザーまたはアプリケーションの権限の管理を簡素化するには、`CREATE ROLE` ステートメントを使用して、一連の権限を持つロールを作成します。その後、`GRANT` および `SET ROLE` ステートメントと `current_role` 関数を使用して、ユーザーまたはアプリケーションにロールを割り当てたり、現在のロールを切り替えたり、有効なロールをチェックしたりできます。MySQL 8.0 でのロールベースのアクセス許可システムの詳細については、MySQL リファレンスマニュアルの[ロールの使用](https://dev.mysql.com/doc/refman/8.0/en/roles.html)を参照してください。

**重要**  
アプリケーションではマスターユーザーを直接使用しないことを強くお勧めします。代わりに、アプリケーションに必要な最小の特権で作成されたデータベースユーザーを使用するというベストプラクティスに従ってください。

RDS for MySQL バージョン 8.0.36 以降には、以下のすべての権限を持つ特別なロールが含まれています。ロールの名前は `rds_superuser_role` です。各 DB インスタンスのプライマリ管理ユーザーには、このロールが既に付与されています。`rds_superuser_role` ロールには、すべてのデータベースオブジェクトに対する次の権限が含まれます。
+  `ALTER` 
+  `APPLICATION_PASSWORD_ADMIN` 
+  `ALTER ROUTINE` 
+  `CREATE` 
+  `CREATE ROLE` 
+  `CREATE ROUTINE` 
+  `CREATE TEMPORARY TABLES` 
+  `CREATE USER` 
+  `CREATE VIEW` 
+  `DELETE` 
+  `DROP` 
+  `DROP ROLE` 
+  `EVENT` 
+  `EXECUTE` 
+  `INDEX` 
+  `INSERT` 
+  `LOCK TABLES` 
+  `PROCESS` 
+  `REFERENCES` 
+  `RELOAD` 
+  `REPLICATION CLIENT` 
+  `REPLICATION SLAVE` 
+  `ROLE_ADMIN` 
+  `SET_USER_ID` 
+  `SELECT` 
+  `SHOW DATABASES` 
+  `SHOW VIEW` 
+  `TRIGGER` 
+  `UPDATE` 
+  `XA_RECOVER_ADMIN`

 ロール定義には `WITH GRANT OPTION` が含まれるため、管理ユーザーはそのロールを他のユーザーに付与することができます。特に、管理者は MySQL クラスターをターゲットとするバイナリログレプリケーションの実行に必要な権限を付与する必要があります。

**ヒント**  
 アクセス許可の詳細全体を表示するには、次のステートメントを使用します。  

```
SHOW GRANTS FOR rds_superuser_role@'%';
```

 RDS for MySQL バージョン 8.0.36 以降でロールを使用してアクセスを許可する場合は、`SET ROLE role_name` または `SET ROLE ALL` ステートメントを使用してロールも有効にします。以下の例のように指定します。`CUSTOM_ROLE` 用に適切なロール名を置き換えます。

```
# Grant role to user
mysql> GRANT CUSTOM_ROLE TO 'user'@'domain-or-ip-address'

# Check the current roles for your user. In this case, the CUSTOM_ROLE role has not been activated.
# Only the rds_superuser_role is currently in effect.
mysql> SELECT CURRENT_ROLE();
+--------------------------+
| CURRENT_ROLE()           |
+--------------------------+
| `rds_superuser_role`@`%` |
+--------------------------+
1 row in set (0.00 sec)

# Activate all roles associated with this user using SET ROLE.
# You can activate specific roles or all roles.
# In this case, the user only has 2 roles, so we specify ALL.
mysql> SET ROLE ALL;
Query OK, 0 rows affected (0.00 sec)

# Verify role is now active
mysql> SELECT CURRENT_ROLE();
+--------------------------------------------------+
| CURRENT_ROLE()                                   |
+--------------------------------------------------+
| `CUSTOM_ROLE`@`%`,`rds_superuser_role`@`%` |
+--------------------------------------------------+
```