データベースについて調べてみた

データベースについて調べたことのメモ。Oracle要素多めになる予定。

Oracle 23ai新機能のスキーマ権限について調べてみた

Oracle Databaseの最新ロングタームリリースであるOracle Database 23ai(今まではOracle Database 23cと呼称)の提供開始が発表されました。

ということで(?)、今回は最近触れる機会があった、Oracle Database 23aiの新機能の一つである、スキーマ権限について調べてみました。

 

1. スキーマ権限とは

スキーマ権限とは、システム権限の対象を特定スキーマに限定できる、Oracle Database 23aiで登場した新機能です。

例えば、今まではシステム権限であるSELECT ANY TABLE権限を付与する際に、権限の対象スキーマを指定できないため、本来は参照させたくないスキーマのテーブルにもSELECTできてしまいましたが、スキーマ権限では特定スキーマのみを対象としたSELECT ANY TABLE権限が付与できるようになったので、参照させたいスキーマのテーブルにだけSELECTできるような制御をできるようになりました。

※Database Vaultを導入している場合は、レルムを定義することで、SELECT ANY TABLE権限が付与されていても、参照させたくないスキーマのテーブルへのアクセスを制限することができます。

 

2. スキーマ権限の付与方法

スキーマ権限は以下の様なGRANT文によって、ユーザやロールに付与できます。ポイントはON SCHEMA句で権限対象のスキーマを指定する点です。

GRANT <スキーマ権限名> ON SCHEMA <権限対象のスキーマ(ユーザ)> TO <権限付与対象ユーザ/ロール>;

ON SCHEMA句に続けて指定できるスキーマは1つだけなので、1回のGRANT文で複数のスキーマに対するスキーマ権限の付与はできないため、付与したい場合は複数回GRANT文を実行する必要がある点に注意が必要です。

※TOの後は複数のユーザ/ロールを指定できます。

 

3. 設定例

以下の様なユーザ(スキーマ)構成の環境下で、スキーマ権限の設定例を紹介いたします。

  • データベースへの接続用ユーザとしてUSR_AとUSR_Bが存在
  • テーブル所有ユーザとしてUSR_CとUSR_Dが存在
  • USR_Cが所有するテーブルはUSR_AとUSR_Bにアクセスさせたいが、USR_Dが所有するテーブルにはアクセスさせたくない
  • USR_CとUSR_Dが所有するテーブル数は多く且つ頻繁に増減するので、SELECT ANY TABLE権限で対応したい

上記の図に合わせて、USR_Aにシステム権限のSELECT ANY TABLE権限を付与し、USR_BにUSR_Cの所有テーブルにだけSELECTできるSELECT ANY TABLEのスキーマ権限を付与して、両ユーザのテーブルアクセス状況を比較してみます。

今回の実機確認では、OCIのOracle Base Database Serviceで構築した、Oracle Database 23ai(23.4.0)を使用しました。

 

まず、USR_AとUSR_Bに権限を付与します。システム権限はdba_sys_privsディクショナリを用いて権限の付与状況を確認できますが、スキーマ権限の場合はdba_schema_privsディクショナリを使用します。

-- USR_Aへのシステム権限付与
SQL> GRANT SELECT ANY TABLE TO USR_A;

Grant succeeded.

-- dba_sys_privsディクショナリで権限の付与状況を確認
SQL> SELECT grantee, privilege FROM dba_sys_privs WHERE grantee = 'USR_A' ORDER BY 1,2;

GRANTEE                        PRIVILEGE
------------------------------ ----------------------------------------
USR_A                          SELECT ANY TABLE


-- USR_Bへのスキーマ権限付与
SQL> GRANT SELECT ANY TABLE ON SCHEMA USR_C TO USR_B;

Grant succeeded.

-- dba_schema_privsディクショナリで権限の付与状況を確認
SQL> SELECT grantee, privilege, schema FROM dba_schema_privs WHERE grantee LIKE 'USR%' ORDER BY 1,2,3;

GRANTEE                        PRIVILEGE                                SCHEMA
------------------------------ ---------------------------------------- ------------------------------
USR_B                          SELECT ANY TABLE                         USR_C

 

まず、従来から存在しているシステム権限のSELECT ANY TABLE権限を付与した、USR_Aでのテーブルアクセス状況を確認してみます。

SQL> show user
ユーザーは"USR_A"です。

SQL> SELECT * FROM USR_C.TAB001;

      COL1 COL2
---------- -----
         1 AAAAA


SQL> SELECT * FROM USR_D.TAB501;

      COL1 COL2
---------- -----
         1 CCCCC

USR_Cが所有するTAB001テーブルにアクセスできるのはよいですが、本来はアクセスさせたくない、USR_Dが所有するTAB501テーブルにもアクセスできてしまっています。

 

続いて、USR_Cを対象としたスキーマ権限のSELECT ANY TABLE権限を付与した、USR_Bでのテーブルアクセス状況を確認してみます。

SQL> show user
ユーザーは"USR_B"です。

SQL> SELECT * FROM USR_C.TAB001;

      COL1 COL2
---------- -----
         1 AAAAA


SQL> SELECT * FROM USR_D.TAB501;
SELECT * FROM USR_D.TAB501
              *
ERROR at line 1:
ORA-00942: table or view "USR_D"."TAB501" does not exist
Help: https://docs.oracle.com/error-help/db/ora-00942/

USR_Cが所有するTAB001テーブルにアクセスでき、アクセスさせたくないUSR_Dが所有するTAB501テーブルに対するSELECT文はORA-00942エラーが発生し、アクセスできないことが確認できました。

 

4. さいごに

スキーマ権限を利用することで、範囲を限定した権限付与が行えることがわかりました。今までは望まないながらも、広範囲にアクセスできてしまうシステム権限を付与していた方は、Oracle Database 23aiからは、スキーマ権限の利用を検討してみるとよいかと思います。

 

 

次の記事:リフレッシュ可能PDBの作成手順を調べてみた

 

前回の記事:CDBとPDBにおけるAWRの違いについて調べてみた