使用说明
Apigee示例-MCP的外部访问控制
此存储库显示了一种包装不安全MCP服务器的方法 使用Apigee代理强制外部定义的访问 控制决策。
许多人认为MCP足够不同,需要 不同的网关,网络中完全不同的方法。
但这和你已经知道的没什么不同。
- MCP使用JSONRPC,众所周知,自2010年以来一直在使用
- MCP远程传输使用HTTP
- MCP安全建立在OAuth之上
听起来很熟悉?如果你有Apigee,你已经有了一个可以 为这种API风格提供正确的治理。
访问控制选项
可以包括 基本的 使用Apigee进行访问控制 Apigee配置流语言。我所说的“基本”是指,你有可能 配置API代理以检查入站请求是否呈现令牌, 以及入站令牌对于给定操作是否有效。但这是一个 “面向客户端”的授权检查-它不考虑 附加用户-并且它是静态的。
但是要在Apigee API代理中包含更多的动态访问控制,通常 会想 外化 访问控制决策,并允许Apigee 执行决定。这个外部化的决定可能依赖于任何武断的决定 数据,包括用户呼叫的身份、环境数据、最近的历史记录 对于该特定用户,一天中的时间等。
此存储库显示了一种实现方式,该实现涉及:
- MCP服务器,用Python实现,在云端运行
- 在Apigee X(云)中配置的API代理,代理到该服务器
- 一 分开 Cloud Run服务,用C#实现,用于做出访问控制决策
- Apigee代理中的ExternalCallout策略,用于调用访问控制云运行服务
萤幕录影
有一个 截屏视频 这表明 这一切是如何运作的。我鼓励你去看看!
免责声明
这个例子不是谷歌的官方产品,也不是 谷歌官方产品。这只是一个例子。
需要大量组装
这个例子依赖于许多运动部件和系统:
- 开放ID连接身份提供者
- 使用Python和FastMCP实现的MCP服务器,部署到Cloud Run
- 在C#中实现的授权规则服务器。NET,部署到云运行
- 包含上述授权服务器规则的电子表格
- Apigee的几个API代理
对我来说,这是一项巨大的努力,比我目前能够承诺的要大 与经过完全测试的工作代码和脚本共享一个仓库,使您能够 自己复制所有这些。
但无论如何,我都会发布代码和配置,因为我认为 只要阅读和检查运动部件就会有所帮助。
背景
基础 使用Apigee配置流语言在Apigee中进行访问控制很容易。对于
例如,配置Apigee API代理以允许访问非常容易,只有当调用方
提供有效令牌(使用内置的Apigee策略
OAuthV2,
与操作= VerifyAccessToken).或者有效的、未过期的API密钥(使用内置Apigee
政策
VerifyAPIKey).
在简单的情况下,OAuthV2/VerifyAccessToken策略看起来像这样:
<OAuthV2 name="OAuthV2-Verify-Access-Token">
<Operation>VerifyAccessToken</Operation>
</OAuthV2>
VerifyAPIKey策略看起来像这样:
<VerifyAPIKey name="APIKeyVerifier">
<APIKey ref="request.queryparam.apikey" />
</VerifyAPIKey>
在前一种情况下,当然,依赖于OAuthV2访问令牌的调用应用程序必须 先前已经通过某种授权流获得了访问令牌。这只是标准 OAuthV2模型,没什么新鲜事。
但正如你所看到的,无论是使用密钥还是令牌,控件都是 二元的。调用者具有对有效的密钥或令牌 当前通话,否则不会。如果你想要更细粒度的控制,特别是 使用MCP服务器和工具,您需要更多的控制和灵活性 粗粒度检查可以提供。
API产品用于访问控制
为了超越基本检查,Apigee采用了API产品概念。 API发布者可以配置特定的客户端凭据(客户端ID或API密钥) 获得特定API产品的授权。这些产品实际上只是 API代理,带元数据。每个入站请求都会提供一个凭据 将解析为有效的API产品。 然后,在运行时,Apigee将验证所提供的应用程序客户端凭据是否 授权用于API产品,该产品包括 当前API请求正在使用。
对API产品概念和隐含动词+路径进行15分钟的截屏回顾 授权检查, 看这里。但基本原则是:
-
配置时:
- API发行商定义API产品。每个包含1个或多个动词+路径对。
- 客户端开发人员获取其应用程序的凭据(客户端ID)。每个凭证都被授权用于一个或多个API产品。
- 客户端开发人员将这些凭据嵌入到他们构建的应用程序中。
-
运行时:
- 客户端应用程序发送GET/foo(动词=GET,路径=/foo)。
- 当您调用VerifyAPIKey或VerifyAccessToken时,Apigee会检查密钥或令牌。
- 如果有效,Apigee 隐含地 检查谓词+路径对是否经由与凭证相关联的API产品中的至少一个被授权。
除了基础知识之外,您还可以配置Apigee来检查Access Token上的作用域。
有一个方便的 试验样品 这将引导你完成这一过程,实际上是在Apigee工作。来看看吧.
那么更灵活的控制呢?
这里缺少的一件事是“基于角色的访问控制”,即/k/a RBAC, 这将允许基于 人的身份 操作应用程序。ABAC也不见了,什么 OWASP称之为“基于属性 访问 控制”, 这不仅允许基于呼叫者的角色或身份进行控制 基于其他数据,如:工作角色、时间、项目名称、发起IP地址, 记录创建日期、之前的活动模式等。Apigee没有好的 该机制本身用于执行逐个用户的RBAC或更通用的ABAC。
为了实现基于用户的RBAC或更通用的ABAC,典型的模式是 外化 访问控制决策并使用Apigee 强制执行 决定。你会用这个 作为对 Apigee可以对API产品进行的基本授权检查。
它处理呼入呼叫的方式(无论是MCP还是其他变体):
-
Apigee运行时收集或确定它需要通知的所有信息 访问控制决策。这可能是关于请求用户的信息 计费帐户状态、最近活动的模式等。通常是用户 信息是从ID令牌之类的东西中获得的,该令牌由 独立身份提供者。
-
Apigee向外部访问控制系统发送访问控制请求。这 请求必须包括外部系统需要创建的所有元数据 决定。调用者的身份、所请求的资源、特定的 请求的操作、源IP地址等。无论需要什么。
-
外部系统做出决定(允许或拒绝),并将其发送回Apigee。
-
然后Apigee API代理强制执行该决定。
此存储库中包含的示例显示了如何使用 定制的Cloud Run服务,用于外部化MCP服务器的访问控制决策。
实现细节
这里的例子显示了基本思想。 这是它的工作原理。
-
客户端应用程序(例如代理)向Apigee API代理发送MCP呼叫请求。这个电话 必须在授权标头中包含访问令牌。
-
Apigee API代理验证访问令牌,检查它是否 对给定的代理有效。
-
如果通过,Apigee API代理将调用 外部访问控制 服务,传递它{jwt有效载荷,MCP方法,MCP 工具}。这个服务恰好是用C#实现的,但这只是一个 细节。
-
访问控制服务使用Google Sheets REST API来检索访问控制 谷歌表格中的规则。此数据缓存在访问控制服务中。
-
访问控制服务对入站数据应用访问规则。 它使用访问令牌上的“az_groups”声明以及MCP动词和工具来查找 匹配规则。如果存在ALLOW条目,则请求为 允许。否则,不会。
服务向代理返回“ALLOW”或“DENY”。
-
代理执行该决定, 否则发出403状态。
规则如下:
以及评估请求是否应该被授权的逻辑,
一些实施说明:
-
在步骤1中,通过以下方式获得代理发送的访问令牌 OAuthV2授权码授权类型,来自OpenID Connect服务器 已注册特定MCP服务器。你需要提供自己的 OIDC服务器。
您可以使用 Auth0.com; 有关说明,请参阅 Auth0设置.
无论您使用何种OIDC服务器,它都必须发出一个带有声明的访问令牌 其中的“az_groups”应该是字符串列表。这 访问控制 服务器 检查该声明以确定是否 允许请求。
-
API代理假定JWKS端点在
${OIDC_SERVER}/jwks令牌发行者与${OIDC_SERVER}url。 -
访问控制服务是GRPC服务。这意味着它将相对较快 从您的Apigee API代理调用,效率高,并且应该是可接受的 对每个API请求进行检查。如果相对较低的延迟仍然没有 如果可以接受,您可以将规则评估逻辑移动到Apigee代理本身中。 此处未显示。
为什么不使用OPA进行访问控制?
好问题!! 开放策略代理 很好 用于存储、管理和评估访问规则的解决方案,适用于任意系统或 资源。它是开源的,维护良好,可以作为可部署的容器使用 图像。您可以部署 集装箱 图像 有权参加Cloud Run之类的活动; 无需构建代码。
听起来不错,对吧?这 一个缺点 我看到的是,OPA依赖于 雷戈 表达政策。这是 特定领域语言;我没有看到它在任何地方使用过 其他 比OPA。 这有点新颖。这对一些球队来说可能是一个障碍。
对于这个特定的例子,我决定使用谷歌表格来存储访问规则,原因如下:
- 它是可视化的——很容易看到有什么具体的规则,也很容易演示;
- 更新和维护访问规则很容易。
- 这很容易 保护 “表格”文档上具有用户权限的访问规则。
- 很容易得到谁更改了什么的日志-只需查看工作表上的版本历史记录即可。
所有这些,你都可以通过谷歌表格“免费”获得。
检索和应用规则的C#逻辑也很容易理解。这 所有这些因素的结合意味着使用Sheets和C#可以得到一个解决方案 更广泛地说 可访问的 而不是基于OPA和REGO的组合。
但是,使用OPA的解决方案的架构模型将是 一模一样 正如我所拥有的 带着定制的C#服务和谷歌表格来到这里。
为您自己的目的部署它
要按照说明在您自己的环境中部署它,您需要 以下先决条件:
- Apigee X或混合动力
- 启用了Cloud Run和Cloud Build的Google Cloud项目
- 一个允许您创建和共享电子表格的Google Workspace环境
- .NET 8.0- 如果你想修改源代码并在本地构建。否则,Cloud Build将为您远程构建,您不需要。NET在您的工作站上。
- 各种工具:bash, 卷曲, gcloud命令行界面, 阿皮吉利, jq公司
你可以在 Google Cloud Shell.
应遵循的步骤
这些需要您进行一些定制。这还没有经过充分的测试和审查。
-
修改 env.sh 文件以适应您的环境。然后获取它来设置这些 用于后续命令的变量:
source ./env.sh -
启用所需的服务:
./1-enable-services.sh -
使用gcloud登录以允许脚本创建电子表格:
./2-auth-login.sh -
将“产品”MCP服务器部署到云端运行
3-deploy-products-mcp-to-cloud-run.sh -
创建包含规则+角色的工作表。
./4-create-sheet.sh脚本完成后,为工作表ID定义shell变量。从输出中找到它 “创建工作表”步骤。
export SHEET_ID=VALUE-FROM-PRIOR-STEP -
为访问控制服务创建服务帐户。
./5-create-service-account-for-access-control-service.sh -
手动将之前创建的工作表与SA电子邮件地址共享。
-
部署云运行服务,该服务将读取并应用工作表中的规则。
./6-deploy-access-control-service-to-cloud-run.sh这需要几分钟的时间。它将源代码发送到Cloud Build, 构建服务,然后从映像部署它。
-
创建Apigee目标服务器。
这是指向访问控制服务器的服务器实体。
./7-create-apigee-target-server-for-authz.sh -
安装apigeecli
./8-install-apigeecli.sh -
导入和部署Apigee API代理
有一个用于处理MCP的“众所周知的端点”(basepath`/.knowledge/),另一个用于 以处理其他MCP交易。
./9-import-and-deploy-apigee-proxies.sh -
在聊天机器人或代理中配置MCP服务器 您的选择(Gemini CLI有效),如下所示:
"mcpServers": {
"products": {
"httpUrl": "https://your-apigee-endpoint/mcp-access-control/mcp",
"oauth": {
"enabled": true,
"clientId": "ab4aded9d20f44RHgmrNCq",
"clientSecret": "26a86ab545704312b748e331f854"
}
}
}
您的OIDC服务器需要知道clientId和clientSecret。 或者,如果您的服务器支持动态客户端注册(DCR),则可以省略它们。
- 启动代理;它应该启动OAuth流程,并最终 调用MCP服务器。您可以在Apigee上打开Trace会话以查看交互。
清理
-
删除Apigee资产。
这包括目标服务器和API代理。
./99a-clean-apigee-entities.sh -
删除Cloud Run资源。
这包括服务帐户。
./99b-clean-cloud-run-authorization-service.sh -
手动删除Google工作表。
支持
此标注和示例代理是开源软件,不受支持 阿皮吉。如果您有疑问或需要帮助,可以尝试查询 这 谷歌云社区论坛致力于Apigee 对于发布到该网站的查询的回复,没有服务级别保证。
许可证
这种材料是 版权所有©2025谷歌有限责任公司. 并根据 Apache 2.0许可证这包括Java 代码以及API代理配置。
漏洞
-
部署Cloud Run服务以允许“未经身份验证的访问”。如果你使用 在真实系统中,您需要将Cloud Run服务部署到 允许
run.invoke从您的访问控制服务运行的服务帐户。 -
API代理不对包含的客户端ID执行“VerifyAPIKey” 在访问令牌内。这是一个简单的扩展。它需要同步 Apigee中的应用程序与OIDC服务器中的客户端ID。
-
访问控制服务不检查格式错误的规则。
