Snowflake で部署ごとに分けた行は、セカンダリロールを外して確かめる|ALL のままだと、ほかのロールが効く
Snowflake の行アクセスポリシーで部署ごとに行を分けたとき、管理者がプライマリロールを切り替えて開くだけでは、部署の人の見え方を確かめたことにならない場合があります。セカンダリロールが既定の ALL のままだと、確かめる人のほかのロールが効くためです。検証用のアカウントで見えた余分な行と隠れた権限、CURRENT_ROLE と IS_ROLE_IN_SESSION の違い、ロールごと・利用者ごとの確かめ方をまとめます。
目次 クリックで開く
この記事は、Snowflake の行アクセスポリシー(Enterprise Edition 以上の機能)で部署ごとに見せる行を分けた方に向けて書いています。前提になるのは、ユーザーのセカンダリロールの既定が ALL であることです。既定値は 2024_08 の動作変更のバンドルで ALL に変わり、2025年3月のリリースからは、すべてのアカウントで有効になっています。手元の確かめは2026年10月に、Enterprise の試用アカウント(AWS の東京リージョン)で行いました。
確かめたかったのは、管理者がプライマリロールを部署のロールに切り替えて表を開けば、その部署の人の見え方を確かめたことになるのか、です。
今回の環境では、なりませんでした。大阪支店のロールに切り替えて受注の表を開くと、セカンダリロールが ALL のままでは東京の行も含めて 30行が見え、セカンダリロールを外す(USE SECONDARY ROLES NONE)と大阪の 10行でした。権限の側でも同じことが起き、東京のロールに読む権限を付けていない表が、ALL のままでは開けて、外すとエラーになりました。同じロールで ALL と NONE だけを替えて結果が変わったので、確かめた利用者(支店のロールも、表を作った SYSADMIN も使える管理者)のほかのロールが、セカンダリロールとして効いていたと読めます。
当社は Snowflake の導入支援で、Snowflake に最初からある管理者のロールは最初の準備だけに使い、毎日の取り込みには、必要な権限だけを付けた取り込み用のロールを使う設計をしました(導入事例。設計が済み、構築はこれから)。セカンダリロールが ALL なら、管理者のロール(ACCOUNTADMIN と、その下の SYSADMIN)は、使うつもりのない場面でも、それを持つ人が部署の見え方を確かめるときにセカンダリロールとして効きます。今回の検証では、確かめのために利用者へ付けた支店のロールがセカンダリロールとして効き(大阪のロールで東京の行まで見えた件)、後から作った表が開けた件では、管理者のロール(ACCOUNTADMIN を通して使える SYSADMIN)が効いたと読めます。受注の表は東京 20行・大阪 10行の架空の 30行で、部署ごとに行を分ける確かめは、この検証用のアカウントで試しました。
確かめるときは、セカンダリロールを外し、確かめるロールだけで開きます。ただし、それで分かるのはロール1つずつの見え方です。部署のロールにほかのロールも付けた利用者が、ALL のまま何を見るかは、その利用者のロールの組み合わせで開かないと分かりません。
同じロールで、セカンダリロールを付けたまま開いたときと外したときを、4つの場面で並べたのが次の図です。
プライマリロールを切り替えても、ほかのロールはセカンダリロールとして効いたまま
USE ROLE で替わるのはプライマリロールだけです。セカンダリロールの ALL は、そのユーザーに付けたロールのすべてで、既定のままのユーザーなら、切り替えた後もほかのロールが効いています。公式の説明では、表を読むような権限は、プライマリロール、セカンダリロール、それらが継承したロールのどれからでも探されます。
行アクセスポリシーの中で使った IS_ROLE_IN_SESSION も、プライマリロールとセカンダリロールの階層の中に、そのロールがあるかを見ます。今回のポリシーは、ロールと支店の対応表を引き、効いているロールに当たる支店の行を返す形です。確かめた利用者は東京と大阪の両方のロールを持っていたので、大阪のロールに切り替えても、セカンダリロールとして効く東京のロールで、東京の行も返りました。
公式の仕組みからは、確かめる人のほかのロールに、部署のロールや表の権限が含まれていなければ、ALL のままでも結果は変わりません。ところが、公式が勧める組み方では、管理者のほかのロールには、部署のロールが含まれます。部署に当たるロールは、公式のベストプラクティスで言う機能ロールで、公式は、ロール階層の最上位の機能ロールを SYSADMIN に付けるよう勧めています。今回もそのとおり、支店のロールを2つまとめるまとめ役のロールを作り、SYSADMIN に付けました。こうすると、SYSADMIN や、それを含む ACCOUNTADMIN を持つ管理者は、すべての部署のロールを下に持つことになります。
支店のロールには、表を開くための4つの権限(ウェアハウス、データベース、スキーマの USAGE と、表の SELECT)を付けました。表への権限をアクセスロールにまとめて機能ロールに付ける組み方も公式は勧めていますが、今回は支店2つ・表1つなので、支店のロールに直接付けています。今回の検証では、ロールは SECURITYADMIN で、データベースと表は SYSADMIN で作りました。公式は、ACCOUNTADMIN で物を作るのは、その物に最も高い水準の保護がどうしても要る場合を除いて避けるよう書いています。
後から作った表は、ALL のままだと権限が無くても開けた
権限を付けた後に、SYSADMIN で受注の表をもう1つ作り、東京のロールで開きました。東京のロールに付けたのは、付けた時点でスキーマにあった表を読む権限(GRANT SELECT ON ALL TABLES)で、後から作った表の分は入っていません。セカンダリロールが ALL のままだと1行が見え、外すと次のエラーになりました(表とロールの名前は〈〉に置き換えています)。
SQL compilation error: Object ‘〈表〉’ does not exist or not authorized. Your primary role 〈ロール〉 must have at least one privilege granted on TABLE 〈表〉.
表の持ち主は、作ったときのプライマリロール(SYSADMIN)です。確かめた利用者は SYSADMIN も使えるので、ALL のままでは、その権限で開けていたと読めます。エラーの文も、プライマリロールに権限が無いことを言っています。
後から作る表に読む権限を付けるには、スキーマに今後の分の権限(FUTURE GRANTS)を付けます。GRANT SELECT ON FUTURE TABLES IN SCHEMA 〈スキーマ〉 TO ROLE 〈支店のロール〉; を流した後に SYSADMIN で作った表は、セカンダリロールを外した東京のロールで 1行が見えました。公式の読み取り専用のロールの例と、その注も、既存の表の分(ON ALL TABLES)と今後の分(ON FUTURE TABLES)の2本立てです。
今後の分で付くのは読む権限で、行アクセスポリシーではありません。ポリシーの付いていない表では、読む権限のあるロールに全部の行が見えます。部署で分けたい表なら、作るときに指定するか(CREATE TABLE の ROW ACCESS POLICY)、作った後に付けます(ALTER TABLE … ADD ROW ACCESS POLICY)。スキーマに付けたタグにポリシーを結び付け、その下の表に効かせる方法もありますが、2026年10月の時点ではプレビューの機能(Enterprise Edition 以上)です。
ウェアハウスの USAGE が無いロールでも、ALL のままでは集計が流れた
ウェアハウスを使う権限だけを付けなかったロールで、対応表のロールの数を数える集計を流しました。ALL のままでは画面上部のウェアハウスの欄にウェアハウスが入り、結果(2)が返りました。外すと欄は「Choose warehouse」になり、次のエラーでした。
No active warehouse selected in the current session. Select an active warehouse with the ‘use warehouse’ command.
公式には、表を問い合わせるにはロールにウェアハウスの USAGE が要り、セッションにウェアハウスが付くまではクエリを流せない、とあります。部署の人の画面でこのエラーが出たら、そのロールのウェアハウスの USAGE と、ユーザーの既定のウェアハウスの両方を見ます。
CURRENT_ROLE で書いたポリシーは、まとめ役のロールに行を返さない
行アクセスポリシーの書き方も、ロールの切り替えで結果が変わります。公式の簡単な例は、プライマリロールの名前を返す CURRENT_ROLE で書かれています。対応表のロール名が CURRENT_ROLE と同じ行を返す形にすると、東京のロールは東京の 20行、大阪のロールは大阪の 10行でしたが、まとめ役のロールも SYSADMIN も 0行でした。CURRENT_ROLE はプライマリロールの名前1つだけを返すので、対応表に無いまとめ役の名前はどの行にも当たらず、下に支店のロールを持っていても通りません。セカンダリロールを外しても付けても、結果は同じでした。
公式は、ロールの階層を考える必要があるなら IS_ROLE_IN_SESSION を使うよう書いています。書き替えると、まとめ役と SYSADMIN には 30行が見えました。その代わり、セカンダリロールが ALL のままなら、支店のロールを両方持つ人は、どちらのロールに切り替えても両方の支店の行を見ます。外せば、切り替えた支店の行だけです。
支店をまたいで見る人には、支店のロールを重ねて付けるより、まとめ役のロールを1つ付ける形を当社は勧めます。公式の勧めではなく、当社の判断です(今回の検証では、確かめのために利用者へ支店のロールを2つとも付けています)。IS_ROLE_IN_SESSION の仕組みでは、ALL のときに見える行は、支店のロールを両方付けても、まとめ役を付けても同じで、見える範囲は変わりません。違いは確かめ方の側に出ます。IS_ROLE_IN_SESSION の仕組みからは、まとめ役のほかにロールが付いていない人なら、セカンダリロールを外してまとめ役のロール1つで開いた行が、その人の見え方と同じになるはずです(今回、セカンダリロールを外してまとめ役のロールで開くと 30行。その人のユーザーでは確かめていません)。ほかのロールも付いている人は、次の節のとおり、利用者ごとに確かめます。支店のロールを2つ持つ人は、ロール1つずつ外して開いても、その人の見え方にはなりません。付け外しも1か所で済みます。その代わり、見せたい支店の組み合わせごとに、まとめ役のロールが1つずつ要ります。
ロールごとにセカンダリロールを外して開き、利用者ごとにロールの組み合わせで開く
ロールごとの確かめは、USE ROLE 〈確かめるロール〉; と USE SECONDARY ROLES NONE; を流してから始めます。NONE はセカンダリロールを止め、すべての権限をプライマリロールから取る指定です。見るのは、行の側と権限の側の両方です。
- 支店のロールで、部署で分けた表を開き、支店ごとの行の数を、そのロールに見せたい行と比べる(今回は東京のロールが東京 20行だけ、大阪のロールが大阪 10行だけ)。
- まとめ役のロールと管理のロールでも同じ表を開き、まとめて見る支店の行がそろうかを見る(まとめ役も SYSADMIN も 30行)。
- 支店のロールで集計を1本流し、ウェアハウスのエラーが出ないかを見る(ウェアハウスの USAGE を付けなかったロールは、ここでエラーになった)。
- 構築の後に作った表を、支店のロールで開く。開けるか、部署で分ける表なら行の数が分かれているかを見る(今後の分の権限が無いとエラー、付けた後に作った表は 1行が見えた)。この4つ目は、表を足すたびに回す。
公式も、ポリシーの管理者が利用者のロールになってクエリを流し、見える行を確かめる方法を挙げています。今回の環境では、その形で確かめるときに、セカンダリロールを外す必要がありました。
ただ、ロールごとに外して開いて分かるのは、そのロール1つの見え方です。実際の利用者には、部署のロールのほかに、別の用途のロールが付いていることがあります。セカンダリロールが ALL の利用者に見える行は、付いているロールすべてで決まるので、ロールごとの確かめが全部合っていても、利用者ごとの見え方は別に確かめる必要があります。
利用者ごとには、まず SHOW GRANTS TO USER 〈利用者〉; でその人に付いたロールを出します(だれにでも付く PUBLIC は一覧に出ません)。確かめる側のユーザーにも同じロールが付いていれば、そのうち1つを USE ROLE で選び、残りを USE SECONDARY ROLES に並べると、その組み合わせで開けます。名前を並べられるのは、自分のユーザーに付いているロールだけです。この手順は今回は流しておらず、公式の SHOW GRANTS と USE SECONDARY ROLES のページの構文と注から組みました。その人のユーザーで開けば、組み合わせを作り直す手間は要りません。
ほかにも、今回試していないことがあります。確かめたのは1人の利用者がロールとセカンダリロールを切り替えた見え方で、部署の人のユーザーでのログインはしていません。行アクセスポリシーを付けたのは元の受注の表だけで、後から作った2つの表(どちらも東京の1行だけ)には付けていません。FUTURE GRANTS を付けた後に、その前に作った表を開き直してもいません。マスキングポリシー(これも Enterprise Edition 以上)、ACCOUNTADMIN で表を作ったときの持ち主の扱い、ポリシーを試すための関数(POLICY_CONTEXT など)、タグで付けるポリシーも試していません。
手元のアカウントでは、まず管理者として部署のロールに切り替え、USE SECONDARY ROLES NONE を流してから、同じ表をもう一度開いてみてください。ALL のときと行の数が違えば、これまでの確かめは、管理者のほかのロールが効いた見え方だったことになります。
部署ごとのロールと行アクセスポリシーの設計から相談したい場合は、当社のSnowflake 導入支援のページをご覧ください。
検証で流したロールとポリシーの SQL
流した SQL のうち、ロール・権限・ポリシー・今後の分の権限の部分です。データベース・スキーマ・受注の表(30行)は先に SYSADMIN で作ってあります。名前の BLOG_DEMO_ は検証用の印で、写真に写っている名前と同じです。表とロールは確かめた後にすべて消しました。
-- 1. ロールと支店の対応表(SYSADMIN で)
USE ROLE SYSADMIN;
CREATE TABLE BLOG_DEMO_DB.SALES.ROLE_BRANCH (ROLE_NAME STRING, BRANCH STRING);
INSERT INTO BLOG_DEMO_DB.SALES.ROLE_BRANCH VALUES ('BLOG_DEMO_TOKYO', '東京'), ('BLOG_DEMO_OSAKA', '大阪');
-- 2. ロールを作り、まとめ役を通して SYSADMIN の下へ。権限を付け、確かめる利用者にも付ける(SECURITYADMIN で)
USE ROLE SECURITYADMIN;
CREATE ROLE BLOG_DEMO_TOKYO;
CREATE ROLE BLOG_DEMO_OSAKA;
CREATE ROLE BLOG_DEMO_MANAGER;
GRANT ROLE BLOG_DEMO_TOKYO TO ROLE BLOG_DEMO_MANAGER;
GRANT ROLE BLOG_DEMO_OSAKA TO ROLE BLOG_DEMO_MANAGER;
GRANT ROLE BLOG_DEMO_MANAGER TO ROLE SYSADMIN;
GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE BLOG_DEMO_TOKYO;
GRANT USAGE ON DATABASE BLOG_DEMO_DB TO ROLE BLOG_DEMO_TOKYO;
GRANT USAGE ON SCHEMA BLOG_DEMO_DB.SALES TO ROLE BLOG_DEMO_TOKYO;
GRANT SELECT ON ALL TABLES IN SCHEMA BLOG_DEMO_DB.SALES TO ROLE BLOG_DEMO_TOKYO;
GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE BLOG_DEMO_OSAKA;
GRANT USAGE ON DATABASE BLOG_DEMO_DB TO ROLE BLOG_DEMO_OSAKA;
GRANT USAGE ON SCHEMA BLOG_DEMO_DB.SALES TO ROLE BLOG_DEMO_OSAKA;
GRANT SELECT ON ALL TABLES IN SCHEMA BLOG_DEMO_DB.SALES TO ROLE BLOG_DEMO_OSAKA;
GRANT ROLE BLOG_DEMO_TOKYO TO USER 〈確かめる利用者〉;
GRANT ROLE BLOG_DEMO_OSAKA TO USER 〈確かめる利用者〉;
GRANT ROLE BLOG_DEMO_MANAGER TO USER 〈確かめる利用者〉;
-- 3. 行アクセスポリシーを作って受注の表に付ける(SYSADMIN で)
USE ROLE SYSADMIN;
CREATE ROW ACCESS POLICY BLOG_DEMO_DB.SALES.RAP_IRS AS (B STRING) RETURNS BOOLEAN ->
EXISTS (SELECT 1 FROM BLOG_DEMO_DB.SALES.ROLE_BRANCH M
WHERE M.BRANCH = B AND IS_ROLE_IN_SESSION(M.ROLE_NAME));
ALTER TABLE BLOG_DEMO_DB.SALES.ORDERS ADD ROW ACCESS POLICY BLOG_DEMO_DB.SALES.RAP_IRS ON (BRANCH);
-- 4. 確かめ(ロールごとに)
USE ROLE BLOG_DEMO_OSAKA;
USE SECONDARY ROLES NONE;
-- 5. 後から作る表の分(SECURITYADMIN で)
USE ROLE SECURITYADMIN;
GRANT SELECT ON FUTURE TABLES IN SCHEMA BLOG_DEMO_DB.SALES TO ROLE BLOG_DEMO_TOKYO;
CURRENT_ROLE で書いた版は、ポリシーの中の IS_ROLE_IN_SESSION(M.ROLE_NAME) を M.ROLE_NAME = CURRENT_ROLE() にしたものです。支店のロールには、行の数を書き込む記録用の表への INSERT も付けました(4つの権限とは別の、検証のためのものです)。
データ分析・データ基盤支援
Snowflake・BigQuery・Treasure Dataといったデータ基盤の選定から、基幹・SaaS・広告・POSに散らばったデータの集約、dbtでの指標統一、Lookerなどでのダッシュボード化までを支援します。
