前回のSnowflake記事では、Snowflakeのロールと権限の仕組み、そしてロールベースアクセス制御(RBAC)でシンプルかつスケーラブルなアクセス階層を構築する方法を、網羅的に解説しました。
本記事ではその続編として、アクセス制御をさらに掘り下げ、立ち上げから運用までのヒントとガイドライン、そして実例を交えてお届けします。
ここで紹介する知見はすべて、Tasman Analyticsで20社を超えるクライアントのSnowflake RBAC階層を設計・実装してきた、現場での実体験に基づくものです。
Tip 1. 最小権限の原則から始める
アクセスモデルを設計し、社内ユーザーへ権限を割り当てる際は、各ユーザーが業務遂行に必要な権限だけを、過不足なく持つ構造を目指しましょう。新任のジュニア財務アナリストに必要なのは貸借対照表テーブルへの参照権限だけなのに、テーブルを削除する権限まで与える必要はありませんよね。
これは最小権限の原則(Principle of Least Privilege)と呼ばれる考え方で、Snowflakeのアクセスモデルに適用すると次のような多くのメリットがあります。
- 外部脅威のリスクと影響の低減: ユーザーのアクセス範囲を必要最小限に絞ることで、偶発的・悪意的なデータ漏洩のリスクを抑えられます。万が一侵害が発生しても、被害は侵害されたアカウントがアクセスできる範囲だけに留まります。
- システム破損リスクの最小化と安定性の向上: アクセスを制限すれば、データの整合性や安定性を損なう変更を防げます。権限の限られたチームメンバーが、データベースを丸ごと削除できるべきではありません! :)
- 監査とモニタリングが容易に: 最低限の権限しか付与しなければ、監視・保守すべき権限の数も自ずと減ります。
- コンプライアンス対応の簡素化: 機密データへのアクセスを必要最小限に絞ることで、GDPRやHIPAAなど(該当する場合)データ保護関連の規制要件への準拠も容易になります。
最小権限の原則は、健全なセキュリティと保守性のバランスが取れた、優れた出発点です。企業によってはセキュリティリスクを許容してよりシンプルなモデルを採用することもあれば、逆により厳格な運用を選ぶこともあるでしょう。ゼロトラストセキュリティモデルとの関係についても、あわせて調べてみることをおすすめします。
Tip 2. アクセスロール・機能ロール・サービスロール
前回の記事では、アカウントロール、データベースロール、インスタンスロールといったさまざまなロールタイプに触れました。これらには技術的にも本質的にも違いがありますが、本記事では話をシンプルに保つためアカウントロールに絞って解説します。
ここで紹介したいのは、ロールを用途で分類するという別の切り口です。具体的には次の3種類です。
- アクセスロール: データベースへのアクセスを制御するためのロール。
- 機能ロール(Functional Role): 社内のSnowflakeユーザーに付与するロール。必要なアクセスロールを組み合わせて付与することで、アクセスレベルを制御します(最小権限の原則に従います)。
- サービスロール: 機能ロールとまったく同じ仕組みですが、エンドユーザー(人間)ではなくサービスに付与する点が異なります。
なお、アクセスロール・機能ロール・サービスロールの間に技術的な違いはありません。いずれもアカウントロールとして作成されます。
アクセスロール
アクセスロールは、データベースおよびデータベースオブジェクトに対するアクセスレベルを定義するためのロールです。階層構造を組み立てる最下層の「部品」と捉えてください。
シンプルな作り方としては、既存のデータベースごとにREADロールとREADWRITEロールを用意する方法があります。
READ: データベース内のすべてのテーブル/ビューに対するSELECT権限を付与。READWRITE:SELECT、INSERT、UPDATE、DELETEの各操作権限を付与。
出発点としては十分ですが、ニーズに応じて、データベース内の特定スキーマだけにアクセスを許可するなど、より細かい粒度のアクセスロールを設計することも可能です。
機能ロール
機能ロールは業務上の職務に沿って設計するロールで、複数のアクセスロールを組み合わせて構成します。例えばDATA_ANALYSTロールには、対象データベース向けに作成したREAD系アクセスロールの権限を継承させ、DATA_ENGINEERロールには同じデータベースのREADWRITE系を継承させるといった具合です。
エンドユーザーに付与するのは、この機能ロールです。 アクセスロールを部品として、(最小権限の原則を念頭に)実際のニーズに合わせて柔軟に組み立てられます。
サービスロール
サービスロールは、本質的には機能ロールとほぼ同じですが、社内ユーザーではなくサービスアカウントに付与する点が異なります。BIやダッシュボードツール、その他SnowflakeのデータベースオブジェクトにREADまたはREADWRITEアクセスを必要とするSaaS(Airbyte、Rudderstack、Modeなど)で利用されます。
機能ロールと同様、アクセスロールを部品にしつつ、最小権限の原則を守りながら実際の用途に合わせて組み立てます。
この3種類のロールがそろえば、シンプルかつ実用的なアクセスロール階層を組み立てるための部品がひととおり揃います。
Tip 3. DRYなロール階層を組み立てる
ソフトウェア開発の重要な原則のひとつに「コードの重複を避ける」というものがあり、頭文字をとってD.R.Y.("Don't Repeat Yourself")と呼ばれます。アクセスロール・機能ロール・サービスロールがあれば、ロール階層の全体像を描き始められます。次の4ステップで進めましょう。
1. 社内で必要な機能ロールとサービスロールを洗い出す
社内のSnowflakeユーザーから要件をヒアリングし、必要な機能ロールと、それぞれに求めるアクセスレベルをリスト化します。このリストが、次に作るべきアクセスロールの設計図になります。
2. アクセスロールを作成する
要件リストが固まれば、必要なアクセスロールが見えてきます。これらを作成し、対象のデータベースオブジェクトに適切な権限を付与します(例: FINANCE_DB_READ_ROLE)。
3. 機能ロール・サービスロールを作成し、アクセスロールを付与する
アクセスロールが整えば、社内メンバー向けの機能ロールやサービス向けのサービスロールを組み立てる準備は完了です。最初に定義した要件を満たすよう、新規に作成した機能ロール/サービスロールにアクセスロールを付与します(例: DATA_ANALYST)。
4. ユーザーに機能ロールを、サービスアカウントにサービスロールを付与する
これでロール階層は完成です。最後に、Snowflakeユーザーには機能ロールを、サービスアカウントにはサービスロールを付与します。調整が必要になったら、ステップ1〜4を繰り返すだけです。
やってはいけないこと…
⛔ アクセスロールをエンドユーザー/サービスアカウントに直接付与しない
機能ロールの層を飛ばしてアクセスロールを直接ユーザーに付与すると、似た職務の新規ユーザーが入るたびに同じ作業を繰り返すことになります。さらに権限を変更する際も、関係するユーザー全員に対して手作業で対応しなければなりません。
機能ロールを介していれば、調整箇所はひとつだけで済みます。その変更は、その機能ロールを持つすべてのユーザーに自動的に反映されます。アクセスロール層は、アカウント全体でデータベースオブジェクトへのアクセスを標準化するためのものであり、直接ユーザーに付与するためのものではありません。
⛔ 機能ロールを別の機能ロールに付与しない
シンプルさを保ちましょう。各機能ロールは、あくまでアクセスロールの組み合わせとして構成すべきです。機能ロール同士の依存関係を持ち込むと、企業の成長や職務の変化につれて構造が一気に複雑化しかねません。
Tip 4. アクセスロール作成時はFuture Grantsを活用する
データベース用のアクセスロールを作ったものの、新しいスキーマやテーブルが追加されるたびに権限を付け直している――そんな状況に心当たりはありませんか? このTipはまさにそうした方のためのものです。Snowflakeでは、データベース内の将来のスキーマや将来のテーブル・ビュー・その他オブジェクトに対して、あらかじめ権限を付与できます。新しいオブジェクトが作成されると、自動的に権限が引き継がれます。
アクセスロールの設計時にFuture Grantsを取り入れておけば、新しいオブジェクトが追加されてもロールに適切な権限が確実に行き渡るため、保守の手間を大幅に減らせます。データベースにオブジェクトが追加されるたびにgrant文を叩く必要はもうありません!
Tip 5. 機能ロールはSYSADMINに付与しておく
カスタムロールは新規作成された時点では孤立した状態にあり、そのロールが作成したオブジェクトも同様に孤立しています。デフォルトでは、ACCOUNTADMINロールですら、カスタムロールが作成したオブジェクトを変更・削除できません。つまり親ロールを持たないままだと、そのロールでしかアクセスできないオブジェクトがアカウント内に生まれてしまうリスクがあります。
カスタムロールをSYSADMINに付与しておけば、少なくともSYSADMIN(およびACCOUNTADMIN)が、そのロールが作成したオブジェクトを管理できるようになります。
そこで、機能ロールはデフォルトでSYSADMINに付与しておくという運用を、ぜひ習慣化しましょう。
Tip 6. Snowflake UIを使い倒す
Snowsightには、Snowflakeアカウント内の既存ロール階層を可視化できる便利な機能があります。作成したロールと、それらのつながりを一目で把握するのに役立ちます。
Users & Roles配下のGraphオプションを開いてみてください。さらにFocusオプションを使えば、特定のロールとその親・子ロールに絞って確認できます。
Tip 7. その作業、ACCOUNTADMINは要らないはず…
言い換えれば、管理操作にはそれぞれにふさわしいロールを使いましょう、ということです。ここでも最小権限の原則をお忘れなく!
ACCOUNTADMINロールは、日常の運用業務に必要な権限よりもはるかに広い権限をデフォルトで持っています。よほどの理由がない限り、使用は避けるべきです。代表的な操作には、次のロールを使い分けましょう。
- ユーザーやロールの作成には
USERADMIN。 - 権限の管理(ユーザーへのロール付与など)には
SECURITYADMIN。 - データベース、スキーマ、仮想ウェアハウスなどオブジェクトの作成には
SYSADMIN。 - テーブルやビューといったデータベース/データベースオブジェクトの作成にも
SYSADMIN。 - 特定テーブルに対するアドホックなデータ操作(
SELECTやINSERTなど)には、適切な機能ロール。 - そしてサードパーティサービスをSnowflakeに接続する場合、
ACCOUNTADMINは絶対に使わないでください! 代わりに専用のサービスロールを作って利用しましょう :)
例えばSELECTのdbt-snowflake-monitoringパッケージは、SNOWFLAKEデータベースに対する特殊な権限IMPORTED PRIVILEGESを必要とし、これはACCOUNTADMINロールでしか付与できません。この場合は、USERADMINでその権限専用のアクセスロールを作成し、ACCOUNTADMINでその権限を付与したうえで、SECURITYADMINを使ってそのアクセスロールをdbt用のサービスロールに紐づけましょう。
学んだことを実践してみよう
シチュエーション
あなたはデータチームに所属するData Engineerで、組織内へのSnowflake導入を任されたばかりです。管理対象は次の3つのデータベースです。
各データベースの概要は次のとおりです。
HR_DB: 従業員や人員数に関するデータを格納。FINANCE_DB: 貸借対照表や財務諸表など、財務関連データを格納。REPORTING_DB: 分析・レポーティング用途のデータを格納。
あなたのミッションは、社内の全員が、これらのデータベースに対して適切なアクセス権を持つように整えることです。
要件
社内のSnowflakeユーザーにヒアリングを行い、次のような要件を集めました。
- FinanceチームとHRチームを支援するData AnalystのRichardは、分析のためにFinanceとHRのすべてのデータを参照したいと希望しています。加えて、Reportingデータベースにレポート用のテーブルを作成できるようにしたいとのことです。
- 社内のData EngineerであるLilyは、過去データをFinanceとHRのデータベースにロードする作業を担当します。
- Financeチームが新たに導入したSaaSツールは、FinanceとHR両方のデータベースからデータを読み取り、加えて処理後のデータをFinanceデータベースに書き戻します。
- Reportingデータベースのデータを参照する、新しいBI・ダッシュボードツールのセットアップも依頼されています。
Snowflake上では、次のコードでデータベースを作成します。
use role SYSADMIN ;
create database FINANCE_DB ;
create database HR_DB ;
create database REPORTING_DB ;
-- テーブル、ビューなどを作成
-- ...
手順
機能ロールとサービスロールを定義する
要件が手元にそろったら、まずは必要なものを正確に洗い出すリストを作りましょう。
機能ロール:
サービスロール:
⚠️ ここでのように、サードパーティツール(Finance SaaS)にデータベースの全スキーマに対する
READWRITE権限を丸ごと与えるのは、実運用では必ずしも最適とは言えません。より現実的なシナリオでは、ツールが実際に読み書きする必要のあるスキーマだけに権限を絞り込みます。本例はあくまで簡略化したモデルだという点にご注意ください。
アクセスロールを作成する
上記の表をもとに、必要なアクセスロールが見えてきます。
HR_READ_ROLEHR_READWRITE_ROLEFINANCE_READ_ROLEFINANCE_READWRITE_ROLEREPORTING_READ_ROLEREPORTING_READWRITE_ROLE
前述のとおり、READロールではSELECTが、READWRITEロールではSELECT、INSERT、UPDATE、DELETEが実行可能になります。図にすると次のようになります。
Snowflakeで実行するステートメントは次のとおりです。
-- HR_DB用のアクセスロールを作成
use role USERADMIN ;
create role HR_READ_ROLE
comment = 'Access Role READ for HR_DB' ;
create role HR_READWRITE_ROLE
comment = 'Access Role READWRITE for HR_DB' ;
-- HR_DB用アクセスロールに権限を付与
use role SECURITYADMIN ;
-- HR_READ_ROLEへの権限付与
-- データベース
grant usage on database HR_DB to role HR_READ_ROLE ;
コードを展開
ここで、データベースとアクセスロールに統一した命名規則を採用しておくと便利です。テンプレートを使った単一スクリプトを用意すれば、複数のデータベースと対応するアクセスロールをまとめて使い回しやすく、デプロイも簡単になります。例を示します。
-- 以下の変数に適切な値を設定
set database_name = 'HR_DB';
set role_read_name = 'HR_READ_ROLE';
set role_readwrite_name = 'HR_READWRITE_ROLE';
-- データベースを作成
use role SYSADMIN ;
create database identifier($database_name) ;
-- 対象データベース用のアクセスロールを作成
use role USERADMIN ;
create role identifier($role_read_name) ;
create role identifier($role_readwrite_name) ;
-- READロールに権限を付与
コードを展開
機能ロールを作成する
アクセスロールが整ったので、ユーザーのニーズを表現する機能ロールを簡単に組み立てられるようになりました。ここからは個別の要件を見ていきます。
まずはRichardの要望から取り上げましょう。
🎯 FinanceチームとHRチームを支援するData AnalystのRichardは、分析のためにFinanceとHRのすべてのデータを参照したいと希望しています。加えて、Reportingデータベースにテーブルを書き込めるようにしたいとのことです。
図示すると次のようになります。
これがRichardのニーズに応えるアクセスロールと機能ロールのシンプルな構成です。ANALYST_ROLEが機能ロールで、HR_READ_ROLE、FINANCE_READ_ROLE、REPORTING_READWRITE_ROLE(いずれもアクセスロール)の親となります。
そのうえでRichardにANALYST_ROLEを付与すれば、HR_DBとFINANCE_DBのテーブルを参照でき、REPORTING_DBのデータを更新できるようになります。同じ職務を担うRichardのチームメンバーにも、同じロールを付与すれば済みます。🎉
Snowflake上のコードは次のようになります。
-- 機能ロール ANALYST_ROLE を作成
use role USERADMIN ;
create role ANALYST_ROLE
comment = 'Functional Role for Data Analysts' ;
-- ANALYST_ROLEに権限を付与
use role SECURITYADMIN ;
grant role HR_READ_ROLE to role ANALYST_ROLE ;
grant role FINANCE_READ_ROLE to role ANALYST_ROLE ;
grant role REPORTING_READWRITE_ROLE to role ANALYST_ROLE ;
-- 機能ロールをSYSADMINに付与(前述のグッドプラクティス)
grant role ANALYST_ROLE to role SYSADMIN ;
コードを展開
同じ考え方をLilyにも当てはめます。
🎯 社内のData EngineerであるLilyは、過去データをFinanceとHRのデータベースにロードする作業を担当します。
Data Engineering向け機能ロールの構成例です。
構成はほぼ同じで、ここではENGINEER_ROLEがHR_READWRITE_ROLEとFINANCE_READWRITE_ROLEの親となり、Lilyに付与されます。
SQLは次のとおりです。
-- 機能ロール ENGINEER_ROLE を作成
use role USERADMIN ;
create role ENGINEER_ROLE
comment = 'Functional Role for Data Engineers' ;
-- ANALYST_ROLEに権限を付与
use role SECURITYADMIN ;
grant role HR_READWRITE_ROLE to role ENGINEER_ROLE ;
grant role FINANCE_READWRITE_ROLE to role ENGINEER_ROLE ;
-- 機能ロールをSYSADMINに付与(前述のグッドプラクティス)
grant role ENGINEER_ROLE to role SYSADMIN ;
コードを展開
続いて、新しいFinance SaaSの要件です。
🎯 Financeチームが新たに導入したSaaSツールは、FinanceとHR両方のデータベースからデータを読み取り、加えて処理後のデータをFinanceデータベースに書き戻します。
こちらも難しくありませんね。図はこちらです。
このケースでは、新しいサービスロールFINANCE_SAAS_ROLEを作成します。基本的な働きは機能ロールと同じですが、人間ではなくプログラムから利用される点が異なります。このロールはFINANCE_READWRITE_ROLEとHR_READ_ROLEの権限を継承し、サービスが利用するSnowflakeサービスアカウントに付与します。
コードはこちらです。
-- サービスロール FINANCE_SAAS_ROLE を作成
use role USERADMIN ;
create role FINANCE_SAAS_ROLE
comment = 'Service Role for Finance SaaS' ;
-- FINANCE_SAAS_ROLEに権限を付与
use role SECURITYADMIN ;
grant role FINANCE_READWRITE_ROLE to role FINANCE_SAAS_ROLE ;
grant role HR_READ_ROLE to role FINANCE_SAAS_ROLE ;
-- サービスロールをSYSADMINに付与(前述のグッドプラクティス)
grant role FINANCE_SAAS_ROLE to role SYSADMIN ;
コードを展開
続いてBIツールのケースです。
🎯 Reportingデータベースのデータを参照する、新しいBI・ダッシュボードツールのセットアップを依頼されています。
もう手慣れたものですね。
このケースでBI_ROLEに必要なアクセスロールはREPORTING_READ_ROLEだけです。これでBIツールは、ダッシュボードを描画するためのSELECTクエリを実行できるようになります! 🎉
コードはこちらです。
-- サービスロール BI_ROLE を作成
use role USERADMIN ;
create role BI_ROLE
comment = 'Service Role for BI and Insights Tool' ;
-- BI_ROLEに権限を付与
use role SECURITYADMIN ;
grant role REPORTING_READ_ROLE to role BI_ROLE ;
-- サービスロールをSYSADMINに付与(前述のグッドプラクティス)
grant role BI_ROLE to role SYSADMIN ;
-- サービスアカウントにロールを付与
コードを展開
まとめ
これですべてのユースケースを満たし、初期ロール階層が完成しました! 全体像は次のとおりです。
おまけ - 変更や調整への対応
DRYな階層のメリットのひとつは、新しい要件が出てきても柔軟に調整できる点です。例えばData EngineerのLilyが、REPORTING_DBへのREADWRITEアクセスを依頼し忘れていたとしましょう。この程度の変更なら、あっという間に対応できます。
-- DATA_ENGINEER機能ロールを調整
use role SECURITYADMIN ;
grant role REPORTING_READWRITE_ROLE to role DATA_ENGINEER ;
これで、新しいビジネス要件にもしなやかに適応できる階層が手に入りました! 🎉
本記事では、Snowflake RBAC階層の構築に役立つヒントやコツを、実例とあわせて紹介しました。Snowflake管理者の日常を少しでも楽にできれば幸いです。ここに載っていない良いTipをご存じでしたら、ぜひお知らせください。記事をアップデートします!
Miguel Duarte・Data Engineer at Tasman Analytics
MiguelはTasman AnalyticsのData Engineerとして、急成長中の企業のデータ活用力強化を支援しています。BIとデータ分析のバックグラウンドを持ち、コンサルティングファームや事業会社で経験を積んできました。最近では、好奇心とデータライフサイクルの技術面により深く関わりたいという思いから、Data Engineeringへキャリアの軸足を移しています。日々Snowflakeなどのツールを駆使し、組織のデータ基盤の構築と最適化に取り組んでいます。