MySQL 8.0.16 より前は、特定のスキーマを除き、グローバルに適用される権限を付与することはできません。 MySQL 8.0.16 では、これは partial_revokes
システム変数が有効な場合に可能です。 具体的には、グローバルレベルの権限を持つユーザーの場合、partial_revokes
では、特定のスキーマの権限を取り消しながら、他のスキーマの権限をそのままにすることができます。 したがって、権限の制限は、グローバル権限を持つが、特定のスキーマへのアクセスを許可しないアカウントの管理に役立つ場合があります。 たとえば、mysql
システムスキーマ内のテーブルを除く任意のテーブルの変更をアカウントに許可できます。
簡潔にするために、ここに示す CREATE USER
ステートメントにはパスワードは含まれていません。 本番で使用する場合は、常にアカウントパスワードを割り当てます。
partial_revokes
システム変数は、アカウントに権限制限を設定できるかどうかを制御します。 デフォルトでは、partial_revokes
は無効になっており、グローバル権限を部分的に取り消そうとするとエラーが発生します:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT ON *.* TO u1;
mysql> REVOKE INSERT ON world.* FROM u1;
ERROR 1141 (42000): There is no such grant defined for user 'u1' on host '%'
REVOKE
操作を許可するには、partial_revokes
を有効にします:
SET PERSIST partial_revokes = ON;
SET PERSIST
は、実行中の MySQL インスタンスの値を設定します。 また、値が保存され、その後のサーバーの再起動に引き継がれます。 後続の再起動に引き継ぐことなく、実行中の MySQL インスタンスの値を変更するには、PERSIST
ではなく GLOBAL
キーワードを使用します。 セクション13.7.6.1「変数代入の SET 構文」を参照してください。
partial_revokes
が有効になっている場合、部分的な取消しは成功します:
mysql> REVOKE INSERT ON world.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+------------------------------------------+
| Grants for u1@% |
+------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
| REVOKE INSERT ON `world`.* FROM `u1`@`%` |
+------------------------------------------+
SHOW GRANTS
の出力には、部分的な取消しが REVOKE
ステートメントとしてリストされます。 この結果は、world
スキーマのテーブルに対して INSERT
を実行できないことを除き、u1
にグローバルな SELECT
および INSERT
権限があることを示しています。 つまり、u1
による world
テーブルへのアクセスは読取り専用です。
サーバーは、部分的な取消しによって実装された権限制限を mysql.user
システムテーブルに記録します。 アカウントに部分的な失効がある場合、その User_attributes
カラム値には Restrictions
属性があります:
mysql> SELECT User, Host, User_attributes->>'$.Restrictions'
FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
+------+------+------------------------------------------------------+
| User | Host | User_attributes->>'$.Restrictions' |
+------+------+------------------------------------------------------+
| u1 | % | [{"Database": "world", "Privileges": ["INSERT"]}] |
+------+------+------------------------------------------------------+
部分的な取消しは任意のスキーマに適用できますが、mysql
システムスキーマに対する権限制限は、通常のアカウントがシステムアカウントを変更できないようにする戦略の一環として特に役立ちます。 通常アカウントによる操作からのシステムアカウントの保護を参照してください。
部分的な取消し操作には、次の条件があります:
部分的な取消しでは、スキーマに文字どおりの名前を付ける必要があります。
%
または_
SQL ワイルドカード文字 (myschema%
など) を含むスキーマ名は使用できません。部分的な取消しを使用して、存在しないスキーマに制限を設定できますが、取り消す権限がグローバルに付与されている場合のみです。 権限がグローバルに付与されていない場合、存在しないスキーマに対して権限を取り消すとエラーが発生します。
部分的な取消しはスキーマレベルでのみ適用されます。 部分取消しは、グローバルにのみ適用される権限 (
FILE
、BINLOG_ADMIN
など)、またはテーブル、カラムまたはルーチン権限には使用できません。
前述のように、スキーマレベルの権限の部分的な取消しは、SHOW GRANTS
出力に REVOKE
ステートメントとして表示されます。 これは、SHOW GRANTS
が「「プレーン」」スキーマレベルの権限を表す方法とは異なります:
-
付与されると、スキーマレベルの権限は、出力内の独自の
GRANT
ステートメントによって表されます:mysql> CREATE USER u1; mysql> GRANT UPDATE ON mysql.* TO u1; mysql> GRANT DELETE ON world.* TO u1; mysql> SHOW GRANTS FOR u1; +---------------------------------------+ | Grants for u1@% | +---------------------------------------+ | GRANT USAGE ON *.* TO `u1`@`%` | | GRANT UPDATE ON `mysql`.* TO `u1`@`%` | | GRANT DELETE ON `world`.* TO `u1`@`%` | +---------------------------------------+
-
取り消すと、スキーマレベルの権限は単に出力から消えます。 これらは
REVOKE
ステートメントとしては表示されません:mysql> REVOKE UPDATE ON mysql.* FROM u1; mysql> REVOKE DELETE ON world.* FROM u1; mysql> SHOW GRANTS FOR u1; +--------------------------------+ | Grants for u1@% | +--------------------------------+ | GRANT USAGE ON *.* TO `u1`@`%` | +--------------------------------+
ユーザーが権限を付与すると、権限受領者がその権限を持たない権限をすでに持っていないかぎり、権限受領者はその権限を継承します。 次の 2 人のユーザーについて考えてみます。いずれかのユーザーにグローバル SELECT
権限があります:
CREATE USER u1, u2;
GRANT SELECT ON *.* TO u2;
管理ユーザー admin
に、グローバルだが部分的に取り消された SELECT
権限があるとします:
mysql> CREATE USER admin;
mysql> GRANT SELECT ON *.* TO admin WITH GRANT OPTION;
mysql> REVOKE SELECT ON mysql.* FROM admin;
mysql> SHOW GRANTS FOR admin;
+------------------------------------------------------+
| Grants for admin@% |
+------------------------------------------------------+
| GRANT SELECT ON *.* TO `admin`@`%` WITH GRANT OPTION |
| REVOKE SELECT ON `mysql`.* FROM `admin`@`%` |
+------------------------------------------------------+
admin
によって SELECT
が u1
および u2
にグローバルに付与される場合、結果はユーザーごとに異なります:
-
admin
がSELECT
権限を持たないu1
にSELECT
をグローバルに付与する場合、u1
はadmin
権限制限を継承します:mysql> GRANT SELECT ON *.* TO u1; mysql> SHOW GRANTS FOR u1; +------------------------------------------+ | Grants for u1@% | +------------------------------------------+ | GRANT SELECT ON *.* TO `u1`@`%` | | REVOKE SELECT ON `mysql`.* FROM `u1`@`%` | +------------------------------------------+
-
一方、
u2
は制限なしでグローバルSELECT
権限をすでに保持しています。GRANT
は、権限受領者の既存の権限にのみ追加でき、権限を減らすことはできないため、admin
がSELECT
をu2
にグローバルに付与する場合、u2
はadmin
の制限を継承しません:mysql> GRANT SELECT ON *.* TO u2; mysql> SHOW GRANTS FOR u2; +---------------------------------+ | Grants for u2@% | +---------------------------------+ | GRANT SELECT ON *.* TO `u2`@`%` | +---------------------------------+
GRANT
ステートメントに AS
句が含まれている場合、適用される権限制限は、ステートメントを実行するユーザーではなく、句で指定されたユーザー/ロールの組合せに対する権限制限です。 user
AS
句の詳細は、セクション13.7.1.6「GRANT ステートメント」 を参照してください。
アカウントに付与される新しい権限の制限は、そのアカウントの既存の制限に追加されます:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql> REVOKE INSERT ON mysql.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE INSERT ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
mysql> REVOKE DELETE, UPDATE ON db2.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE UPDATE, DELETE ON `db2`.* FROM `u1`@`%` |
| REVOKE INSERT ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
権限制限の集計は、権限が明示的に明示的に取り消された場合 (前述のとおり)、およびステートメントを実行するユーザーまたは AS
句に指定されたユーザーから制限が暗黙的に継承された場合の両方に適用されます。
user
アカウントにスキーマに対する権限制限がある場合:
アカウントは、制限付きスキーマまたはその中のオブジェクトに対する権限を他のアカウントに付与することはできません。
-
制限のない別のアカウントは、制限付きスキーマまたはその中のオブジェクトの制限付きアカウントに権限を付与できます。 無制限のユーザーが次のステートメントを実行するとします:
CREATE USER u1; GRANT SELECT, INSERT, UPDATE ON *.* TO u1; REVOKE SELECT, INSERT, UPDATE ON mysql.* FROM u1; GRANT SELECT ON mysql.user TO u1; -- grant table privilege GRANT SELECT(Host,User) ON mysql.db TO u1; -- grant column privileges
結果のアカウントには次の権限があり、制限付きスキーマ内で制限付き操作を実行できます:
mysql> SHOW GRANTS FOR u1; +-----------------------------------------------------------+ | Grants for u1@% | +-----------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` | | REVOKE SELECT, INSERT, UPDATE ON `mysql`.* FROM `u1`@`%` | | GRANT SELECT (`Host`, `User`) ON `mysql`.`db` TO `u1`@`%` | | GRANT SELECT ON `mysql`.`user` TO `u1`@`%` | +-----------------------------------------------------------+
アカウントにグローバル権限の制限がある場合、その制限は次のいずれかのアクションによって削除されます:
権限に対する制限のないアカウントによるアカウントへの権限のグローバルな付与。
スキーマレベルでの権限の付与。
権限をグローバルに取り消します。
複数の権限をグローバルに保持しているが、INSERT
、UPDATE
および DELETE
に制限があるユーザー u1
について考えてみます:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO u1;
mysql> REVOKE INSERT, UPDATE, DELETE ON mysql.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+----------------------------------------------------------+
| Grants for u1@% |
+----------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE INSERT, UPDATE, DELETE ON `mysql`.* FROM `u1`@`%` |
+----------------------------------------------------------+
制限のないアカウントから u1
にグローバルに権限を付与すると、権限制限が削除されます。 たとえば、INSERT
の制限を削除するには:
mysql> GRANT INSERT ON *.* TO u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE UPDATE, DELETE ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
スキーマレベルで u1
に権限を付与すると、権限の制限がなくなります。 たとえば、UPDATE
の制限を削除するには:
mysql> GRANT UPDATE ON mysql.* TO u1;
mysql> SHOW GRANTS FOR u1;
+---------------------------------------------------------+
| Grants for u1@% |
+---------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO `u1`@`%` |
| REVOKE DELETE ON `mysql`.* FROM `u1`@`%` |
+---------------------------------------------------------+
グローバル権限を取り消すと、その権限に対する制限も含めて権限が削除されます。 たとえば、DELETE
の制限を削除するには、次のようにします (すべての DELETE
アクセスを削除します):
mysql> REVOKE DELETE ON *.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+-------------------------------------------------+
| Grants for u1@% |
+-------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO `u1`@`%` |
+-------------------------------------------------+
アカウントにグローバルレベルとスキーマレベルの両方の権限がある場合、部分的な取消しを有効にするには、スキーマレベルで 2 回取り消す必要があります。 u1
に次の権限があり、INSERT
がグローバルおよび world
スキーマの両方で保持されているとします:
mysql> CREATE USER u1;
mysql> GRANT SELECT, INSERT ON *.* TO u1;
mysql> GRANT INSERT ON world.* TO u1;
mysql> SHOW GRANTS FOR u1;
+-----------------------------------------+
| Grants for u1@% |
+-----------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
| GRANT INSERT ON `world`.* TO `u1`@`%` |
+-----------------------------------------+
world
で INSERT
を取り消すと、スキーマレベルの権限が取り消されます (SHOW GRANTS
にはスキーマレベルの GRANT
ステートメントは表示されなくなります):
mysql> REVOKE INSERT ON world.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+-----------------------------------------+
| Grants for u1@% |
+-----------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
+-----------------------------------------+
world
で INSERT
を再度取り消すと、グローバル権限の部分的な取消しが実行されます (SHOW GRANTS
にはスキーマレベルの REVOKE
ステートメントが含まれるようになりました):
mysql> REVOKE INSERT ON world.* FROM u1;
mysql> SHOW GRANTS FOR u1;
+------------------------------------------+
| Grants for u1@% |
+------------------------------------------+
| GRANT SELECT, INSERT ON *.* TO `u1`@`%` |
| REVOKE INSERT ON `world`.* FROM `u1`@`%` |
+------------------------------------------+
一部のスキーマのアカウントへのアクセスを提供し、他のスキーマのアカウントへのアクセスを提供するために、部分的な取消しでは、グローバル権限を付与せずにスキーマレベルのアクセス権を明示的に付与する方法の代替方法が提供されます。 2 つのアプローチには、長所と短所があります。
グローバル権限ではなく、スキーマレベルの権限を付与します:
新規スキーマの追加: デフォルトでは、スキーマには既存のアカウントからアクセスできません。 スキーマにアクセスできるアカウントの場合、DBA はスキーマレベルのアクセス権を付与する必要があります。
新規アカウントの追加: DBA は、アカウントがアクセスできるスキーマごとにスキーマレベルのアクセス権を付与する必要があります。
部分的な取消しと組み合せたグローバル権限の付与:
新規スキーマの追加: スキーマは、グローバル権限を持つ既存のアカウントからアクセスできます。 スキーマにアクセスできないアカウントの場合、DBA は部分的な取消しを追加する必要があります。
新規アカウントの追加: DBA は、グローバル権限に加えて、各制限付きスキーマに対する部分的な取消しを付与する必要があります。
明示的なスキーマレベルの付与を使用するアプローチは、アクセスがいくつかのスキーマに制限されているアカウントでは便利です。 部分的な取消しを使用するアプローチは、少数を除くすべてのスキーマへの広範なアクセス権を持つアカウントではより便利です。
一度有効にすると、アカウントに権限制限がある場合は partial_revokes
を無効にできません。 そのようなアカウントが存在する場合、partial_revokes
の無効化は失敗します:
起動時に
partial_revokes
を無効にしようとすると、サーバーはエラーメッセージをログに記録し、partial_revokes
を有効にします。実行時に
partial_revokes
を無効にしようとすると、エラーが発生し、partial_revokes
値は変更されません。
制限が存在する場合に partial_revokes
を無効にするには、最初に制限を削除する必要があります:
-
部分的な失効があるアカウントを判別します:
SELECT User, Host, User_attributes->>'$.Restrictions' FROM mysql.user WHERE User_attributes->>'$.Restrictions' <> '';
-
このようなアカウントごとに、その権限制限を削除します。 前のステップで、アカウント
u1
に次の制限があるとします:[{"Database": "world", "Privileges": ["INSERT", "DELETE"]
制限の削除は様々な方法で実行できます:
-
制限なしで権限をグローバルに付与します:
GRANT INSERT, DELETE ON *.* TO u1;
-
スキーマレベルで権限を付与します:
GRANT INSERT, DELETE ON world.* TO u1;
-
権限をグローバルに取り消します (不要になった場合):
REVOKE INSERT, DELETE ON *.* FROM u1;
-
アカウント自体を削除します (不要になった場合):
DROP USER u1;
-
すべての権限制限を削除した後、部分的な取消しを無効にできます:
SET PERSIST partial_revokes = OFF;