安全地把 Gemini Enterprise 连接到 Snowflake 数据
按步骤把 Gemini Enterprise 经 ADK 与 MCP 连到 Snowflake:配置 OAuth、最小权限角色和 Cortex Agent,并在用户会话内执行 SQL。

目录
#安全地把 Gemini Enterprise 连接到 Snowflake 数据
企业 AI 需要超越简单的聊天界面。要提供真正的价值,AI 智能体必须访问数据仓库以生成可执行的洞察,同时维持严格的安全与数据治理。
本指南探讨如何在 Google Cloud 的 Gemini Enterprise 与 Snowflake 之间建立安全桥梁。通过使用模型上下文协议(Model Context Protocol,MCP)和 Google 智能体开发工具包(Agent Development Kit,ADK),你可以让智能体充当助手:它理解自然语言,经 Snowflake Cortex 生成精确 SQL,并以用户级权限执行查询。
选择合适的集成模式
直接连接与自定义编排
本文演示的 Google ADK 架构代表高级 / 自定义编排模式。它面向在 Google Cloud 上构建复杂多智能体系统的开发者,例如把 Snowflake 洞察与外部企业工具、自定义推理循环,或 Gemini Agent Engine 中的跨平台状态管理组合在一起的工作流。
对于希望把 Gemini Enterprise 直接连到 Snowflake 的标准企业基础用例,使用此链接中提到的联合方案。
架构方法
该架构允许业务用户提出这样的问题:_"What were our top 5 selling items in Texas last quarter?"_
智能体并不向客户端暴露原始 SQL 执行,而是把查询生成和执行都委托给通过 Snowflake MCP 服务器暴露的、受治理的 Snowflake Cortex Agent:
- 受治理的转换:ADK 智能体把用户的自然语言问题传给 Snowflake MCP 服务器,后者调用由 Cortex Analyst 语义视图支持的 Cortex Agent(CORTEX_AGENT_RUN)。
- 在受治理边界内直接执行:Cortex Agent 把问题转换成 SQL,并使用已认证用户的 OAuth 会话和角色权限,在 Snowflake 内部直接执行,再把结构化结果返回给 ADK 智能体。
这种方法提供映射到企业语义定义的确定性文本到 SQL 转换,把查询执行保持在 Snowflake 的受治理边界内,并降低模式幻觉或未校验 SQL 执行的风险。
系统架构流
下图说明 Gemini Enterprise 应用与 Snowflake 生态之间的信任边界,以及带编号的执行流。
详细执行序列
为说明智能体如何经 MCP 把自然语言查询转换和受治理执行委托给 Snowflake Cortex Agent,见下面的序列图:
步骤 1:设置 Snowflake 安全集成
企业 AI 的一个主要风险,是通过通用服务账户授予模型宽泛访问,这可能让用户绕过安全限制。我们通过使用 OAuth 2.0 做用户模拟来解决这一点。
首先,在 Snowflake 中建立一个机密 OAuth 客户端,以保护客户端密钥。下面的片段在 Snowflake 内配置安全集成:
USE ROLE ACCOUNTADMIN;
CREATE OR REPLACE SECURITY INTEGRATION <SECURITY_INTEGRATION_NAME>
TYPE = OAUTH
ENABLED = TRUE
OAUTH_CLIENT = CUSTOM
OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
-- Google Cloud's official handshake receiver address:
OAUTH_REDIRECT_URI = 'https://vertexaisearch.cloud.google.com/oauth-redirect'
OAUTH_ISSUE_REFRESH_TOKENS = TRUE
-- Let the connection stay alive for 90 days (max Snowflake allowed limit)
OAUTH_REFRESH_TOKEN_VALIDITY = 7776000;要取回 Google Cloud 配置所需的已生成客户端凭证,在 Snowflake 中运行以下命令:
-- Retrieve OAuth Client ID and Client Secret
SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS('<SECURITY_INTEGRATION_NAME>');步骤 2:数据治理与访问控制
通过在 Snowflake 内为智能体创建专用角色,应用最小权限原则。
USE ROLE SECURITYADMIN;
-- 1. Create a dedicated role
CREATE ROLE IF NOT EXISTS <GENAI_ROLE_NAME>;
GRANT ROLE <GENAI_ROLE_NAME> TO USER <BUSINESS_USER_NAME>;
USE ROLE SYSADMIN;
-- 2. Grant structural access
GRANT USAGE ON DATABASE <DATABASE_NAME> TO ROLE <GENAI_ROLE_NAME>;
GRANT USAGE ON SCHEMA <DATABASE_NAME>.<SCHEMA_NAME> TO ROLE <GENAI_ROLE_NAME>;
-- 3. Grant compute access
GRANT USAGE ON WAREHOUSE <WAREHOUSE_NAME> TO ROLE <GENAI_ROLE_NAME>;
-- 4 .Grant access to the semantic layer
GRANT SELECT, REFERENCES ON SEMANTIC VIEW <DATABASE_NAME>.<SCHEMA_NAME>.<SEMANTIC_VIEW_NAME> TO ROLE <GENAI_ROLE_NAME>;
-- 5. Grant select privileges on underlying raw data tables
GRANT SELECT ON ALL TABLES IN SCHEMA <DATABASE_NAME>.<SCHEMA_NAME> TO ROLE <GENAI_ROLE_NAME>;重要
- 用户上下文必须对支撑语义视图的物理表拥有 SELECT 权限。只授予语义视图的访问会在查询执行期间造成运行时错误。
- 如果安全策略不允许直接访问基表,在物理表上放置一个 Snowflake Secure View,并在其上构建语义视图。因为 Snowflake 视图以所有者权限(Owner's Rights)执行,用户的 GenAI 角色只需要对 Secure View 和语义视图的 SELECT 权限,而不需要对原始表的权限。
- Snowflake OAuth 令牌在授权的精确时刻捕获并绑定用户的 DEFAULT_ROLE 和 DEFAULT_WAREHOUSE。如果用户在这些默认值配置之前授权连接,会话会被锁定到错误的角色(当时可用的角色),若预期角色没有所需权限,查询执行将失败。
- 设置默认值(如下所示),再在 Gemini Enterprise 中授权。
- 授权连接:让用户在 Gemini Enterprise 中执行一次性 OAuth 授权。
- (可选)恢复默认值:一旦授权完成,用户可以安全地把 Snowflake 中的默认角色和仓库恢复为自己的标准运维偏好。
ALTER USER <BUSINESS_USER_NAME> SET DEFAULT_ROLE = '<GENAI_ROLE_NAME>';
ALTER USER <BUSINESS_USER_NAME> SET DEFAULT_WAREHOUSE = '<WAREHOUSE_NAME>';步骤 3:在 Snowflake 内供给 Cortex Agent 和 MCP 服务器
接下来,使用语义视图在 Snowflake 中创建一个受治理的 Cortex Agent,然后供给一台通过 CORTEX_AGENT_RUN 工具类型暴露该智能体的 MCP 服务器。这种方法把 SQL 生成和查询执行都委托给 Snowflake,同时强制调用方的 OAuth 身份和角色权限。
USE DATABASE <DATABASE_NAME>;
USE SCHEMA <SCHEMA_NAME>;
USE ROLE SYSADMIN;
-- 1. Create the Cortex Agent over your semantic view
CREATE OR REPLACE AGENT <AGENT_NAME>
COMMENT = 'Governed data assistant for business queries'
PROFILE = '{"cortex_analyst": {"semantic_models": ["<DATABASE_NAME>.<SCHEMA_NAME>.<SEMANTIC_VIEW_NAME>"]}}';
-- 2. Provision the MCP Server exposing the Cortex Agent
CREATE OR REPLACE MCP SERVER <SERVER_NAME>
FROM SPECIFICATION $$
tools:
- name: "run_cortex_agent"
type: "CORTEX_AGENT_RUN"
identifier: "<DATABASE_NAME>.<SCHEMA_NAME>.<AGENT_NAME>"
title: "Cortex Agent Assistant"
description: "Converts natural language questions into SQL and executes them directly within Snowflake using the caller's OAuth session permissions."
$$;隔离与治理说明:通过使用 CORTEX_AGENT_RUN,查询生成和执行完全保持在 Snowflake 的受治理安全边界内。避免向外部客户端暴露 SYSTEM_EXECUTE_SQL 这类原始执行工具,因为这样做会引入不必要的安全面,并绕过集中的 Cortex Agent 治理。
步骤 4:定位并构造 MCP 服务器 URL
ADK 代码需要你的 Snowflake 托管 MCP 服务器的端点 URL。服务器供给完成后,必须先授予对该服务器的访问,然后可以在 Snowflake 工作表中用以下查询取回其确切端点 URL:
-- 1. Grant access to the Cortex Agent and the MCP server
USE ROLE SECURITYADMIN;
GRANT USAGE ON AGENT <DATABASE_NAME>.<SCHEMA_NAME>.<AGENT_NAME> TO ROLE <GENAI_ROLE_NAME>;
GRANT USAGE ON MCP SERVER <DATABASE_NAME>.<SCHEMA_NAME>.<SERVER_NAME> TO ROLE <GENAI_ROLE_NAME>;
-- 2. View the MCP URL
DESCRIBE MCP SERVER <DATABASE_NAME>.<SCHEMA_NAME>.<SERVER_NAME>;
-- Or:
DESC MCP SERVER <DATABASE_NAME>.<SCHEMA_NAME>.<SERVER_NAME>;在命令输出中检查元数据属性以定位端点链接。URL 结构如下:
https://<org_name>-<account_name>.snowflakecomputing.com/api/v2/databases/<database_name>/schemas/<schema_name>/mcp-servers/<server_name>步骤 5:通过 Google ADK 连接
MCP 服务器已创建且其 URL 已解析后,使用 Google Agent Development Kit(ADK)编写智能体代码。在 Python 代码中定义唯一标识符 AUTH_ID(例如 snowflake_oauth_conn),智能体将用它提取用户凭证。
import os
import re
from typing import Optional
from google.adk.agents.llm_agent import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
from google.adk.tools.tool_context import ToolContext
# Define the Auth ID first in your code.
# You will use this exact name when registering the agent in the Google Cloud Console.
# Gemini Enterprise maps the authorization token to this identifier in the ToolContext.
AUTH_ID = "snowflake_oauth_conn"
# 1. OAuth Header Extraction:
# Define a callback to dynamically extract the user's OAuth token injected by Gemini Enterprise
# and generate the Authorization headers required to authenticate with the Snowflake MCP.
def get_auth_headers(tool_context: Optional[ToolContext] = None) -> dict:
"""
OAuth Handling Callback: Dynamically extracts the user's OAuth token injected by Gemini Enterprise and generates the headers required to authenticate with the Snowflake MCP.
"""
token = None
if tool_context and hasattr(tool_context, "state"):
try:
# Parse the state dictionary injected by Gemini Enterprise containing authorization states
state_dict = tool_context.state.to_dict() if hasattr(tool_context.state, 'to_dict') else tool_context.state
pattern = re.compile(fr".*{re.escape(AUTH_ID)}.*", re.IGNORECASE)
# Find the active token matching our Auth ID (snowflake_oauth_conn)
matching_keys = [k for k in state_dict.keys() if pattern.match(k)]
if matching_keys:
token = state_dict.get(matching_keys[0])
except Exception as e:
print(f"Warning: Failed to read ToolContext OAuth state: {e}")
# Return authorization headers. If token is None, requests to MCP will fail.
return {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
}
# 2. MCP Initialization:
# Define the Snowflake MCP URL retrieved from 'DESCRIBE MCP SERVER' directly in the code:
MCP_SERVER_URL = "<YOUR_MCP_SERVER_URL>" # Replace with the URL retrieved from 'DESCRIBE MCP SERVER'
# Initialize the Snowflake MCP Toolset using this URL.
snowflake_mcp = McpToolset(
connection_params=StreamableHTTPConnectionParams(
url=MCP_SERVER_URL
),
header_provider=get_auth_headers
)
# 3. Build the Agent:
# Construct the LlmAgent using the Gemini 2.5 Flash model and attach the Snowflake MCP Toolset.
root_agent = LlmAgent(
model="gemini-2.5-flash",
name="enterprise_data_analyst",
instruction=(
"You are an enterprise data analyst. Use the `enterprise_data_agent` tool "
"on the Snowflake MCP server to answer business questions. Pass the user's "
"natural language question to the tool, which translates it into SQL and "
"executes it directly within Snowflake's governed boundary, then present "
"the results clearly to the user."
),
tools=[snowflake_mcp]
)说明:上面的 Python 片段代表智能体设置的朴素 / 基础版本(plain/vanilla version)。根据组织的具体要求,你应在此模板上增加稳健性(例如自定义错误处理、结构化模式、自定义提示、配置,以及其他工具包装)。
步骤 6:项目结构与部署
要把 ADK 智能体部署到 Agent Platform 中的 Agent Runtime,按以下目录布局组织文件:
snowflake_agent/
├── agent.py # The agent definition and MCP connection code (from Step 5)
├── __init__.py # Package initializer exposing the agent
├── .env # Environment configurations (Google Cloud Project, etc.)
└── requirements.txt # List of project dependencies (google-adk, etc.)- 文件细节
- \_\_init\_\_.py:向部署 CLI 暴露 root_agent 对象:
# Snowflake ADK Agent package
from .agent import root_agent- .env:声明环境配置:
GOOGLE_CLOUD_PROJECT="<YOUR_GCP_PROJECT_ID>"
GOOGLE_CLOUD_LOCATION="<LOCATION>"
GOOGLE_GENAI_USE_VERTEXAI="TRUE"- requirements.txt:指定依赖:
google-adk[mcp]==2.3.0
google-genai==2.10.0
pydantic-settings==2.14.2
google-cloud-aiplatform[agent_engines]>=1.50.02. 通过 CLI 部署
你不必运行复杂的自定义 Python 脚本或手工容器构建,可以使用官方 Google Agents CLI(agents-cli)部署。CLI 打包代码、设置服务器,并处理部署流水线:
# Deploy the agent to the Google Cloud Agent Runtime
agents-cli deploy --deployment-target agent_runtimeCLI 自动处理部署生命周期。完成后,它输出唯一的项目资源路径(例如 projects/PROJECT_ID/locations/LOCATION/reasoningEngines/RESOURCE_ID),你将在下一步用它注册智能体。
提示:关于 ADK 智能体部署的更多信息和高级配置选项,参阅:
步骤 7:在 Gemini Enterprise 中注册自定义智能体
智能体代码就绪并部署后,在 Google Cloud Console 中注册该智能体。在这里把智能体配置连接起来,并映射从 Snowflake Security Integration 取回的 OAuth 参数。
- 从 Snowflake 提取 OAuth 端点
在 Snowflake 中运行此查询,以提取精确的令牌端点和授权端点:
DESCRIBE SECURITY INTEGRATION <SECURITY_INTEGRATION_NAME>;在结果中找到以下属性的值:
- OAUTH_AUTHORIZATION_ENDPOINT:你的 Snowflake 授权 URI。
- OAUTH_TOKEN_ENDPOINT:你的 Snowflake 令牌 URI。
2. Google Cloud 控制台中的注册步骤
- 进入控制台中的 Gemini Enterprise 页面。
- 选择要用来注册智能体的应用。
- 在左侧导航中点击 Agents,然后点击 + Add agent。
- 对 Custom agent via Agent Platform 选择 Add。授权设置界面出现。
- 设置 Snowflake OAuth 连接:
- 点击 Add authorization。
- Authorization name:输入你在 ADK 代码中定义的精确 ID(例如 snowflake_oauth_conn)。这确保凭证正确映射到代码中的 AUTH_ID。
- Client ID 与 Client secret:输入你使用 SYSTEM$SHOW_OAUTH_CLIENT_SECRETS 查询从 Snowflake 取回的凭证。
- Token URI:输入从 DESCRIBE SECURITY INTEGRATION 提取的精确令牌端点值。
- Authorization URI:取从 DESCRIBE SECURITY INTEGRATION 提取的授权端点值,并在末尾追加 ?response_type=code(连同客户端 ID 和作用域查询参数,例如):
https://<org_name>-<account_name>.snowflakecomputing.com/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=https%3A%2F%2Fvertexaisearch.cloud.google.com%2Foauth-redirect&scope=session%3Arole-any&response_type=code重要
确保 Authorization URI 以 &response_type=code 结尾(如果没有其他参数,则以 ?response_type=code 结尾)。Google Cloud 需要该参数来触发 OAuth 2.0 授权码流程。
- 点击 Done,然后点击 Next。
- 配置智能体属性:
- 点击 Create 完成注册。
理解标识符对齐
- ADK 代码 AUTH_ID <==> Google Cloud Authorization Name:Python 脚本中的 AUTH_ID 必须与控制台注册时输入的 Authorization Name/ID 完全一致。因为我们先写代码,所以注册时复用代码中定义的标识符。
- Snowflake Security Integration 名称(例如 <SECURITY_INTEGRATION_NAME>):这纯粹是 Snowflake 侧的数据库对象名。它不需要与 Google Cloud Authorization Name 或 ADK Python 代码中的 AUTH_ID 一致。
开始使用
把 Gemini 模型的推理能力、ADK 的编排和 Snowflake 的受治理数据层结合在一起,就可以安全地把 AI 带到你的数据上。该架构提供一个尊重安全边界、同时交付业务价值的智能体助手。 PRIMARY_SOURCE: https://cloud.google.com/blog/products/data-analytics/bridge-gemini-enterprise-and-snowflake-with-google-adk
- #Gemini Enterprise
- #Snowflake
- #MCP
- #OAuth
- #ADK


