ユーザーが権限を持つデータベース一覧をRecursive CTEsを使用して取得する
目次
はじめに
データエンジニア部の城内です。
Recursive CTEs(Recursive Common Table Expressioins)を使用したクエリで、ユーザーが権限を持つデータベース一覧を取得する方法を説明していきます。
この記事を読んでわかること
・Recursive CTEsの概要
・ユーザーが権限を持つデータベース一覧を取得する方法
Recursive CTEsを使用する理由
ユーザーが権限を持つデータベース一覧を取得するには、以下の手順を踏む必要があります。
手順1.ユーザーが持つロールを取得する
手順2.1で取得したロールに付与した(下の階層の)ロールを(無くなるまで)繰り返し取得する
手順3.1、2で取得した各ロールに付与した権限からデータベースの権限を取得する
手順2は、もしユーザーに対して全てのロールを明示的に付与している場合には必要ありません。ただしそうではない場合に、手順2を1回で行うには、階層データに対して再帰的に処理できるRecursive CTEsが適しています。
その他の手順2に対する方法としては、Procedureを使用する、手動で何回もクエリを実行する等が考えられます。
Recursive CTEsとは
まずCTEとは、WITH句で定義したサブクエリのことです。モジュール化することで、クエリを見やすくする等のために使用します。
with granted_role (name, grantee_name) as ( select name, grantee_name from snowflake.account_usage.grants_to_roles ) select name, grantee_name from granted_role; +---------------+---------------+ | NAME | GRANTEE_NAME | |---------------+---------------| | SECURITYADMIN | ACCOUNTADMIN | | USERADMIN | SECURITYADMIN | | SYSADMIN | ACCOUNTADMIN | +---------------+---------------+
granted_role CTEはROLEの階層構造を取得するCTEで、nameがGrantするRole、grantee_roleがGrantされるRoleです。
次にRecursive CTEsとは、SELECT句AとSELECT句BをUNION ALLし、UNION ALLした結果はSELECT句Aとなり再度SELECT句BとUNION ALLする、これをSELECT句Bが空になるまで続けるサブクエリのことです。
with granted_role (name, grantee_name) as ( select name, grantee_name from snowflake.account_usage.grants_to_roles where granted_on = 'ROLE' and privilege = 'USAGE' ), recursive_granted_role (name, grantee_name) as ( select name, grantee_name from granted_role union all select granted_role.name as name, recursive_granted_role.grantee_name as grantee_name from recursive_granted_role join granted_role on recursive_granted_role.name = granted_role.grantee_name ) select name, grantee_name from recursive_granted_role; +---------------+---------------+ | NAME | GRANTEE_NAME | |---------------+---------------| | SECURITYADMIN | ACCOUNTADMIN | | USERADMIN | ACCOUNTADMIN | | USERADMIN | SECURITYADMIN | | SYSADMIN | ACCOUNTADMIN | +---------------+---------------+
Recurrent CTEsであるrecursive_granted_roleは、UNION ALLの後ろの句が無くなるまで、granted_roleのgrantee_roleに(直接的、間接的にかかわらず)GRANTしているRoleを探すので、Roleの全ての階層構造を取得できます。
必要なビュー
今回使用するビューになります。(account_usageスキーマ内のビューは、多少の遅延が起きるので、注意が必要です。)
snowflake.account_usage.grants_to_roles:ロールに付与している権限の情報
snowflake.account_usage.grants_to_users:ユーザーに付与しているロールの情報
ユーザーが権限を持つデータベース一覧を取得するクエリ
以下がRecursive CTEsを使用したクエリになります。
-- grants_to_roles ビューから、直接のGrantによってできたRoleの階層構造を取得するCTE with granted_role as ( select name, grantee_name from snowflake.account_usage.grants_to_roles where granted_on = 'ROLE' and privilege = 'USAGE' ), -- granted_role cteから、直接的、間接的なGrantにかかわらない、Roleの階層構造を取得するRecursive CTEs recursive_granted_role (name, grantee_name) as ( select name, grantee_name from granted_role union all select granted_role.name as name, recursive_granted_role.grantee_name as grantee_name from recursive_granted_role join granted_role on recursive_granted_role.name = granted_role.grantee_name ), -- RoleとRoleにGrantしたDatabaseを取得するCTE role_database as ( select name as database_name, grantee_name as role_name from snowflake.account_usage.grants_to_roles where granted_on = 'DATABASE' and deleted_on is null ), -- RoleとRoleをGrantしたUserを取得するCTE user_role as ( select grantee_name as user_name, role from snowflake.account_usage.grants_to_users as grants_to_users where grants_to_users.deleted_on is null ) -- ユーザーが権限を持つデータベース一覧を取得するクエリ -- 複数Roleに同じGrantがされていることも考慮してGroupbyしてMaxを取る select max(user_role.user_name) as user_name, max(role_database.database_name) as database_name from ( -- recursive_granted_roleはGrantによるRoleの階層構造のみで、Role自身を含んでいないので、親Roleと子Roleが同じなデータをUNION ALLする select name, grantee_name from recursive_granted_role union all select name, name as grantee_name from snowflake.account_usage.roles where deleted_on is null ) as self_recursive_granted_role -- 子RoleにGrantしたDatabase情報を取得するInner join inner join role_database on self_recursive_granted_role.name = role_database.role_name -- UserにGrantしたRole情報を取得するInner join inner join user_role as user_role on user_role.role = self_recursive_granted_role.grantee_name group by user_role.user_name, self_recursive_granted_role.grantee_name, role_database.database_name order by user_role.user_name, role_database.database_name ;
おわりに
今回はRecursive CTEsと、ユーザーが権限を持つデータベース一覧を取得するクエリについて説明しました。クエリを変更すれば、テーブル一覧にすること、特定の権限に絞ること等も可能です。
Snowflakeについてお困りごとがあればDATUM STUDIOまでお問合せください。
DATUM STUDIOは、クライアントの事業成長と経営課題解決を最適な形でサポートする、データ・ビジネスパートナーです。
データ分析の分野でお客様に最適なソリューションをご提供します。まずはご相談ください。
Contact
Explore Jobs
関連記事