🧻

SnowflakeのAI機能を使ってデータ分析を行うときのロール構成をまとめる

に公開

はじめに

こんにちは。ナウキャストでデータエンジニア/LLMエンジニアとして頑張っているTakumiです。

SnowflakeでAI機能を使ってデータ分析をやろう!という取り組みが増えてきたように感じています。
Snowflake IntelligenceがGAとなったことで、使いやすいUIを伴うデータ分析をSnowflakeのみで完結させることが現実的になりました。
一方でAI機能ごとに権限の要件が微妙に異なるので、最小権限の原則に沿った設計をするのが難しくなったなぁと感じました。

この記事では、SnowflakeのAI機能(対象は後述)を用いて、データ分析を行うときに必要な最小権限を整理します。

この記事でわかること

"AI機能を用いてデータ分析を行いたい。"というユースケースにおける権限設計

対象の機能

今回想定しているユースケースでは以下の機能を対象としています。

  • Cortex AISQL(LLM関数) : 大規模言語モデル(LLM)をSnowflake内で呼び出すSQL関数(例:AI_COMPLETE, AI_EXTRACTなど)。
  • Cortex Analyst : Text2SQLを行うエージェント機能。ビジネスユーザが自然言語質問をすると、セマンティックレイヤーに基づきSQLを生成・実行して回答を返す。
  • Cortex Search : いわゆるRAGを行うサービス。テーブル中のテキストデータに対しハイブリッド検索(ベクトルによる意味検索+キーワード検索)を提供。
  • Cortex Agents : エージェント機能。複数のツール(Cortex AnalystやCortex Search、UDF等)を組み合わせ、ユーザの曖昧な質問をプランニング・分解して解決する対話型AI。
  • Snowflake Intelligence : Cortex Agentに対する問い合わせをSnowSight上で実現できるようにするサービス。
  • カスタムツール(UDF/ストアドプロシージャ) : Cortex Agentに組み込める拡張ツール。ユーザ定義関数やストアドプロシージャとしてビジネス固有のロジックを実装し、エージェントが呼び出せるようにするもの。

ユースケースの具体化

"AI機能を用いてデータ分析を行いたい。"ではユースケースが雑なので、もう少し具体化する。

  • 現実的に考えて、分析対象のデータが1つのDBやスキーマに収まることは少ない想定。
  • 基本的な操作は、自然言語を用いてテーブルからデータを取得すること(Cortex Analyst)。
  • しかし、場合によってはRAGをしたかったり(Cortex Search)、取得したデータに対して特殊な操作をしたい場合(UDF、Stored Procedureの呼び出し)も含まれる。

みたいな状態で必要な権限を考えます。

具体的に必要な権限を整理する

ここからは実際に必要な権限を整理していきましょう。

AI機能を用いてデータ分析を行う際に必要な権限は、大きく2つに分けられます。

  1. AI機能を使うのに必要な権限

    • AISQL(LLM関数)、Cortex Analyst、Cortex Search、Cortex AgentなどのAI機能自体を実行するための権限
    • 主にSnowflakeが提供するデータベースロール(SNOWFLAKE.CORTEX_***系)によって制御されます
  2. AI機能でデータを触るのに必要な権限

    • データベース、スキーマ、テーブル、ビュー、Semantic View、Search Service、Agentなどのオブジェクトへのアクセス権限
    • データの読み取り、オブジェクトの作成・編集・利用などに必要な権限

以下では、これらの権限を機能ごとに詳しく見ていきます。なお、AI機能で参照するDB, SCHEMA, TABLE, VIEW等の参照権限は持っているものとします。

AISQL(LLM関数)に必要な権限

AISQL(COMPLETE, SUMMARIZE, CLASSIFY など)を実行するためには、Snowflake が提供するデータベースロール SNOWFLAKE.CORTEX_USER が必要です。これは Snowflake が提供する AI 機能の中でも最も基本的な権限をまとめたデータベースロールで、LLM 関数を実行する権限を付与できます。

データベースロールSNOWFLAKE.CORTEX_USERは、デフォルトでPUBLICにGRANTされています。
そのため、AI機能を細かく権限制御したいニーズがある場合のみ、より細かいデータベースロールののGRANT, REVOKEが必要になります。

SNOWFLAKE.CORTEX_USER の構造

Snowflake の AI 機能系データベースロールは階層構造になっており、用途別に細かくコントロールできます。
”特定のユーザーにSEARCH SERVICEを作らせる必要はないけど、Agentは実行できて欲しいとき”みたいな細かい粒度でも対応可能です。

SNOWFLAKE.CORTEX_USER
├─ SNOWFLAKE.CORTEX_ANALYST_USER – Cortex Analyst を実行する権限
├─ SNOWFLAKE.CORTEX_AGENT_USER – Cortex Agent を実行する権限
└─ SNOWFLAKE.CORTEX_EMBED_USER – ベクトル埋め込み生成の権限(Search Service作成に必要)

ここから先は何かしらの形でAISQLを使うので、この権限をすでに持っている前提で最小権限を検討します。

Cortex Analystに必要な権限

Cortex Analystを呼び出す時は先程紹介したデータベースロールがあれば機能します。
それに加えて、Semantic Layer周りの権限が必要になります。ここでは、Semantic Viewを使う場合を検討しましょう。

Semantic Viewを使うとき

Semantic View 作成
  • USAGE on DB
  • USAGE on Schema
  • CREATE SEMANTIC VIEW on Schema
Semantic View 利用
  • SELECT on semantic view
  • REFERENCES on semantic view

があれば、Semantic Viewの作成〜Cortex Analystの呼び出しまでできます。
(Semantic ViewのOwnership権限を持っているときは不要。)

SELECTとREFERENCEの役割

両方付与されていないときは1枚目のエラー、どちらかが付与されていないときは2枚目のエラーが発生しました。
NotAuthrizedBOTH
NotAuthrizedEACH

Semantic Viewのドキュメントを読む限りは、

権限 役割
REFERENCES Semantic View の「構造(メトリクス・ディメンション)」を読む権限(DESCRIBEコマンド実行可能)。データは返さない。Analyst がメタデータを読むために必要。
SELECT Semantic View を 実行して “論理的な結果セット” を生成する 権限。元テーブルの SELECT は不要。

みたいな感じでした。
そのためSEMANTIC VIEWそのものの情報と集計した情報両方取得できることが、Cortex Analystを動かす条件になっているのだろうと思っています。

Semantic Modelは?

Deprecated

Cortex Searchに必要な権限

Cortex Search Serviceを作るとき

CORTEX SEARCHを作成する時に必要な権限は以下の通りです。

  • CREATE CORTEX SEARCH SERVICE権限(or 作成するスキーマのOWNERSHIP権限)
    • CORTEX SEARCH SERVICEはスキーマレベルのオブジェクトなので、作成対象スキーマのOWNERSHIPあれば作成可能
  • 検索対象となるテーブル(非構造化データ加工後のテーブル)へのSELECT権限
  • 検索対象テーブルが格納されているDB, スキーマのUSAGE権限

Cortex Search Serviceを使うとき

  • CORTEX SEARCH SERVICEおよびそのDB、スキーマのUSAGE権限

Cortex Agentに必要な権限

Cortex Agentを使う際には、ここまでで作成してきたサービスのUSAGE権限に加えてエージェントオブジェクトに関する権限が必要になります。ユーザーが自由にエージェントを作成して、改善活動ができるような状態を実現するには、

  • CREATE AGENT権限 (or 作成するスキーマのOWNERSHIP権限)
    • CORTEX AGENTはスキーマレベルのオブジェクトなので、作成対象スキーマのOWNERSHIPあれば作成可能
  • USAGE AGENT権限(エージェントを実行して応答を得る)
  • MODIFY AGENT権限(エージェントの設定を編集する)
  • MONITOR AGENT権限(エージェントの実行ログを参照する)
    あたりが必要になります。

また、AGENTへカスタムツールを付与して使いたい場合は、そのカスタムツール(UDF, STORED PROCEDURE)のUSAGE権限が必要になります。

ロール付与設計の例

必要な権限は整理できました。ここからは実際にアカウントロールを設計、付与する時にどのような権限ツリーを構築するかを検討しましょう。

方針としては、次の三層に分けて設計します。

  • データベースロール
    • 「どのDB/Schema/Table/Viewにアクセスできるか」をまとめる
    • AI機能についてデータベースロールとしてまとめる
  • SNOWFLAKE データベースロール(CORTEX_* 系)**
    • 「どのAI機能を呼び出せるか」をまとめる(これは既にSnowflake内に用意されているので構築は不要)
  • Account Role
    • 2種類の人物像を想定して作成
      • AI_ANALYST : 既存のSemantic View / Cortex Search / Agentを使って自然言語で分析する人(ビジネスユーザー層)
      • AI_BUILDER : Semantic ViewやCortex Search、Agent自体を設計・作成・改善する人(エンジニア)

この設計例では、以下のデータベースとスキーマを使用します。

  • SALES_DB : セールスデータを格納するデータベース
    • SALES_DB.PUBLIC : セールスデータのテーブルを格納するスキーマ
    • SALES_DB.SEMANTIC : Semantic Viewを格納するスキーマ
  • MKT_DB : マーケティングデータを格納するデータベース
    • MKT_DB.ANALYTICS : マーケティング分析用のテーブルを格納するスキーマ
  • DOC_DB : ドキュメント検索用のデータベース
    • DOC_DB.SEARCH : Cortex Search Serviceを格納するスキーマ
  • AI_DB : AI機能のオブジェクト(Cortex Agent等)を格納するデータベース
    • AI_DB.PUBLIC : Cortex Agentを格納するスキーマ
  • UTIL_DB : ユーティリティ関数(UDF、ストアドプロシージャ)を格納するデータベース
    • UTIL_DB.UTILS : カスタムツール用のUDFやストアドプロシージャを格納するスキーマ
  • SNOWFLAKE : Snowflakeが提供するデータベースロール(CORTEX_***系)が格納されているデータベース

1. データベースロール: データソースごとの読み取り権限をまとめる

まず、各データベースごとに「分析に使うテーブルへの読み取り権限」をまとめた データベースロール を作成します。

SALES_DB / MKT_DB の例
SALES_DB の データベースロール
USE DATABASE SALES_DB;

CREATE DATABASE ROLE DATA_READ_ANALYST;

GRANT USAGE ON DATABASE SALES_DB
  TO DATABASE ROLE DATA_READ_ANALYST;

GRANT USAGE ON ALL SCHEMAS IN DATABASE SALES_DB
  TO DATABASE ROLE DATA_READ_ANALYST;

GRANT SELECT ON ALL TABLES IN SCHEMA SALES_DB.PUBLIC
  TO DATABASE ROLE DATA_READ_ANALYST;

-- FUTURE GRANTS(必要に応じて)
-- GRANT SELECT ON FUTURE TABLES IN SCHEMA SALES_DB.PUBLIC
--   TO DATABASE ROLE DATA_READ_ANALYST;

注: 上記のDATA_READ_ANALYSTはデータベースロール名です。

MKT_DB の データベースロール
USE DATABASE MKT_DB;

CREATE DATABASE ROLE DATA_READ_ANALYST;

GRANT USAGE ON DATABASE MKT_DB
  TO DATABASE ROLE DATA_READ_ANALYST;

GRANT USAGE ON ALL SCHEMAS IN DATABASE MKT_DB
  TO DATABASE ROLE DATA_READ_ANALYST;

GRANT SELECT ON ALL TABLES IN SCHEMA MKT_DB.ANALYTICS
  TO DATABASE ROLE DATA_READ_ANALYST;

注: 上記のDATA_READ_ANALYSTはデータベースロール名です。

Semantic View(Cortex Analyst) / Cortex Search Service 用の データベースロール

Semantic View(Cortex Analyst) と Cortex Search Service の利用権限も データベースロール としてまとめます。これにより、権限管理の見通しが良くなります。

SALES_DB の Semantic View 用 データベースロール
USE DATABASE SALES_DB;

CREATE DATABASE ROLE SEMANTIC_VIEW_ANALYST;

GRANT USAGE ON DATABASE SALES_DB
  TO DATABASE ROLE SEMANTIC_VIEW_ANALYST;

GRANT USAGE ON SCHEMA SALES_DB.SEMANTIC
  TO DATABASE ROLE SEMANTIC_VIEW_ANALYST;

GRANT SELECT, REFERENCES
  ON SEMANTIC VIEW SALES_DB.SEMANTIC.SALES_ANALYST_VIEW
  TO DATABASE ROLE SEMANTIC_VIEW_ANALYST;

-- FUTURE GRANTS(必要に応じて)
-- GRANT SELECT, REFERENCES ON FUTURE SEMANTIC VIEWS IN SCHEMA SALES_DB.SEMANTIC
--   TO DATABASE ROLE SEMANTIC_VIEW_ANALYST;

注: 上記のSEMANTIC_VIEW_ANALYSTはデータベースロール名です。

DOC_DB の Search Service 用 データベースロール
USE DATABASE DOC_DB;

CREATE DATABASE ROLE SEARCH_SERVICE_ANALYST;

GRANT USAGE ON DATABASE DOC_DB
  TO DATABASE ROLE SEARCH_SERVICE_ANALYST;

GRANT USAGE ON SCHEMA DOC_DB.SEARCH
  TO DATABASE ROLE SEARCH_SERVICE_ANALYST;

GRANT USAGE ON SEARCH SERVICE DOC_DB.SEARCH.CUSTOMER_DOC_SEARCH
  TO DATABASE ROLE SEARCH_SERVICE_ANALYST;

-- FUTURE GRANTS(必要に応じて)
-- GRANT USAGE ON FUTURE SEARCH SERVICES IN SCHEMA DOC_DB.SEARCH
--   TO DATABASE ROLE SEARCH_SERVICE_ANALYST;

注: 上記のSEARCH_SERVICE_ANALYSTはデータベースロール名です。

2. SNOWFLAKE データベースロールの整理(AI機能ごとの権限)

AI機能ごとの権限は Snowflake が提供している SNOWFLAKE データベースロール によってコントロールされます。

必要に応じて、AI_ANALYST_ROLE / AI_BUILDER_ROLE(アカウントロール)に紐づけます。

SNOWFLAKE データベースロール付与例
-- Analyst / Agent 機能を利用するためのデータベースロール
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_ANALYST_USER TO ROLE AI_ANALYST_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER   TO ROLE AI_ANALYST_ROLE;

-- Builder はさらに幅広い権限を持つ
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_ANALYST_USER TO ROLE AI_BUILDER_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER   TO ROLE AI_BUILDER_ROLE;
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_EMBED_USER   TO ROLE AI_BUILDER_ROLE;

3. Account Role: 「使う人」と「作る人」を分ける

先ほどの方針に従って、ACCOUNT ROLEを作成しましょう。

Account Role の作成
CREATE ROLE AI_ANALYST_ROLE;
CREATE ROLE AI_BUILDER_ROLE;
3-1. AI_ANALYST_ROLE(利用者用アカウントロール)

AI_ANALYST_ROLE は 既存の仕組みを使うだけ のアカウントロールです。

含めるもの

  • DB の読み取りデータベースロール
  • Cortex Analyst / Agent の SNOWFLAKE データベースロール
  • Semantic View 用のデータベースロール
  • Search Service 用のデータベースロール
  • Agent の USAGE
AI_ANALYST_ROLE の権限付与
-- 各DBの読み取りデータベースロールを継承
GRANT DATABASE ROLE SALES_DB.DATA_READ_ANALYST
  TO ROLE AI_ANALYST_ROLE;

GRANT DATABASE ROLE MKT_DB.DATA_READ_ANALYST
  TO ROLE AI_ANALYST_ROLE;

-- Cortex Analyst / Agent を使うためのデータベースロール
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_ANALYST_USER
  TO ROLE AI_ANALYST_ROLE;

GRANT DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER
  TO ROLE AI_ANALYST_ROLE;

-- Semantic View の利用(database role 経由)
GRANT DATABASE ROLE SALES_DB.SEMANTIC_VIEW_ANALYST
  TO ROLE AI_ANALYST_ROLE;

-- Cortex Search Service の利用(database role 経由)
GRANT DATABASE ROLE DOC_DB.SEARCH_SERVICE_ANALYST
  TO ROLE AI_ANALYST_ROLE;

-- Agent の利用
GRANT USAGE
  ON AGENT AI_DB.PUBLIC.CUSTOMER_QA_AGENT
  TO ROLE AI_ANALYST_ROLE;

-- Warehouse 利用
GRANT USAGE ON WAREHOUSE ANALYSIS_WH TO ROLE AI_ANALYST_ROLE;
AI_ANALYST_ROLE をユーザーに付与
GRANT ROLE AI_ANALYST_ROLE TO USER alice;
ALTER USER alice SET DEFAULT_ROLE = AI_ANALYST_ROLE;
ALTER USER alice SET DEFAULT_WAREHOUSE = ANALYSIS_WH;
3-2. AI_BUILDER_ROLE(構築者/改善者用アカウントロール)

AI_BUILDER_ROLE は、Semantic View / Search Service / Agent の 作成・編集 を行うアカウントロールです。

AI_BUILDER_ROLE の権限付与
-- AI_ANALYST_ROLE を継承
GRANT ROLE AI_ANALYST_ROLE TO ROLE AI_BUILDER_ROLE;

-- Semantic View 作成
GRANT CREATE SEMANTIC VIEW
  ON SCHEMA SALES_DB.SEMANTIC
  TO ROLE AI_BUILDER_ROLE;

-- Cortex Search Service 作成
GRANT CREATE CORTEX SEARCH SERVICE
  ON SCHEMA DOC_DB.SEARCH
  TO ROLE AI_BUILDER_ROLE;

-- Agent 作成・編集・監視
GRANT CREATE AGENT
  ON SCHEMA AI_DB.PUBLIC
  TO ROLE AI_BUILDER_ROLE;

GRANT MODIFY, MONITOR
  ON ALL AGENTS IN SCHEMA AI_DB.PUBLIC
  TO ROLE AI_BUILDER_ROLE;

-- 埋め込み生成権限(Search Service 作成時)
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_EMBED_USER
  TO ROLE AI_BUILDER_ROLE;

-- UDF / Stored Procedure の利用
GRANT USAGE
  ON FUNCTION UTIL_DB.UTILS.SPECIAL_METRIC(NUMERIC)
  TO ROLE AI_BUILDER_ROLE;

GRANT USAGE
  ON PROCEDURE UTIL_DB.UTILS.CLEANSE_RAW_DATA()
  TO ROLE AI_BUILDER_ROLE;
AI_BUILDER_ROLE をユーザーに付与
GRANT ROLE AI_BUILDER_ROLE TO USER <your_user_name>;
ALTER USER <your_user_name> SET DEFAULT_ROLE = AI_BUILDER_ROLE;
ALTER USER <your_user_name> SET DEFAULT_WAREHOUSE = ANALYSIS_WH;

4. 最終的に作成されるロールツリー

これまでの操作でできるアカウントロールは以下の通りとなります。

(Account Roles)
  AI_ANALYST_ROLE
    ├─ DATABASE ROLE SALES_DB.DATA_READ_ANALYST
    ├─ DATABASE ROLE MKT_DB.DATA_READ_ANALYST
    ├─ DATABASE ROLE SNOWFLAKE.CORTEX_ANALYST_USER
    ├─ DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER
    ├─ DATABASE ROLE SALES_DB.SEMANTIC_VIEW_ANALYST
    ├─ DATABASE ROLE DOC_DB.SEARCH_SERVICE_ANALYST
    └─ USAGE on existing AGENTs

  AI_BUILDER_ROLE
    ├─ (inherits) AI_ANALYST_ROLE
    ├─ CREATE SEMANTIC VIEW on target schemas
    ├─ CREATE CORTEX SEARCH SERVICE on target schemas
    ├─ CREATE AGENT on AI schema
    ├─ MODIFY / MONITOR on AGENTs
    └─ DATABASE ROLE SNOWFLAKE.CORTEX_EMBED_USER

AI機能のオブジェクト(Cortex Agent, Cortex Search Service, Semantic View)の作成場所はデータの置き場と分けるべきか否か

今回は、AI機能のオブジェクトのためにデータベース、スキーマを専用で作成して置き場を分けました。
Snowflakeの公式ドキュメントにベストプラクティスとして明確な推奨があるわけではありません。
長期間運用を前提としたときは、データベース、スキーマレベルで分離したほうが良さそうに感じています。

以下の理由から、今回のような専用データベース、スキーマを分けています。

1. 所有者権限(OWNERSHIP)の影響範囲を小さくするため

Semantic View / Cortex Search Service / Agent は所有者ロールを使った操作によって、

  • オブジェクト定義の変更
  • 権限付与/剥奪
  • 場合によっては、そのオブジェクトを経由したデータアクセスの範囲

に強い影響を持ちます。

データそのものを保持しているDBと、AI機能用オブジェクトのDBを分離しておくことで、

  • 「生データDBのOWNERロール」
  • 「AIオブジェクト(Semantic View / Agent / Search Service)のOWNERロール」

を見通しをよくした上で分けやすくなります。
結果として、AI機能側の設定ミスや権限の付けすぎによる“巻き込み範囲”を限定しやすいというメリットがあります。

2. ロール設計をシンプルにするため

現実的な運用を考えると、

  • 生データやDWHを管理するチーム(Data Platform / DWHチーム)
  • AI機能やエージェントを管理するチーム(AI Platform / LLMチーム)
  • それらを利用して分析するビジネスユーザー(BI / Bizチーム)

のように、担当が分かれるケースが多くなります。

データベース/スキーマを

  • データ用:SALES_DB, MKT_DB, DOC_DB など
  • AI用  :AI_DB

のように分けておくと、

  • 「どのDBのOWNERロールをどのチームに渡すか」
  • 「どのAccount RoleがどのDatabase Roleを引き継ぐか」

をRBACのツリーとして整理しやすいと感じています。

まとめ

複雑なアカウントロール構造にすることなく、今回のデモとしては動くことが確認できました。

やっていることはこれまでのSnowflakeが推奨しているアクセス制御と同等のつもりです。 このテックブログが生成AIの肥やしになって、誰かがLLMに聞いた時にベストプラクティスとなってくれると嬉しいです。

Finatext Tech Blog

Discussion