概要
権限まわりを検証する際は、セカンダリロールにより「想定より強い権限」で SQL を実行している可能性がある点に注意が必要です。特に、オブジェクト作成はプライマリロールの指定が必須である一方で、権限判定そのものはセカンダリロールを含めた有効ロール集合で行われます。このため「Snowflake は指定したロールでのみ動作する仕様である」と誤解しないようにしてください。
本稿ではセカンダリロールの概要を整理したうえで、私が実際に遭遇した失敗例を解説します。権限関連のオブジェクトを検証する場面では、意図したロールで検証するために USE SECONDARY ROLES を明示することが実務上ほぼ必須になり得ます。
また、運用時においても下記のクエリを実行し、セカンダリロールの状態を確認することをおすすめします。
| default_secondary_roles |
|---|
| ["ALL"] |
下記図は生成 AI により生成した本記事の概要です。
セカンダリロール
セカンダリロールとは
Snowflake のセカンダリロールは、1つだけ選ぶ「プライマリロール」に加えて、ユーザーに付与済みの他ロールをセッション内で同時にアクティブ化し、権限判定に含める機能です。USE SECONDARY ROLES で切り替えでき、各 SQL 実行時に有効ロールの集合は再評価されます。詳細はドキュメントを参照し、仕様と利用方法を理解することをおすすめします。
すべてのアクティブユーザーセッションは、 プライマリロール とも呼ばれる、現在のロールを持っています。
さらに、 セカンダリ ロールのセットは、ユーザーセッションでアクティブにすることができます。ユーザーは、プライマリロールとセカンダリロールに付与された集約権限を使用して、セッション内のオブジェクトに対して SQL アクションを実行できます。
出所: アクセス制御の概要 | Snowflake Documentation
ユーザーのデフォルトのセカンダリロール(つまり、ALL)または設定されていない場合は NULL を指定します。
出所: USERS ビュー | Snowflake Documentation
ユーザーが特定のセカンダリロールを使用できるようにするには、以下を実行します。
出所: セッションポリシーの使用 | Snowflake Documentation
セッションのアクティブ/現在のセカンダリロールを指定します。現在アクティブなセカンダリロールは、現在のユーザーが SQL アクションを実行するために必要な権限を持っているかどうかを決定するコンテキストを設定します。
出所: USE SECONDARY ROLES | Snowflake Documentation
プライマリロールはCREATE <オブジェクト>ステートメントのみプライマリロールで実行可能
CREATE <オブジェクト>ステートメント 実行時にはプライマリロールのみに制限されます。一方で、ALTER <オブジェクト> は(セカンダリロールを含む)有効ロール集合の権限により実行できてしまう点に注意が必要です。セカンダリロールの仕様に気づかずに操作すると、本番環境のオブジェクト設定を意図せず変更してしまうリスクがあります。後述するケースでは、あるオブジェクトの作成に伴い、ソーステーブルのプロパティが変更されていたことにより状況整理に時間を要しました。
オブジェクトを作成するために CREATE <オブジェクト> ステートメントを実行する認証は、プライマリロールによって提供されることに注意してください。
出所: USE SECONDARY ROLES | Snowflake Documentation
他データベースのエンジニアにとっての違和感への対処
他のデータベースに慣れているユーザーからすると、ロールを明示的に指定する運用に違和感を覚え、通常の挙動に見えるかもしれません。他データベースに慣れた開発者は、Snowflake ではロールを重視する傾向があるため、本仕様と既存運用の両方を踏まえた理解が必要です。新規導入であれば他データベースに近い運用設計に寄せる選択肢もありますが、運用済みの場合に運用を無理に変更して現場の混乱を招くべきではありません。
セカンダリロールの利用指針
私の考えとしては、他のデータベースと同様の運用に揃えることを前提に、原則としてセカンダリロールの利用は許容し、例外として制限すべきだと考えています。なお、ここで示す方針は記事執筆時点の見解であり、今後の検討内容や運用状況に応じて変更する可能性があります。
-
ACCOUNTADMINのように過剰な権限を持つロールは、セッションポリシーのBLOCKED_SECONDARY_ROLESにより、セカンダリロールとして利用できないようにすること - データベースオブジェクトの作成、ならびにデータベースオブジェクト作成を伴う処理(dbt 等)を実行する場合は、プライマリロールを明示的に指定すること
- データベースオブジェクト管理ユーザーについては、オペレーションミスを防ぐ観点から、セッションポリシーの
BLOCKED_SECONDARY_ROLESにより、セカンダリロールを禁止すること - セキュリティ上保護すべきデータにアクセス可能なロールについては、セッションポリシーの
BLOCKED_SECONDARY_ROLESにより、セカンダリロールを禁止すること
また、実運用に適用する際は、まつば~らさんの 【Snowflake】最強の呪文 SECONDARY ROLES を制御・制限しよう の記事において、適用方法が網羅的に検証されており参考になります。
私の失敗
STREAM 作成時にソーステーブルのプロパティが変更される事象
STREAM 作成時には、ソーステーブルで CHANGE_TRACKING が有効化されている必要があり、権限が不足する場合にはエラーとなるとドキュメントに記載されています。
ステートメントを実行するユーザーが十分な権限(OWNERSHIP)を持つロールを指定していない場合、ステートメントは失敗し、基礎となるデータベースオブジェクトは更新されず、ロックが解除されます
引用: ストリームの管理 | Snowflake Documentation
CHANGE_TRACKING が無効なテーブルに対して STREAM を作成しようとした場合、実行ロールにソーステーブルのプロパティを変更する権限を付与していないため、STREAM 作成は下記のようにエラーになる想定でした。
SQL access control error: Insufficient privileges to operate on stream source without CHANGE_TRACKING enabled 'TABLE_10'.
それにもかかわらず STREAM を作成できてしまい、SELECT 権限しか付与していないはずのソーステーブルに対して、CHANGE_TRACKING の設定を変更してしまいました。下記が実行できたのは、セカンダリロール側で当該テーブルに対する OWNERSHIP 権限を保持していたためでした。
USE ROLE STREAM_ROLE_01;
CREATE OR REPLACE STREAM CHANGE_TRACKING_TEST_02.SCHEMA_02.TABLE_10__STREAM_01
ON TABLE TABLE_10
SHOW_INITIAL_ROWS = TRUE;
そこで、想定の動作を得るためには USE SECONDARY ROLES にてセカンダリロールを無効化してから実行する必要があります。検証用環境では実運用より強い権限が付与されているケースが多いため、意図した権限検証になっているかを明示的に揃えることが重要です。
USE ROLE STREAM_ROLE_01;
USE SECONDARY ROLES NONE;
CREATE OR REPLACE STREAM CHANGE_TRACKING_TEST_02.SCHEMA_02.TABLE_10__STREAM_01
ON TABLE TABLE_10
SHOW_INITIAL_ROWS = TRUE;
この事象を整理すると、STREAM 作成そのものは「STREAM を作成する権限」だけで完結しているのではなく、必要に応じて「ソーステーブル側の CHANGE_TRACKING を有効化する」という副作用を伴う点がポイントです。CHANGE_TRACKING が無効な状態で STREAM を作成すると、内部的にはソーステーブルに対するプロパティ変更(CHANGE_TRACKING=TRUE 相当)が必要になり、これを実行できる権限を(プライマリロールまたはセカンダリロールのいずれかで)保持していると、STREAM 作成が成功します。
逆に言えば、プライマリロール単体では当該権限を持っていない設計であっても、セカンダリロールにより権限が補われていると、検証時に「本来エラーになるはずの操作が通る」状態が発生し得ます。
セカンダリロールを考慮せずに検証してしまうことで、誤った結論に至る可能性がありました。









