0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Databricks から Snowflake-managed MCP Server を使ってみる ― Microsoft Entra ID(M2M)と Snowflake OAuth(U2M)を検証

0
Posted at

はじめに

Snowflake では、Snowflake-managed MCP Server を利用することで、MCP(Model Context Protocol)クライアントから Snowflake 上のデータや機能にアクセスできます。

一方、Databricks では外部の MCP Server を HTTP Connection として接続し、Unity Gateway の MCP サービスとして公開することで、Databricks 上のエージェントやアプリケーションから利用できます。

そこで本記事では、Snowflake-managed MCP Server を Databricks から利用する構成を実際に構築し、以下の2つの OAuth 認証方式を検証します。

  • Microsoft Entra ID を利用した OAuth 認証(M2M)
  • Snowflake OAuth を利用した OAuth 認証(U2M)

M2M では、Microsoft Entra ID の Client Credentials Flow で取得したアクセストークンを Snowflake の External OAuth で検証し、Snowflake のサービスユーザーおよびロールへマッピングします。

一方、U2M では Snowflake OAuth を利用し、Databricks の HTTP Connection から Snowflake にサインインすることで、ユーザー単位の認証を行います。

さらに、作成した Snowflake-managed MCP Server を Databricks の HTTP Connection に登録し、Unity Gateway の MCP サービス経由で tools/list を実行できるところまで確認します。

本記事では、それぞれの認証方式について、Snowflake・Microsoft Entra ID・Databricks の設定手順と、実際の接続確認結果を順番に紹介します。

それぞれの認証では以下の構成にします。

  • Microsoft Entra ID を利用した OAuth 認証(M2M)
  • Snowflake OAuth を利用した OAuth 認証(U2M)

Microsoft Entra ID を利用した OAuth 認証(M2M)

1. Snowflake で MCP を作成する

Snowflake-managed MCP Server を作成します。

本検証では、SYSTEM_EXECUTE_SQL(SQL 実行)ツールを使用しました。

CREATE OR REPLACE MCP SERVER <DATABASE_NAME>.<SCHEMA_NAME>.DEMO_MCP_01
  FROM SPECIFICATION $$
    tools:
      - title: "SQL Execution Tool"
        name: "sql_exec_tool"
        type: "SYSTEM_EXECUTE_SQL"
        description: "SQL 実行"
        config: 
            read_only: false
            query_timeout: 600
            warehouse: "MCP_WH"
  $$;

DESCRIBE MCP SERVER DEMO_MCP_01;

image.png

2. Snowflake に MCP 用ロールを作成する

MCP 専用ロールを作成します。

CREATE ROLE IF NOT EXISTS MCP_ROLE;

必要な権限を付与します。

GRANT USAGE ON DATABASE <DATABASE_NAME>
TO ROLE MCP_ROLE;

GRANT USAGE ON SCHEMA <DATABASE_NAME>.<SCHEMA_NAME>
TO ROLE MCP_ROLE;

GRANT USAGE ON WAREHOUSE MCP_WH
TO ROLE MCP_ROLE;

GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA <DATABASE_NAME>.<SCHEMA_NAME> TO ROLE MCP_ROLE;

GRANT USAGE
ON MCP SERVER <DATABASE_NAME>.<SCHEMA_NAME>.DEMO_MCP_01
TO ROLE MCP_ROLE;

3. Entra ID に Snowflake OAuth Resource 用アプリ登録を作成する

Entra ID で Snowflake OAuth Resource 用アプリ登録を作成します。

項目 設定値
名前 snowflake-mcp-resource
アカウントの種類 シングル テナントのみ

image.png

続いて、Snowflake OAuth Resource 用アプリ登録 → API の公開 を選択して、Application ID URI を設定します。

設定する値は以下です。

api://<snowflake-mcp-resource_CLIENT_ID>

image.png

最後に MCP アクセス用 App Role を作成します。

Snowflake OAuth Resource 用アプリ登録 → アプリ ロール を選択して、以下のように適用します。

項目 設定値
表示名 MCP Role
メンバーの種類 アプリケーション
値 session:role:MCP_ROLE
説明 Snowflake MCP access

image.png

4. Databricks アクセス用アプリ登録を作成する

Databricks アクセス用アプリ登録を作成します。

手順は以下の記事の 7-2. をご参照ください。Client ID と Client Secret を控えておきます。

作成後、API のアクセス許可を付与します。

Databricks アクセス用アプリ登録 → API のアクセス許可 を選択して、以下のように追加します。

項目 設定値
アクセス許可の種類 アプリケーションの許可
アクセス許可 session:role:MCP_ROLE

image.png

その後、「管理者の同意」を実行します。

5. アクセス トークンの中身を確認する

Azure Portal の Cloud Shell で以下を実行します。

アクセス トークンの取得
TOKEN=$(curl -sS \
  -X POST \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=<CLIENT_ID>" \
  --data-urlencode "client_secret=<CLIENT_SECRET>" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=api://<RESOURCE_APP_CLIENT_ID>/.default" \
  "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token" \
  | jq -r '.access_token')
アクセス トークンのデコード
python3 - <<'PY'
import os
import json
import base64

token = os.environ["TOKEN"]

payload = token.split(".")[1]
payload += "=" * (-len(payload) % 4)

data = json.loads(
    base64.urlsafe_b64decode(payload)
)

print(json.dumps(data, indent=2))
PY

出力結果は以下のようになります。

{
  "aud": "api://<snowflake-mcp-resource_CLIENT_ID>",
  "iss": "https://sts.windows.net/<TENANT_ID>/",
  "sub": "xxxxxxxxxxxxxxxxxxxxxxxx",
  "roles": [
    "session:role:MCP_ROLE"
  ],
  ...
}

image.png

特に、session:role:MCP_ROLE が入っていない場合は、アプリ ロール、API のアクセス許可、管理者の同意を確認します。

後続で使用する sub と iss の値を控えておきます。

6. sub を Snowflake USER へマッピングする

sub の値を Snowflake USER の LOGIN_NAME に設定します。

Snowflake で以下を実行します。

CREATE OR REPLACE USER MCP_USER
    TYPE = SERVICE
    LOGIN_NAME = '<sub と一致する値>'
    DEFAULT_ROLE = MCP_ROLE
    DEFAULT_WAREHOUSE = MCP_WH;

ロールを付与します。

GRANT ROLE MCP_ROLE
TO USER MCP_USER;

7. External OAuth Security Integration を作成する

Snowflake に External OAuth Security Integration を作成します。

CREATE OR REPLACE SECURITY INTEGRATION MCP_DEMO_OAUTH
    TYPE = EXTERNAL_OAUTH
    ENABLED = TRUE
    EXTERNAL_OAUTH_TYPE = AZURE
    EXTERNAL_OAUTH_ISSUER =
        '<iss と一致する値>'
    EXTERNAL_OAUTH_JWS_KEYS_URL =
        'https://login.microsoftonline.com/<TENANT_ID>/discovery/v2.0/keys'
    EXTERNAL_OAUTH_AUDIENCE_LIST =
        ('api://<snowflake-mcp-resource_CLIENT_ID>')
    EXTERNAL_OAUTH_TOKEN_USER_MAPPING_CLAIM = 'sub'
    EXTERNAL_OAUTH_SNOWFLAKE_USER_MAPPING_ATTRIBUTE = 'LOGIN_NAME';

DESC SECURITY INTEGRATION MCP_DEMO_OAUTH;

image.png

8. Snowflake MCP Server に External OAuth をバインドする

MCP Server が存在する Schema に設定します。

ALTER SCHEMA POC_DB.MCP
SET
    OAUTH_AUTHORIZATION_SERVER = MCP_DEMO_OAUTH
    OAUTH_SCOPES_SUPPORTED = 'session:role:MCP_ROLE';

SHOW PARAMETERS LIKE 'OAUTH_%'
IN SCHEMA POC_DB.MCP;

image.png

9. Databricks HTTP Connection を作成

Databricks で HTTP Connectionを作成します。

Databricks アクセス用アプリ登録の Client ID と Client Secret は Databricks Secret に保管して利用しています。

from databricks.sdk import WorkspaceClient
from databricks.sdk.service import catalog

w = WorkspaceClient()

# Databricks アクセス用アプリ登録の Client ID と Client Secret 
client_id = dbutils.secrets.get(catalog="<CATALOG_NAME>", schema="<SCHEMA_NAME>", key="<CLIENT_ID_SECRET_NAME>")
client_secret = dbutils.secrets.get(catalog="<CATALOG_NAME>", schema="<SCHEMA_NAME>", key="<CLIENT_SECRET_SECRET_NAME>")

connection = w.connections.create(
    name="connection_snow_sql_mcp_server_m2m",
    connection_type=catalog.ConnectionType.HTTP,
    parent="schemas/<CATALOG_NAME>.<SCHEMA_NAME>",
    options={
        "host": "https://<SNOWFLAKE_ACCOUNT_URL>",
        "port": "443",
        "base_path": "/api/v2/databases/<DATABASE>/schemas/<SCHEMA>/mcp-servers/<MCP_SERVER>",
        "client_id": client_id,
        "client_secret": client_secret,
        "oauth_scope": 'api://<snowflake-mcp-resource_CLIENT_ID>/.default',
        "token_endpoint": "https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token",
    },
    comment="Snowflake 管理 MCP サーバーへの M2M 接続",
)
print(connection.full_name)

image.png

10. MCP サービスの作成

次に MCP サービスを作成します。

以下の記事の「MCP サービスの作成」をご参照ください。

MCP サービス経由で Python でツール一覧を取得できることを確認しました。

%pip install -U databricks-mcp nest_asyncio
dbutils.library.restartPython()
import nest_asyncio
nest_asyncio.apply()

from databricks_mcp import DatabricksMCPClient
from databricks.sdk import WorkspaceClient

w = WorkspaceClient()

host = w.config.host

mcp_url = f"{host}/ai-gateway/mcp-services/<MCP_SERVICE_NAME>"

client = DatabricksMCPClient(
    server_url=mcp_url,
    workspace_client=w
)

tools = client.list_tools()

for t in tools:
  print("Tool: ", t.name)
  print("Description: ", t.description)
  print("Schema: ", t.input_schema)
  print("-----")

image.png

トライアル環境で発生したエラー

トライアル環境では tools/list までは成功しましたが、MCP ツールの実行で以下のエラーが発生しました。

MCP error calling tool sql_exec_tool:
Agent error (code 399504):
Access denied for trial accounts.

ツール実行まで検証する場合は、通常のアカウントでの再検証が必要です。

認証から MCP ツールの実行までの流れは以下です。

11. アクセス確認

ログイン履歴を確認できます。

MCP_USER としてログインしていることが確認できました。

ALTER SESSION SET TIMEZONE = 'Asia/Tokyo';
SELECT
    *
FROM TABLE(
    INFORMATION_SCHEMA.LOGIN_HISTORY(
        TIME_RANGE_START => DATEADD('hour', -1, CURRENT_TIMESTAMP()),
        TIME_RANGE_END   => CURRENT_TIMESTAMP(),
        RESULT_LIMIT     => 100
    )
)
ORDER BY EVENT_TIMESTAMP DESC;

image.png

ドキュメントには OAuth ログインを許可した Security Integration も確認できる列がありそうでしたが、対象列を確認できませんでした。

image.png

https://docs.snowflake.com/en/sql-reference/functions/login_history

Snowflake OAuth による認証(U2M)

1. OAuth Security Integration を作成する

Snowflake に OAuth Security Integration を作成します。

CREATE OR REPLACE SECURITY INTEGRATION MCP_OAUTH_DATABRICKS
  TYPE = OAUTH
  OAUTH_CLIENT = CUSTOM
  ENABLED = TRUE
  OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
  OAUTH_REDIRECT_URI = 
      'https://<Databricks Workspace>/login/oauth/http.html';

image.png

作成後、OAUTH_CLIENT_ID と OAUTH_CLIENT_SECRET を控えておきます。

SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS(
    'MCP_OAUTH_DATABRICKS'
);

image.png

また、OAUTH_AUTHORIZATION_ENDPOINT と OAUTH_TOKEN_ENDPOINT の値を控えておきます。

DESC SECURITY INTEGRATION MCP_OAUTH_DATABRICKS;

image.png

2. Databricks HTTP Connectionを作成

Databricks で HTTP Connectionを作成します。

Snowflake OAuth Security Integration の OAUTH_CLIENT_ID と OAUTH_CLIENT_SECRET は Databricks Secret に保管して利用しています。

from databricks.sdk import WorkspaceClient
from databricks.sdk.service import catalog

w = WorkspaceClient()

# Snowflake OAuth Security Integration の Client ID と Client Secret 
client_id = dbutils.secrets.get(catalog="<CATALOG_NAME>", schema="<SCHEMA_NAME>", key="<CLIENT_ID_SECRET_NAME>")
client_secret = dbutils.secrets.get(catalog="<CATALOG_NAME>", schema="<SCHEMA_NAME>", key="<CLIENT_SECRET_SECRET_NAME>")

connection = w.connections.create(
    name="connection_snow_sql_mcp_server_u2m",
    connection_type=catalog.ConnectionType.HTTP,
    parent="schemas/<CATALOG_NAME>.<SCHEMA_NAME>",
    options={
        "host": "https://<SNOWFLAKE_ACCOUNT_URL>",
        "port": "443",
        "base_path": "/api/v2/databases/<DATABASE>/schemas/<SCHEMA>/mcp-servers/<MCP_SERVER>",
        "client_id": client_id,
        "client_secret": client_secret,
        "authorization_endpoint": "<OAUTH_AUTHORIZATION_ENDPOINT>",
        "token_endpoint": "<OAUTH_TOKEN_ENDPOINT>",
    },
    comment="Snowflake 管理 MCP サーバーへの U2M 接続",
)
print(connection.full_name)

image.png

作成後、HTTP Connection の UI 画面で Snowflake にサインインします。

image.png

高権限ロールによるアクセスエラー

※本番環境では専用ロールを推奨

デフォルトロールが ACCOUNTADMIN の場合、サインイン時に以下のようなエラーが発生します。

The role requested has been explicitly blocked
for use with this application by an administrator.

Please try logging in with a different role,
or contact your administrator.

Snowflake ではデフォルトで以下の高権限ロールが OAuth 利用からブロックされています。

ACCOUNTADMIN
SECURITYADMIN
ORGADMIN
GLOBALORGADMIN

高権限ロールの OAuth 利用を許可し、Security Integration の許可ロールに追加します

ALTER ACCOUNT SET
OAUTH_ADD_PRIVILEGED_ROLES_TO_BLOCKED_LIST = FALSE;

ALTER SECURITY INTEGRATION <SECURITY_INTEGRATION_NAME>
SET ALLOWED_ROLES_LIST = (
    'ACCOUNTADMIN'
);

DESC SECURITY INTEGRATION MCP_OAUTH_DATABRICKS;

image.png

3. MCP サービスの作成

次に MCP サービスを作成します。

以下の記事の「MCP サービスの作成」をご参照ください。

MCP サービス経由で Python でツール一覧を取得できることを確認しました。

%pip install -U databricks-mcp nest_asyncio
dbutils.library.restartPython()
import nest_asyncio
nest_asyncio.apply()

from databricks_mcp import DatabricksMCPClient
from databricks.sdk import WorkspaceClient

w = WorkspaceClient()

host = w.config.host

mcp_url = f"{host}/ai-gateway/mcp-services/<MCP_SERVICE_NAME>"

client = DatabricksMCPClient(
    server_url=mcp_url,
    workspace_client=w
)

tools = client.list_tools()

for t in tools:
  print("Tool: ", t.name)
  print("Description: ", t.description)
  print("Schema: ", t.input_schema)
  print("-----")

image.png

4. アクセス確認

ログイン履歴を確認できます。

個別ユーザーとしてログインしていることが確認できました。

ALTER SESSION SET TIMEZONE = 'Asia/Tokyo';
SELECT
    *
FROM TABLE(
    INFORMATION_SCHEMA.LOGIN_HISTORY(
        TIME_RANGE_START => DATEADD('hour', -1, CURRENT_TIMESTAMP()),
        TIME_RANGE_END   => CURRENT_TIMESTAMP(),
        RESULT_LIMIT     => 100
    )
)
ORDER BY EVENT_TIMESTAMP DESC;

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?